#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <set>
#include <memory>

#include <dirent.h>
#include <linux/filter.h>
#include <linux/limits.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/auxv.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>

extern char **environ;

// ---------------- 底层安全通信函数 ----------------
ssize_t read_all(int fd, void* buf, size_t count) {
    char* p = (char*)buf;
    size_t total = 0;
    while (count > 0) {
        ssize_t res = read(fd, p, count);
        if (res < 0 && errno == EINTR) continue;
        if (res <= 0) return total > 0 ? total : res;
        p += res; count -= res; total += res;
    }
    return total;
}

ssize_t write_all(int fd, const void* buf, size_t count) {
    const char* p = (const char*)buf;
    size_t total = 0;
    while (count > 0) {
        ssize_t res = write(fd, p, count);
        if (res < 0 && errno == EINTR) continue;
        if (res <= 0) return total > 0 ? total : res;
        p += res; count -= res; total += res;
    }
    return total;
}

// ---------------- OJ 提供的防 Hack 和沙盒库 (针对严苛沙盒全面加固) ----------------
namespace {
namespace CommunicationLib {

using namespace std::string_literals;

void sanitize_fd() {
    DIR *dir = opendir("/proc/self/fd");
    if (!dir) return;
    int dfd = dirfd(dir);
    dirent *entry;
    std::vector<int> fds_to_close;
    while ((entry = readdir(dir)) != nullptr) {
        if (entry->d_name == "."s || entry->d_name == ".."s) continue;
        int fd = atoi(entry->d_name);
        if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO && fd != dfd) {
            fds_to_close.push_back(fd);
        }
    }
    closedir(dir);
    for (int fd : fds_to_close) close(fd);
}

void setupSeccomp() {
    sock_filter filter[] = {
        BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch)),
        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xc000003eu, 1, 0),
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
        BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x40u, 4, 0),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x1du, 0, 11),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x38u, 1, 0),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x20u, 9, 8),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x3au, 8, 7),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x13fu, 3, 0),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xf0u, 1, 0),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x48u, 5, 4),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0xf6u, 4, 3),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x1b3u, 1, 0),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x140u, 2, 1),
        BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 0x1b4u, 1, 0),
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | 0x1u),
        BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
    };
    sock_fprog prog{sizeof(filter) / sizeof(filter[0]), filter};
    prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
}

struct SubProcess {
    static inline std::set<pid_t> pids;
    pid_t _pid;
    int fd_in;
    int fd_out;

    SubProcess(pid_t __pid, int __fd_in, int __fd_out)
        : _pid(__pid), fd_in(__fd_in), fd_out(__fd_out) { pids.emplace(__pid); }

    ~SubProcess() {
        if (fd_in != -1) close(fd_in);
        if (fd_out != -1) close(fd_out);
    }

    struct _FinalGuard {
        ~_FinalGuard() {
            // 绝不在析构中调用任何形式的 exit() 避免引发 SIGABRT，只做静默回收
            for (pid_t pid : pids) waitpid(pid, nullptr, 0);
        }
    } static inline __finalGuard;

    void guard() {
        if (!pids.count(_pid)) return;
        int _status; waitpid(_pid, &_status, 0);
        pids.erase(_pid);
        if (!WIFEXITED(_status) || WEXITSTATUS(_status) != EXIT_SUCCESS) {
            // 使用内核级 _exit(1) 代替 C++ std::exit，防范由于全局析构带来的 Signal 6 Aborted
            _exit(EXIT_FAILURE);
        }
    }

    static std::unique_ptr<SubProcess> safe_invoke() {
        int i_pipe_fd[2], o_pipe_fd[2];
        if (pipe(i_pipe_fd) == -1) { perror("pipe"); _exit(EXIT_FAILURE); }
        if (pipe(o_pipe_fd) == -1) { perror("pipe"); _exit(EXIT_FAILURE); }

        pid_t pid = fork();
        if (pid == -1) { perror("fork"); _exit(EXIT_FAILURE); }

        if (!pid) {
            int in_fd = o_pipe_fd[0], out_fd = i_pipe_fd[1];
            if (in_fd != 100) { dup2(in_fd, 100); close(in_fd); }
            if (out_fd != 101) { dup2(out_fd, 101); close(out_fd); }
            close(o_pipe_fd[1]); close(i_pipe_fd[0]);

            int null_fd = open("/dev/null", O_RDWR);
            if (null_fd != -1) {
                dup2(null_fd, STDIN_FILENO);
                dup2(null_fd, STDOUT_FILENO);
                if (null_fd > 2) close(null_fd);
            }

            std::vector<char*> newEnv;
            for (int i = 0; environ[i] != NULL; i++) newEnv.push_back(environ[i]);
            static char child_flag[] = "IS_CHILD_PROCESS=1";
            newEnv.push_back(child_flag);
            newEnv.push_back(NULL);

            setupSeccomp();

            const char* exec_path = (const char*)getauxval(AT_EXECFN);
            if (exec_path) {
                const char *newArgv[] = {exec_path, NULL};
                execve(exec_path, (char **)newArgv, newEnv.data());
            }
            const char *newArgv2[] = {"/proc/self/exe", NULL};
            execve("/proc/self/exe", (char **)newArgv2, newEnv.data());
            _exit(EXIT_FAILURE);
        } else {
            close(i_pipe_fd[1]); close(o_pipe_fd[0]);
            return std::make_unique<SubProcess>(pid, i_pipe_fd[0], o_pipe_fd[1]);
        }
    }
};
} // namespace CommunicationLib
} // namespace

void grader_main();

// ---------------- 常量与选手的函数接口 ----------------
extern long long LongestValidParentheses();

const int CMD_SEND = 1;
const int CMD_RECEIVE = 2;
const int CMD_FINISH = 3;

// =========================================================================================
// ==================== 子进程运行的独立环境 (隔离区, API实现) =============================
// =========================================================================================

static int child_N;
static long long child_M;
static int child_id;
static long long child_start;
static std::string child_chunk;

static std::vector<char> child_out_bufs[25];
static std::vector<char> child_in_bufs[25];
static size_t child_in_buf_ptrs[25];

void safe_read(void* buf, size_t count) {
    if (read_all(100, buf, count) != (ssize_t)count) _exit(EXIT_FAILURE);
}
void safe_write(const void* buf, size_t count) {
    if (write_all(101, buf, count) != (ssize_t)count) _exit(EXIT_FAILURE);
}

int GetN() { return child_N; }
int GetMyId() { return child_id; }
long long GetM() { return child_M; }

char GetCharAt(long long i) {
    if (i < child_start || i >= child_start + (long long)child_chunk.size()) _exit(EXIT_FAILURE);
    return child_chunk[i - child_start];
}

void PutInt(int target, int val) {
    if (target < 0 || target >= child_N) _exit(EXIT_FAILURE);
    uint32_t uval = val;
    for(int i = 0; i < 4; ++i) child_out_bufs[target].push_back((uval >> (i * 8)) & 0xFF);
}

void PutLL(int target, long long val) {
    if (target < 0 || target >= child_N) _exit(EXIT_FAILURE);
    uint64_t uval = val;
    for(int i = 0; i < 8; ++i) child_out_bufs[target].push_back((uval >> (i * 8)) & 0xFF);
}

void Send(int target) {
    if (target < 0 || target >= child_N) _exit(EXIT_FAILURE);
    size_t sz = child_out_bufs[target].size();
    if (sz == 0) _exit(EXIT_FAILURE);
    int cmd = CMD_SEND;
    safe_write(&cmd, sizeof(cmd));
    safe_write(&target, sizeof(target));
    safe_write(&sz, sizeof(sz));
    if (sz > 0) safe_write(child_out_bufs[target].data(), sz);
    child_out_bufs[target].clear();
}

void Receive(int source) {
    if (source < 0 || source >= child_N) _exit(EXIT_FAILURE);
    int cmd = CMD_RECEIVE;
    safe_write(&cmd, sizeof(cmd));
    safe_write(&source, sizeof(source));
    size_t sz;
    safe_read(&sz, sizeof(sz));
    child_in_bufs[source].resize(sz);
    if (sz > 0) safe_read(child_in_bufs[source].data(), sz);
    child_in_buf_ptrs[source] = 0;
}

int GetInt(int source) {
    if (source < 0 || source >= child_N) _exit(EXIT_FAILURE);
    uint32_t res = 0;
    auto& buf = child_in_bufs[source];
    auto& ptr = child_in_buf_ptrs[source];
    if (ptr + 4 > buf.size()) _exit(EXIT_FAILURE);
    for(int i = 0; i < 4; ++i) {
        if (ptr < buf.size()) res |= ((uint32_t)(unsigned char)buf[ptr++] << (i * 8));
        else ptr++;
    }
    return (int)res;
}

long long GetLL(int source) {
    if (source < 0 || source >= child_N) _exit(EXIT_FAILURE);
    uint64_t res = 0;
    auto& buf = child_in_bufs[source];
    auto& ptr = child_in_buf_ptrs[source];
    if (ptr + 8 > buf.size()) _exit(EXIT_FAILURE);
    for(int i = 0; i < 8; ++i) {
        if (ptr < buf.size()) res |= ((uint64_t)(unsigned char)buf[ptr++] << (i * 8));
        else ptr++;
    }
    return (long long)res;
}

int main() {
    safe_read(&child_N, sizeof(child_N));
    safe_read(&child_M, sizeof(child_M));
    safe_read(&child_id, sizeof(child_id));
    size_t chunk_len;
    safe_read(&chunk_len, sizeof(chunk_len));
    child_chunk.resize(chunk_len);
    if (chunk_len > 0) safe_read(&child_chunk[0], chunk_len);

    child_start = (long long)child_id * (child_M / child_N);

    long long ans = LongestValidParentheses();

    int cmd = CMD_FINISH;
    safe_write(&cmd, sizeof(cmd));
    safe_write(&ans, sizeof(ans));

    return 0;
}


// =========================================================================================
// =================主进程运行的 Grader 逻辑 (无锁的高级 Poll 事件单线程分发器)===============
// =========================================================================================

using namespace std;

void grader_main() {
    int N;
    long long M;
    string S;
    if (!(cin >> N >> M >> S)) return;

    vector<unique_ptr<CommunicationLib::SubProcess>> procs;
    for (int i = 0; i < N; ++i) {
        procs.push_back(CommunicationLib::SubProcess::safe_invoke());
    }

    size_t L = M / N;
    for (int i = 0; i < N; ++i) {
        size_t chunk_len = L;
        write_all(procs[i]->fd_out, &N, sizeof(N));
        write_all(procs[i]->fd_out, &M, sizeof(M));
        write_all(procs[i]->fd_out, &i, sizeof(i));
        write_all(procs[i]->fd_out, &chunk_len, sizeof(chunk_len));
        if (chunk_len > 0) write_all(procs[i]->fd_out, &S[i * L], chunk_len);
    }

    queue<vector<char>> mailboxes[25][25];
    bool is_blocked[25] = {false};
    int waiting_for[25] = {0};
    long long comm_count[25] = {0};
    long long final_ans = 0;

    int active_children = N;
    vector<pollfd> pfds(N);
    for(int i = 0; i < N; ++i) {
        pfds[i].fd = procs[i]->fd_in;
        pfds[i].events = POLLIN;
    }

    while (active_children > 0) {
        int ret = poll(pfds.data(), N, -1);
        if (ret < 0) {
            if (errno == EINTR) continue;
            break;
        }

        for (int i = 0; i < N; ++i) {
            if (pfds[i].fd == -1) continue;
            if (pfds[i].revents & (POLLIN | POLLERR | POLLHUP)) {
                int cmd;
                if (read_all(pfds[i].fd, &cmd, sizeof(cmd)) <= 0) {
                    pfds[i].fd = -1; active_children--; continue;
                }

                if (cmd == CMD_SEND) {
                    int target; size_t sz;
                    read_all(pfds[i].fd, &target, sizeof(target));
                    read_all(pfds[i].fd, &sz, sizeof(sz));
                    if (target < 0 || target >= N) _exit(EXIT_FAILURE);

                    vector<char> data(sz);
                    if (sz > 0) read_all(pfds[i].fd, data.data(), sz);
                    comm_count[i] += sz;

                    if (is_blocked[target] && waiting_for[target] == i) {
                        write_all(procs[target]->fd_out, &sz, sizeof(sz));
                        if (sz > 0) write_all(procs[target]->fd_out, data.data(), sz);
                        is_blocked[target] = false;
                        comm_count[target] += sz;
                    } else {
                        mailboxes[target][i].push(move(data));
                    }
                }
                else if (cmd == CMD_RECEIVE) {
                    int source;
                    read_all(pfds[i].fd, &source, sizeof(source));
                    if (source < 0 || source >= N) _exit(EXIT_FAILURE);

                    if (!mailboxes[i][source].empty()) {
                        auto& msg = mailboxes[i][source].front();
                        size_t msz = msg.size();
                        write_all(procs[i]->fd_out, &msz, sizeof(msz));
                        if (msz > 0) write_all(procs[i]->fd_out, msg.data(), msz);
                        comm_count[i] += msz;
                        mailboxes[i][source].pop();
                    } else {
                        is_blocked[i] = true;
                        waiting_for[i] = source;
                    }
                }
                else if (cmd == CMD_FINISH) {
                    long long ans;
                    read_all(pfds[i].fd, &ans, sizeof(ans));
                    if (i == 0) final_ans = ans;
                    pfds[i].fd = -1; active_children--;
                }
            }
        }
    }

    for (int i = 0; i < N; ++i) procs[i]->guard();

    long long total_c = 0;
    for (int i = 0; i < N; ++i) total_c += comm_count[i];

    double score = 0;
    if (total_c <= 424) {
        score = 100.0;
    } else if (total_c <= 2048) {
        const double K = 25.0;

        double t = (log10((double)total_c) - log10(424.0))
                 / (log10(2048.0) - log10(424.0));

        double val = 1.0 + 99.0 *
            ((1.0 / (1.0 + K * t) - 1.0 / (1.0 + K))
            / (1.0 - 1.0 / (1.0 + K)));

        score = max(1.0, floor(val));
    } else if (total_c <= 37500000) {
        score = 1.0;
    }

    cout << "secret_token_1145141919810ca942c86-e693-4b21-86e1-85f0c405ed40\n";
    cout << fixed << setprecision(2) << score << "\n";
    cout << total_c << "\n" << final_ans << "\n";
    fflush(stdout);
}

// =========================================================================================
// 此宏必须位于代码最底部以确保其调用的所有全局容器 (如 std::string) 能够被系统正常初始化
// =========================================================================================
#define COMMUNICATION_LIB_REGISTER_GRADER(grader)                              \
  namespace {                                                                  \
  struct _Manager {                                                            \
    _Manager() {                                                               \
      using namespace std::string_literals;                                    \
      bool flg = 0;                                                            \
      for (auto i = 0; environ[i] != NULL; i++)                                \
        flg |= environ[i] == "IS_CHILD_PROCESS=1"s;                            \
      if (!flg) {                                                              \
        CommunicationLib::sanitize_fd();                                       \
        grader();                                                              \
        exit(0);                                                               \
      }                                                                        \
    }                                                                          \
  } __manager;                                                                 \
  }

COMMUNICATION_LIB_REGISTER_GRADER(grader_main)
