{"model_name":"kimi-k2.5","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int l, r, b, t;\n    long long area() const { return 1LL * (r - l) * (t - b); }\n};\n\nint n;\nvector<int> X, Y, R;\nvector<Rect> rects;\n\n// satisfaction of a single company given current area\ndouble score_one(int i) {\n    long long s = rects[i].area();\n    long long r = R[i];\n    if (s == 0) return 0.0;               // should never happen\n    double ratio = (s <= r) ? (double)s / r : (double)r / s;\n    double d = 1.0 - ratio;\n    return 1.0 - d * d;\n}\n\n// check whether rectangle nr for company i is valid\nbool valid(int i, const Rect& nr) {\n    // must contain the point (x_i+0.5, y_i+0.5)\n    if (!(nr.l <= X[i] && X[i] < nr.r && nr.b <= Y[i] && Y[i] < nr.t)) return false;\n    // board limits\n    if (nr.l < 0 || nr.r > 10000 || nr.b < 0 || nr.t > 10000) return false;\n    if (nr.l >= nr.r || nr.b >= nr.t) return false;\n    // no overlap with others\n    for (int j = 0; j < n; ++j) if (j != i) {\n        const Rect& o = rects[j];\n        if (max(nr.l, o.l) < min(nr.r, o.r) &&\n            max(nr.b, o.b) < min(nr.t, o.t))\n            return false;\n    }\n    return true;\n}\n\n// maximum expansion distances for each direction\nstruct ExpandLimit {\n    int left, right, down, up;\n};\n\nExpandLimit compute_limits(int i) {\n    const Rect& rc = rects[i];\n    ExpandLimit lim;\n    lim.left  = rc.l;          // can move to 0, so max move is rc.l\n    lim.right = 10000 - rc.r;  // can move to 10000\n    lim.down  = rc.b;\n    lim.up    = 10000 - rc.t;\n\n    for (int j = 0; j < n; ++j) if (j != i) {\n        const Rect& o = rects[j];\n        // horizontal overlap?\n        bool y_overlap = max(rc.b, o.b) < min(rc.t, o.t);\n        if (y_overlap) {\n            if (o.r <= rc.l) {\n                lim.left = min(lim.left, rc.l - o.r);\n            }\n            if (o.l >= rc.r) {\n                lim.right = min(lim.right, o.l - rc.r);\n            }\n        }\n        // vertical overlap?\n        bool x_overlap = max(rc.l, o.l) < min(rc.r, o.r);\n        if (x_overlap) {\n            if (o.t <= rc.b) {\n                lim.down = min(lim.down, rc.b - o.t);\n            }\n            if (o.b >= rc.t) {\n                lim.up = min(lim.up, o.b - rc.t);\n            }\n        }\n    }\n    return lim;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---------- input ----------\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    // ---------- initial minimal rectangles ----------\n    rects.resize(n);\n    for (int i = 0; i < n; ++i) {\n        rects[i] = {X[i], X[i] + 1, Y[i], Y[i] + 1};\n    }\n    \n    // ---------- greedy expansion ----------\n    vector<int> ord(n);\n    iota(ord.begin(), ord.end(), 0);\n    mt19937 rng(12345);\n    \n    for (int it = 0; it < 300; ++it) {\n        sort(ord.begin(), ord.end(),\n             [&](int a, int b) {\n                 double ra = (double)rects[a].area() / R[a];\n                 double rb = (double)rects[b].area() / R[b];\n                 return ra < rb; // larger deficit first\n             });\n        \n        for (int idx : ord) {\n            long long cur = rects[idx].area();\n            if (cur >= R[idx]) continue;\n            \n            // try to expand as much as possible in one go\n            for (int step = 0; step < 50; ++step) {\n                ExpandLimit lim = compute_limits(idx);\n                Rect &rc = rects[idx];\n                long long need = R[idx] - cur;\n                if (need <= 0) break;\n                \n                // choose best direction (largest free space)\n                int best_dir = -1;\n                long long best_gain = 0;\n                \n                // left\n                if (lim.left > 0) {\n                    long long gain = 1LL * lim.left * (rc.t - rc.b);\n                    if (gain > best_gain) { best_gain = gain; best_dir = 0; }\n                }\n                // right\n                if (lim.right > 0) {\n                    long long gain = 1LL * lim.right * (rc.t - rc.b);\n                    if (gain > best_gain) { best_gain = gain; best_dir = 1; }\n                }\n                // down\n                if (lim.down > 0) {\n                    long long gain = 1LL * lim.down * (rc.r - rc.l);\n                    if (gain > best_gain) { best_gain = gain; best_dir = 2; }\n                }\n                // up\n                if (lim.up > 0) {\n                    long long gain = 1LL * lim.up * (rc.r - rc.l);\n                    if (gain > best_gain) { best_gain = gain; best_dir = 3; }\n                }\n                if (best_dir == -1) break; // stuck\n                \n                // decide amount: we want to get closer to target, but not overshoot too much\n                long long h = rc.t - rc.b;\n                long long w = rc.r - rc.l;\n                int add = 0;\n                Rect nr = rc;\n                if (best_dir == 0) { // left\n                    long long can = min<long long>(lim.left, (need + h - 1) / h);\n                    if (can == 0) can = 1;\n                    add = (int)can;\n                    nr.l -= add;\n                } else if (best_dir == 1) { // right\n                    long long can = min<long long>(lim.right, (need + h - 1) / h);\n                    if (can == 0) can = 1;\n                    add = (int)can;\n                    nr.r += add;\n                } else if (best_dir == 2) { // down\n                    long long can = min<long long>(lim.down, (need + w - 1) / w);\n                    if (can == 0) can = 1;\n                    add = (int)can;\n                    nr.b -= add;\n                } else { // up\n                    long long can = min<long long>(lim.up, (need + w - 1) / w);\n                    if (can == 0) can = 1;\n                    add = (int)can;\n                    nr.t += add;\n                }\n                \n                if (valid(idx, nr)) {\n                    rc = nr;\n                    cur = rc.area();\n                } else {\n                    // if big jump fails, try single step (safety)\n                    add = 1;\n                    nr = rc;\n                    if (best_dir == 0) nr.l -= add;\n                    else if (best_dir == 1) nr.r += add;\n                    else if (best_dir == 2) nr.b -= add;\n                    else nr.t += add;\n                    if (valid(idx, nr)) {\n                        rc = nr;\n                        cur = rc.area();\n                    } else {\n                        break; // cannot expand this direction anymore\n                    }\n                }\n            }\n        }\n    }\n    \n    // ---------- Simulated Annealing ----------\n    uniform_int_distribution<int> dist_n(0, n - 1);\n    uniform_int_distribution<int> dist_side(0, 3); // 0:L,1:R,2:B,3:T\n    uniform_int_distribution<int> dist_dir(0, 1);  // 0:decrease, 1:increase\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    \n    double T = 1.0;          // initial temperature\n    const double T_min = 1e-5;\n    const double alpha = 0.99997;\n    \n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    \n    long long iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        ++iter;\n        if ((iter & 1023) == 0) {\n            T *= alpha; // cool down periodically\n            if (T < T_min) T = T_min;\n        }\n        \n        int i = dist_n(rng);\n        int side = dist_side(rng);\n        int delta = dist_dir(rng) * 2 - 1; // -1 or +1\n        \n        Rect &rc = rects[i];\n        Rect nr = rc;\n        if (side == 0) nr.l += delta;\n        else if (side == 1) nr.r += delta;\n        else if (side == 2) nr.b += delta;\n        else nr.t += delta;\n        \n        if (!valid(i, nr)) continue;\n        \n        double old_sc = score_one(i);\n        Rect save = rc;\n        rc = nr;\n        double new_sc = score_one(i);\n        double delta_sc = new_sc - old_sc;\n        \n        if (delta_sc >= 0 || exp(delta_sc / T) > dist_real(rng)) {\n            // keep change\n        } else {\n            rc = save; // revert\n        }\n    }\n    \n    // ---------- output ----------\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].l << ' ' << rects[i].b << ' '\n             << rects[i].r << ' ' << rects[i].t << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int H = 50, W = 50;\n    int si, sj;\n    vector<vector<int>> tile;\n    vector<vector<int>> val;\n    int M; // number of tiles\n    \n    const vector<int> di = {-1, 1, 0, 0};\n    const vector<int> dj = {0, 0, -1, 1};\n    const vector<char> dc = {'U', 'D', 'L', 'R'};\n    \n    // Calculate score of a path for validation/comparison\n    long long calc_score(const string& path) {\n        vector<bool> vis(M, false);\n        int i = si, j = sj;\n        vis[tile[i][j]] = true;\n        long long score = val[i][j];\n        \n        for (char c : path) {\n            int d = 0;\n            if (c == 'U') d = 0;\n            else if (c == 'D') d = 1;\n            else if (c == 'L') d = 2;\n            else if (c == 'R') d = 3;\n            else return -1;\n            \n            int ni = i + di[d];\n            int nj = j + dj[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) return -1;\n            int nt = tile[ni][nj];\n            if (vis[nt]) return -1; // visited same tile\n            \n            i = ni; j = nj;\n            vis[nt] = true;\n            score += val[i][j];\n        }\n        return score;\n    }\n    \n    // Greedy walk with specified heuristic type\n    string greedy_walk(int heuristic_type) {\n        vector<bool> visited(M, false);\n        int i = si, j = sj;\n        visited[tile[i][j]] = true;\n        string path;\n        \n        while (true) {\n            struct Candidate {\n                double score;\n                int dir;\n                int ni, nj;\n                bool operator<(const Candidate& other) const {\n                    return score < other.score; // for max-heap\n                }\n            };\n            vector<Candidate> cand;\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n                int nt = tile[ni][nj];\n                if (visited[nt]) continue;\n                \n                // Calculate degree (number of unvisited adjacent tiles)\n                int degree = 0;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int ni2 = ni + di[d2];\n                    int nj2 = nj + dj[d2];\n                    if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                    if (!visited[tile[ni2][nj2]]) degree++;\n                }\n                \n                double h = 0;\n                if (heuristic_type == 0) {\n                    // Pure value\n                    h = val[ni][nj];\n                } else if (heuristic_type == 1) {\n                    // Value + small degree bonus\n                    h = val[ni][nj] + degree * 10.0;\n                } else if (heuristic_type == 2) {\n                    // Value + large degree bonus\n                    h = val[ni][nj] + degree * 50.0;\n                } else if (heuristic_type == 3) {\n                    // Avoid dead ends strongly\n                    if (degree == 0) h = val[ni][nj] - 1000000.0;\n                    else h = val[ni][nj];\n                } else if (heuristic_type == 4) {\n                    // Lookahead: value + 0.5 * best next value\n                    double best_next = 0;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int ni2 = ni + di[d2];\n                        int nj2 = nj + dj[d2];\n                        if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                        int nt2 = tile[ni2][nj2];\n                        if (nt2 == nt) continue; // same tile, will be visited\n                        if (!visited[nt2]) {\n                            best_next = max(best_next, (double)val[ni2][nj2]);\n                        }\n                    }\n                    h = val[ni][nj] + best_next * 0.5;\n                }\n                cand.push_back({h, d, ni, nj});\n            }\n            \n            if (cand.empty()) break;\n            // Select max\n            auto best = *max_element(cand.begin(), cand.end());\n            \n            // Move\n            i = best.ni;\n            j = best.nj;\n            visited[tile[i][j]] = true;\n            path.push_back(dc[best.dir]);\n        }\n        return path;\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Try different heuristics\n        for (int h = 0; h < 5; ++h) {\n            string path = greedy_walk(h);\n            long long sc = calc_score(path);\n            if (sc > best_score) {\n                best_score = sc;\n                best_path = path;\n            }\n        }\n        return best_path;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Process all test cases until EOF\n    // (Each test case: si sj, then 50x50 tile grid, then 50x50 value grid)\n    while (true) {\n        int si, sj;\n        if (!(cin >> si >> sj)) break;\n        \n        vector<vector<int>> t(50, vector<int>(50));\n        vector<vector<int>> p(50, vector<int>(50));\n        \n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                cin >> p[i][j];\n        \n        Solver solver;\n        solver.si = si;\n        solver.sj = sj;\n        solver.tile = t;\n        solver.val = p;\n        \n        // Determine number of tiles M\n        int max_id = 0;\n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                max_id = max(max_id, t[i][j]);\n        solver.M = max_id + 1;\n        \n        string ans = solver.solve();\n        cout << ans << \"\\n\";\n    }\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    constexpr int N = 30;\n    constexpr int Q = 1000;\n    \n    // Estimated edge weights\n    double h[N][N-1];\n    double v[N-1][N];\n    // Visit counts\n    int hcnt[N][N-1] = {};\n    int vcnt[N-1][N] = {};\n    \n    // Initialize to midpoint of possible range [1000,9000]\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N-1; ++j)\n            h[i][j] = 5000.0;\n    for (int i = 0; i < N-1; ++i)\n        for (int j = 0; j < N; ++j)\n            v[i][j] = 5000.0;\n    \n    // Directions: U,D,L,R\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    for (int q = 0; q < Q; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n        \n        // Exploration bonus decays linearly, zero after query 500\n        double explore = 0.0;\n        if (q < 500) {\n            explore = 2000.0 * (1.0 - static_cast<double>(q) / 500.0);\n        }\n        \n        // Dijkstra\n        double dist[N][N];\n        int par_i[N][N];\n        int par_j[N][N];\n        char par_dir[N][N];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = 1e100;\n        \n        using State = tuple<double, int, int>;\n        priority_queue<State, vector<State>, greater<State>> pq;\n        \n        dist[si][sj] = 0.0;\n        pq.emplace(0.0, si, sj);\n        \n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (d > dist[i][j] + 1e-9) continue;\n            if (i == ti && j == tj) break;\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                double w;\n                int cnt;\n                if (dir == 0) { // U: uses v[i-1][j]\n                    w = v[i-1][j];\n                    cnt = vcnt[i-1][j];\n                } else if (dir == 1) { // D: uses v[i][j]\n                    w = v[i][j];\n                    cnt = vcnt[i][j];\n                } else if (dir == 2) { // L: uses h[i][j-1]\n                    w = h[i][j-1];\n                    cnt = hcnt[i][j-1];\n                } else { // R: uses h[i][j]\n                    w = h[i][j];\n                    cnt = hcnt[i][j];\n                }\n                \n                // Effective weight: encourage exploring rarely visited edges\n                double weff = w - explore / sqrt(static_cast<double>(cnt) + 1.0);\n                \n                if (dist[ni][nj] > dist[i][j] + weff) {\n                    dist[ni][nj] = dist[i][j] + weff;\n                    par_i[ni][nj] = i;\n                    par_j[ni][nj] = j;\n                    par_dir[ni][nj] = dc[dir];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n        \n        // Reconstruct path\n        string path;\n        int ci = ti, cj = tj;\n        while (ci != si || cj != sj) {\n            path.push_back(par_dir[ci][cj]);\n            int pi = par_i[ci][cj];\n            int pj = par_j[ci][cj];\n            ci = pi;\n            cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        \n        cout << path << '\\n';\n        cout.flush();\n        \n        // Read noisy length\n        long long r_obs;\n        cin >> r_obs;\n        double r = static_cast<double>(r_obs);\n        \n        // Walk the path again to collect edges and compute estimated length\n        double len_est = 0.0;\n        vector<tuple<char,int,int>> edges; // type, i, j  type: 'h' or 'v'\n        ci = si; cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                len_est += v[ci-1][cj];\n                edges.emplace_back('v', ci-1, cj);\n                ci--;\n            } else if (c == 'D') {\n                len_est += v[ci][cj];\n                edges.emplace_back('v', ci, cj);\n                ci++;\n            } else if (c == 'L') {\n                len_est += h[ci][cj-1];\n                edges.emplace_back('h', ci, cj-1);\n                cj--;\n            } else { // 'R'\n                len_est += h[ci][cj];\n                edges.emplace_back('h', ci, cj);\n                cj++;\n            }\n        }\n        \n        // SGD update\n        double error = r - len_est;\n        int m = static_cast<int>(edges.size());\n        // Learning rate: start larger, decay slowly\n        double lr = 0.05 * pow(0.998, q);\n        if (m == 0) continue; // should not happen\n        \n        double delta = lr * error / m;\n        \n        for (auto& [type, i, j] : edges) {\n            if (type == 'h') {\n                h[i][j] += delta;\n                if (h[i][j] < 100.0) h[i][j] = 100.0;\n                if (h[i][j] > 10000.0) h[i][j] = 10000.0;\n                hcnt[i][j]++;\n            } else {\n                v[i][j] += delta;\n                if (v[i][j] < 100.0) v[i][j] = 100.0;\n                if (v[i][j] > 10000.0) v[i][j] = 10000.0;\n                vcnt[i][j]++;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int str_id;\n    uint8_t len;\n};\n\nstruct Ref {\n    int pid;\n    uint8_t req;          // 0 \u2026 7  (A \u2026 H)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) cin >> strs[i];\n\n    auto ch2i = [](char c)->int{ return c - 'A'; };   // 'A'..'H' -> 0..7\n\n    const int C = N * N;                 // number of cells\n    vector<vector<Ref>> cell_refs(C);    // reverse index\n    vector<Placement> plc;               // all placements\n    plc.reserve(M * 2 * N * N);\n\n    /* -----------------------------------------------------------\n       generate all placements\n       ----------------------------------------------------------- */\n    for (int s = 0; s < M; ++s) {\n        const string &st = strs[s];\n        int L = (int)st.size();\n        // horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    int cid = r * N + cc;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n        // vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int rr = (r + p) % N;\n                    int cid = rr * N + c;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n    }\n\n    const int P = (int)plc.size();\n    vector<uint8_t> counter(P, 0);\n    vector<int> sat_cnt(M, 0);\n    int total_sat = 0;\n\n    /* -----------------------------------------------------------\n       random initial grid (only letters, 0..7)\n       ----------------------------------------------------------- */\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    vector<uint8_t> grid(C);\n    for (int i = 0; i < C; ++i) grid[i] = (uint8_t)(rng() & 7);\n\n    /* initial counting */\n    for (int cid = 0; cid < C; ++cid) {\n        uint8_t v = grid[cid];\n        for (const auto &rf : cell_refs[cid]) {\n            if (rf.req == v) ++counter[rf.pid];\n        }\n    }\n    for (int pid = 0; pid < P; ++pid) {\n        if (counter[pid] == plc[pid].len) {\n            ++sat_cnt[plc[pid].str_id];\n        }\n    }\n    for (int s = 0; s < M; ++s) if (sat_cnt[s] > 0) ++total_sat;\n\n    /* -----------------------------------------------------------\n       helper: apply change of one cell (old_val -> new_val)\n       updates counter[], sat_cnt[] and total_sat\n       ----------------------------------------------------------- */\n    auto apply_change = [&](int cid, uint8_t old_val, uint8_t new_val) {\n        if (old_val == new_val) return;\n        for (const auto &rf : cell_refs[cid]) {\n            bool old_match = (old_val == rf.req);\n            bool new_match = (new_val == rf.req);\n            if (old_match == new_match) continue;   // nothing changes\n\n            uint8_t &cnt = counter[rf.pid];\n            uint8_t len  = plc[rf.pid].len;\n            if (old_match) {                 // we lose one matching cell\n                --cnt;\n                if (cnt == len - 1) {        // was satisfied, now not\n                    int sid = plc[rf.pid].str_id;\n                    if (--sat_cnt[sid] == 0) --total_sat;\n                }\n            } else {                         // we gain one matching cell\n                ++cnt;\n                if (cnt == len) {            // becomes satisfied\n                    int sid = plc[rf.pid].str_id;\n                    if (sat_cnt[sid]++ == 0) ++total_sat;\n                }\n            }\n        }\n    };\n\n    /* -----------------------------------------------------------\n       Simulated Annealing\n       ----------------------------------------------------------- */\n    const double TIME_LIMIT = 2.5;            // seconds\n    auto start = chrono::steady_clock::now();\n    double temp = 0.8;                        // initial temperature\n    int iter = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        ++iter;\n        if ((iter & 127) == 0) temp *= 0.999; // slow cooling\n\n        int cid = (int)(rng() % C);\n        uint8_t oldv = grid[cid];\n        uint8_t newv = (uint8_t)(rng() & 7);\n        if (oldv == newv) continue;\n\n        int before = total_sat;\n        apply_change(cid, oldv, newv);\n        int after = total_sat;\n        int delta = after - before;\n\n        if (delta < 0) {\n            double accept_prob = exp(delta / temp);\n            if (uniform_real_distribution<double>(0.0, 1.0)(rng) > accept_prob) {\n                // reject: revert\n                apply_change(cid, newv, oldv);\n                // grid[cid] stays oldv\n                continue;\n            }\n        }\n        grid[cid] = newv;   // accept\n    }\n\n    /* -----------------------------------------------------------\n       Phase 2: try to turn cells into '.' (value 8) without breaking\n       ----------------------------------------------------------- */\n    if (total_sat == M) {\n        vector<int> order(C);\n        iota(order.begin(), order.end(), 0);\n        for (int rep = 0; rep < 3; ++rep) {\n            shuffle(order.begin(), order.end(), rng);\n            for (int cid : order) {\n                if (grid[cid] == 8) continue;          // already dot\n                uint8_t oldv = grid[cid];\n                apply_change(cid, oldv, 8);\n                if (total_sat == M) {\n                    grid[cid] = 8;                      // keep dot\n                } else {\n                    apply_change(cid, 8, oldv);         // revert\n                }\n            }\n        }\n    }\n\n    /* -----------------------------------------------------------\n       Output\n       ----------------------------------------------------------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        line.reserve(N);\n        for (int c = 0; c < N; ++c) {\n            int v = grid[r * N + c];\n            if (v == 8) line.push_back('.');\n            else        line.push_back(char('A' + v));\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastBitset {\n    static const int MAXR = 5000;\n    static const int WORDS = (MAXR + 63) / 64;\n    uint64_t w[WORDS];\n    FastBitset() { memset(w, 0, sizeof(w)); }\n    void set(int i) { w[i>>6] |= 1ULL << (i&63); }\n    bool test(int i) const { return (w[i>>6] >> (i&63)) & 1ULL; }\n    void clear() { memset(w, 0, sizeof(w)); }\n    int count() const {\n        int s = 0;\n        for (int i = 0; i < WORDS; i++) s += __builtin_popcountll(w[i]);\n        return s;\n    }\n    FastBitset operator&(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] & o.w[i];\n        return r;\n    }\n    FastBitset operator|(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] | o.w[i];\n        return r;\n    }\n    FastBitset operator~() const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = ~w[i];\n        return r;\n    }\n    FastBitset& operator&=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] &= o.w[i];\n        return *this;\n    }\n    FastBitset& operator|=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] |= o.w[i];\n        return *this;\n    }\n    bool any() const {\n        for (int i = 0; i < WORDS; i++) if (w[i]) return true;\n        return false;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = cells.size();\n                cells.emplace_back(i, j);\n            }\n        }\n    }\n    int R = cells.size();\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    // Horizontal and vertical segment IDs and coverage bitsets\n    vector<vector<int>> h_id(N, vector<int>(N, -1));\n    vector<vector<int>> v_id(N, vector<int>(N, -1));\n    vector<FastBitset> h_cover, v_cover;\n    \n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != '#') {\n                int l = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int r = j - 1;\n                FastBitset bs;\n                int sid = h_cover.size();\n                for (int k = l; k <= r; k++) {\n                    h_id[i][k] = sid;\n                    bs.set(id[i][k]);\n                }\n                h_cover.push_back(bs);\n            } else {\n                j++;\n            }\n        }\n    }\n    \n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != '#') {\n                int t = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int b = i - 1;\n                FastBitset bs;\n                int sid = v_cover.size();\n                for (int k = t; k <= b; k++) {\n                    v_id[k][j] = sid;\n                    bs.set(id[k][j]);\n                }\n                v_cover.push_back(bs);\n            } else {\n                i++;\n            }\n        }\n    }\n    \n    // Coverage for each cell\n    vector<FastBitset> cell_cover(R);\n    for (int idx = 0; idx < R; idx++) {\n        auto [i, j] = cells[idx];\n        cell_cover[idx] = h_cover[h_id[i][j]] | v_cover[v_id[i][j]];\n    }\n    \n    int start_idx = id[si][sj];\n    \n    // Greedy set cover\n    FastBitset uncovered;\n    for (int i = 0; i < R; i++) uncovered.set(i);\n    uncovered &= ~cell_cover[start_idx]; // start position is already visible\n    \n    vector<int> selected;\n    \n    // Pre-calculate which cells have any coverage of remaining uncovered cells\n    while (uncovered.any()) {\n        int best = -1;\n        int best_cnt = -1;\n        \n        // Find cell with maximum coverage of uncovered\n        for (int c = 0; c < R; c++) {\n            // Quick check: any overlap?\n            bool has_overlap = false;\n            for (int w = 0; w < FastBitset::WORDS; w++) {\n                if (cell_cover[c].w[w] & uncovered.w[w]) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            if (!has_overlap) continue;\n            \n            FastBitset inter = cell_cover[c] & uncovered;\n            int cnt = inter.count();\n            if (cnt > best_cnt) {\n                best_cnt = cnt;\n                best = c;\n            }\n        }\n        \n        if (best == -1) break; // Should not happen if roads are connected properly\n        selected.push_back(best);\n        uncovered &= ~cell_cover[best];\n    }\n    \n    // Build point list for TSP: start + selected\n    vector<int> points;\n    points.reserve(selected.size() + 1);\n    points.push_back(start_idx);\n    for (int idx : selected) points.push_back(idx);\n    int K = points.size();\n    \n    // Map from cell id to point index (0..K-1) or -1\n    vector<int> node_to_point(R, -1);\n    for (int i = 0; i < K; i++) node_to_point[points[i]] = i;\n    \n    const int INF = 1e9;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // Distance matrix between points\n    vector<vector<int>> dmat(K, vector<int>(K, INF));\n    \n    // Dijkstra from each point, stopping when all other points are settled\n    for (int pi = 0; pi < K; pi++) {\n        int src = points[pi];\n        vector<int> dist(R, INF);\n        dist[src] = 0;\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.emplace(0, src);\n        int settled = 0;\n        \n        while (!pq.empty() && settled < K) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (node_to_point[u] != -1) {\n                settled++;\n            }\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        for (int pj = 0; pj < K; pj++) {\n            dmat[pi][pj] = dist[points[pj]];\n        }\n    }\n    \n    // TSP: Nearest neighbor initialization\n    vector<int> tour;\n    tour.reserve(K);\n    vector<bool> used(K, false);\n    tour.push_back(0);\n    used[0] = true;\n    int cur = 0;\n    for (int iter = 1; iter < K; iter++) {\n        int nxt = -1;\n        int best_d = INF;\n        for (int i = 0; i < K; i++) if (!used[i]) {\n            if (dmat[cur][i] < best_d) {\n                best_d = dmat[cur][i];\n                nxt = i;\n            }\n        }\n        if (nxt == -1) break;\n        tour.push_back(nxt);\n        used[nxt] = true;\n        cur = nxt;\n    }\n    \n    // 2-opt improvement\n    bool improved = true;\n    int max_iter = 1000;\n    int iter_cnt = 0;\n    while (improved && iter_cnt < max_iter) {\n        improved = false;\n        iter_cnt++;\n        for (int i = 0; i < K; i++) {\n            for (int j = i + 2; j < K; j++) {\n                int a = tour[i];\n                int b = tour[(i+1)%K];\n                int c = tour[j];\n                int d = tour[(j+1)%K];\n                \n                int cur_len = dmat[a][b] + dmat[c][d];\n                int new_len = dmat[a][c] + dmat[b][d];\n                \n                if (new_len < cur_len) {\n                    // Reverse segment [i+1, j]\n                    int l = i + 1, r = j;\n                    while (l < r) {\n                        swap(tour[l], tour[r]);\n                        l++; r--;\n                    }\n                    improved = true;\n                }\n            }\n        }\n    }\n    \n    // Build route string\n    string route;\n    route.reserve(N * N * 4); // rough estimate\n    \n    for (int ii = 0; ii < K; ii++) {\n        int from_idx = points[tour[ii]];\n        int to_idx = points[tour[(ii+1)%K]];\n        if (from_idx == to_idx) continue;\n        \n        // Dijkstra to get path\n        vector<int> dist(R, INF);\n        vector<int> prev(R, -1);\n        vector<int> prev_dir(R, -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[from_idx] = 0;\n        pq.emplace(0, from_idx);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == to_idx) break;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_dir[v] = dir;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        // Reconstruct path\n        vector<int> dirs;\n        int cur_node = to_idx;\n        while (cur_node != from_idx) {\n            dirs.push_back(prev_dir[cur_node]);\n            cur_node = prev[cur_node];\n        }\n        reverse(dirs.begin(), dirs.end());\n        for (int d : dirs) {\n            if (d == 0) route += 'U';\n            else if (d == 1) route += 'D';\n            else if (d == 2) route += 'L';\n            else route += 'R';\n        }\n    }\n    \n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if(!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<K; j++) cin >> d[i][j];\n    }\n    \n    vector<vector<int>> adj(N);      // u -> v (u must be done before v)\n    vector<vector<int>> radj(N);     // reverse graph\n    vector<int> indeg(N, 0);\n    for(int i=0; i<R; i++) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n        indeg[v]++;\n    }\n    \n    // Precompute sum of d for each task for skill update\n    vector<int> sum_d(N, 0);\n    for(int i=0; i<N; i++) {\n        sum_d[i] = accumulate(d[i].begin(), d[i].end(), 0);\n    }\n    \n    // State: estimated skills for each member\n    vector<vector<double>> est_s(M, vector<double>(K, 50.0)); // initialized to 50 (middle of typical range)\n    \n    vector<int> indeg_cur = indeg;\n    vector<int> task_state(N, 0); // 0:not ready, 1:ready(available), 2:running, 3:done\n    vector<int> member_task(M, -1); // -1 if free, else task id\n    vector<int> task_start_day(N, -1);\n    vector<int> task_member(N, -1); // which member is assigned\n    \n    int day = 0;\n    const int MAX_DAY = 2000;\n    \n    while(day < MAX_DAY) {\n        ++day;\n        \n        // Update available tasks (indegree became 0)\n        vector<int> available;\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 0 && indeg_cur[i] == 0) {\n                task_state[i] = 1;\n            }\n            if(task_state[i] == 1) {\n                available.push_back(i);\n            }\n        }\n        \n        // Find free members\n        vector<int> free_members;\n        for(int j=0; j<M; j++) {\n            if(member_task[j] == -1) free_members.push_back(j);\n        }\n        \n        // Compute expected time for each unfinished task (min over members)\n        vector<double> min_est_time(N, 1.0);\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 3) continue; // done\n            double best = 1e18;\n            for(int j=0; j<M; j++) {\n                double w = 0;\n                for(int k=0; k<K; k++) {\n                    if(d[i][k] > est_s[j][k]) w += d[i][k] - est_s[j][k];\n                }\n                double t = (w <= 0) ? 1.0 : max(1.0, w); // expected time ignoring random noise\n                best = min(best, t);\n            }\n            min_est_time[i] = best;\n        }\n        \n        // Compute DP for critical path (longest path to end) using memoization\n        vector<double> dp(N, -1.0);\n        function<double(int)> solve_dp = [&](int u) -> double {\n            if(task_state[u] == 3) return 0.0; // done, no more time needed\n            if(dp[u] >= 0) return dp[u];\n            double max_next = 0.0;\n            for(int v : adj[u]) {\n                if(task_state[v] != 3) {\n                    max_next = max(max_next, solve_dp(v));\n                }\n            }\n            dp[u] = min_est_time[u] + max_next;\n            return dp[u];\n        };\n        \n        for(int i : available) {\n            solve_dp(i);\n        }\n        \n        // Sort available by dp descending (most critical first)\n        sort(available.begin(), available.end(), [&](int a, int b) {\n            double da = (dp[a] < 0) ? 0 : dp[a];\n            double db = (dp[b] < 0) ? 0 : dp[b];\n            return da > db;\n        });\n        \n        // Greedy assignment: urgent task -> best free member\n        vector<pair<int,int>> assignments; // (member, task)\n        vector<bool> used(M, false);\n        \n        for(int task_id : available) {\n            if(assignments.size() >= free_members.size()) break;\n            \n            int best_j = -1;\n            double best_time = 1e18;\n            for(int j : free_members) {\n                if(used[j]) continue;\n                double w = 0;\n                for(int k=0; k<K; k++) {\n                    if(d[task_id][k] > est_s[j][k]) w += d[task_id][k] - est_s[j][k];\n                }\n                double t = (w <= 0) ? 1.0 : max(1.0, w);\n                if(t < best_time) {\n                    best_time = t;\n                    best_j = j;\n                }\n            }\n            if(best_j != -1) {\n                assignments.emplace_back(best_j, task_id);\n                used[best_j] = true;\n            }\n        }\n        \n        // Output\n        cout << assignments.size();\n        for(auto& [j, i] : assignments) {\n            cout << \" \" << j+1 << \" \" << i+1;\n            member_task[j] = i;\n            task_state[i] = 2;\n            task_start_day[i] = day;\n            task_member[i] = j;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion input\n        int n_comp;\n        cin >> n_comp;\n        if(n_comp == -1) break; // all done or day 2000 reached\n        \n        vector<int> completed(n_comp);\n        for(int i=0; i<n_comp; i++) {\n            cin >> completed[i];\n            completed[i]--; // to 0-index\n        }\n        \n        // Process completions and update skills\n        for(int j : completed) {\n            int task_id = member_task[j];\n            if(task_id == -1) continue; // should not happen\n            \n            int duration = day - task_start_day[task_id] + 1; // t_{i,j}\n            double obs_w = max(0, duration - 1); // observed deficiency (ignoring random noise)\n            \n            // Calculate predicted deficiency\n            double pred_w = 0;\n            vector<int> active_dims;\n            for(int k=0; k<K; k++) {\n                if(d[task_id][k] > est_s[j][k]) {\n                    pred_w += d[task_id][k] - est_s[j][k];\n                    active_dims.push_back(k);\n                }\n            }\n            \n            if(obs_w == 0) {\n                // Completed in 1 day: skills are at least d\n                for(int k=0; k<K; k++) {\n                    if(d[task_id][k] > est_s[j][k]) {\n                        est_s[j][k] = d[task_id][k];\n                    }\n                }\n            } else {\n                if(pred_w == 0) {\n                    // We thought they were expert, but they took longer\n                    // Distribute obs_w among dimensions proportional to d[i][k]\n                    double sumd = sum_d[task_id];\n                    if(sumd > 0) {\n                        for(int k=0; k<K; k++) {\n                            double reduce = obs_w * d[task_id][k] / sumd;\n                            est_s[j][k] = max(0.0, est_s[j][k] - reduce);\n                        }\n                    }\n                } else {\n                    // Gradient update\n                    double diff = obs_w - pred_w;\n                    // Learning rate 0.5\n                    double lr = 0.5;\n                    for(int k : active_dims) {\n                        double contrib = d[task_id][k] - est_s[j][k];\n                        double delta = diff * (contrib / pred_w) * lr;\n                        est_s[j][k] += delta;\n                        est_s[j][k] = max(0.0, est_s[j][k]);\n                    }\n                }\n            }\n            \n            // Mark task done and free member\n            task_state[task_id] = 3;\n            member_task[j] = -1;\n            \n            // Update indegrees of successors\n            for(int v : adj[task_id]) {\n                indeg_cur[v]--;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point start;\n    Timer() { start = chrono::steady_clock::now(); }\n    double elapsed() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 1000;\n    const int OFFICE = 0;\n    const int OFFICE_X = 400, OFFICE_Y = 400;\n    \n    vector<int> a(N), b(N), c(N), d(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> a[i] >> b[i] >> c[i] >> d[i];\n    }\n    \n    // Coordinate compression: 0 = office, 1..N = pickup, N+1..2N = delivery\n    vector<int> xs(2 * N + 1), ys(2 * N + 1);\n    xs[OFFICE] = OFFICE_X; ys[OFFICE] = OFFICE_Y;\n    for (int i = 0; i < N; ++i) {\n        xs[1 + i] = a[i];\n        ys[1 + i] = b[i];\n        xs[1 + N + i] = c[i];\n        ys[1 + N + i] = d[i];\n    }\n    \n    // Precompute distance matrix\n    vector<vector<int>> dist_mat(2 * N + 1, vector<int>(2 * N + 1));\n    for (int i = 0; i <= 2 * N; ++i) {\n        for (int j = 0; j <= 2 * N; ++j) {\n            dist_mat[i][j] = abs(xs[i] - xs[j]) + abs(ys[i] - ys[j]);\n        }\n    }\n    \n    // ---------- Greedy Insertion ----------\n    vector<int> route = {OFFICE, OFFICE}; // current sequence of point indices\n    vector<int> selected;\n    selected.reserve(50);\n    vector<bool> used(N, false);\n    \n    for (int iter = 0; iter < 50; ++iter) {\n        int best_o = -1;\n        int best_delta = 1e9;\n        int best_i = -1, best_j = -1;\n        int m = (int)route.size();\n        \n        for (int o = 0; o < N; ++o) if (!used[o]) {\n            int p = 1 + o;          // pickup index\n            int del = 1 + N + o;    // delivery index\n            \n            for (int i = 0; i < m - 1; ++i) {\n                for (int j = i; j < m - 1; ++j) {\n                    int delta;\n                    if (i == j) {\n                        // Pickup then delivery immediately after\n                        delta = -dist_mat[route[i]][route[i+1]]\n                                + dist_mat[route[i]][p]\n                                + dist_mat[p][del]\n                                + dist_mat[del][route[i+1]];\n                    } else {\n                        // Pickup at i, delivery at j (original indices)\n                        delta = -dist_mat[route[i]][route[i+1]]\n                                - dist_mat[route[j]][route[j+1]]\n                                + dist_mat[route[i]][p]\n                                + dist_mat[p][route[i+1]]\n                                + dist_mat[route[j]][del]\n                                + dist_mat[del][route[j+1]];\n                    }\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_o = o;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        // Insert the best order into the route\n        int p = 1 + best_o;\n        int del = 1 + N + best_o;\n        if (best_i == best_j) {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_i + 2, del);\n        } else {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_j + 2, del);\n        }\n        selected.push_back(best_o);\n        used[best_o] = true;\n    }\n    \n    // ---------- Simulated Annealing ----------\n    // route has size 102: indices 0 and 101 are office (fixed)\n    vector<int> cur = route;\n    vector<int> best_seq = route;\n    \n    auto calculate_cost = [&](const vector<int>& seq) {\n        int sum = 0;\n        for (size_t i = 0; i + 1 < seq.size(); ++i) {\n            sum += dist_mat[seq[i]][seq[i+1]];\n        }\n        return sum;\n    };\n    \n    int cur_cost = calculate_cost(cur);\n    int best_cost = cur_cost;\n    \n    array<int, 2001> pos; // position of each point index in current sequence\n    \n    auto is_valid = [&]() -> bool {\n        // Record positions of the 100 middle nodes\n        for (int i = 1; i <= 100; ++i) {\n            pos[cur[i]] = i;\n        }\n        for (int o : selected) {\n            if (pos[1 + o] >= pos[1 + N + o]) return false;\n        }\n        return true;\n    };\n    \n    // Verify initial validity\n    if (!is_valid()) {\n        // Fallback: should not happen with greedy insertion\n        cerr << \"Warning: Initial route invalid\\n\";\n    }\n    \n    mt19937 rng(123456);\n    uniform_int_distribution<int> dist_pos(1, 100); // movable range\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n    \n    Timer timer;\n    const double TL = 1.95; // Stop slightly before 2.0s\n    \n    const double T_start = 1000.0;\n    const double T_end = 0.1;\n    \n    long long iteration = 0;\n    while (timer.elapsed() < TL) {\n        double progress = timer.elapsed() / TL;\n        double T = T_start * pow(T_end / T_start, progress); // Exponential cooling\n        \n        int type = rng() % 2; // 0 = swap, 1 = 2-opt\n        int l, r;\n        bool do_reverse = false;\n        \n        if (type == 0) {\n            // Swap two positions\n            l = dist_pos(rng);\n            r = dist_pos(rng);\n            if (l == r) continue;\n            swap(cur[l], cur[r]);\n        } else {\n            // 2-opt: reverse [l, r]\n            l = dist_pos(rng);\n            r = dist_pos(rng);\n            if (l > r) swap(l, r);\n            if (l == r) continue;\n            reverse(cur.begin() + l, cur.begin() + r + 1);\n            do_reverse = true;\n        }\n        \n        if (!is_valid()) {\n            // Revert\n            if (do_reverse) {\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n            } else {\n                swap(cur[l], cur[r]);\n            }\n            continue;\n        }\n        \n        int new_cost = calculate_cost(cur);\n        int delta = new_cost - cur_cost;\n        \n        if (delta < 0 || dist_prob(rng) < exp(-delta / T)) {\n            cur_cost = new_cost;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_seq = cur;\n            }\n        } else {\n            // Revert\n            if (do_reverse) {\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n            } else {\n                swap(cur[l], cur[r]);\n            }\n        }\n        ++iteration;\n    }\n    \n    // ---------- Output ----------\n    cout << 50;\n    for (int o : selected) {\n        cout << ' ' << (o + 1); // convert to 1-indexed\n    }\n    cout << '\\n';\n    \n    cout << best_seq.size();\n    for (int idx : best_seq) {\n        cout << ' ' << xs[idx] << ' ' << ys[idx];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        r.assign(n, 0);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        return p[x] == x ? x : p[x] = find(p[x]);\n    }\n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n    void unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    \n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> xs[i] >> ys[i];\n    }\n    \n    vector<int> u(M), v(M);\n    vector<long long> d(M);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        long long dx = (long long)xs[u[i]] - xs[v[i]];\n        long long dy = (long long)ys[u[i]] - ys[v[i]];\n        long long dist_sq = dx * dx + dy * dy;\n        long long dist = (long long)(sqrt((double)dist_sq) + 0.5);\n        d[i] = dist;\n    }\n    \n    // Precompute which edges are bridges in the suffix graph G_i = (V, {e_i, e_{i+1}, ..., e_{M-1}})\n    vector<char> is_bridge(M, 0);\n    DSU dsu_back(N);\n    for (int i = M - 1; i >= 0; --i) {\n        if (dsu_back.same(u[i], v[i])) {\n            is_bridge[i] = 0;\n        } else {\n            is_bridge[i] = 1;\n            dsu_back.unite(u[i], v[i]);\n        }\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;\n        cin >> l;\n        \n        if (dsu.same(u[i], v[i])) {\n            cout << 0 << '\\n';\n        } else {\n            int need = components - 1;      // How many more edges we need\n            int remaining = M - i;          // How many edges remain (including current)\n            bool take = false;\n            \n            // If this edge is a bridge in the suffix, we must take it (no future path exists)\n            if (is_bridge[i]) {\n                take = true;\n            } \n            // If we skip this edge, we have 'remaining-1' edges left to connect 'need' components.\n            // If need > remaining-1, we cannot afford to skip.\n            else if (need >= remaining) {\n                take = true;\n            } \n            else {\n                // Dynamic threshold: stricter when we have many edges left, looser when few left\n                // Ratio need/remaining goes from ~0.2 to 1.0\n                double ratio = (double)need / (double)remaining;\n                double threshold = 1.0 + 2.0 * ratio; // ranges from ~1.4 to 3.0\n                \n                // Accept if the edge is cheaper than the threshold\n                if ((double)l <= threshold * (double)d[i]) {\n                    take = true;\n                } else {\n                    take = false;\n                }\n            }\n            \n            if (take) {\n                cout << 1 << '\\n';\n                dsu.unite(u[i], v[i]);\n                components--;\n            } else {\n                cout << 0 << '\\n';\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n    int target_x = -1, target_y = -1; // Target wall position to build\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool blocked[32][32]; // true if impassable\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char wall_cmd[4] = {'u', 'd', 'l', 'r'};\nconst char move_cmd[4] = {'U', 'D', 'L', 'R'};\n\nbool is_passable(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30 && !blocked[x][y];\n}\n\nbool can_place_wall(int x, int y) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) return false;\n    if (blocked[x][y]) return false;\n    \n    // Check if any pet or human is at (x,y)\n    for (auto& p : pets) {\n        if (p.x == x && p.y == y) return false;\n    }\n    for (auto& h : humans) {\n        if (h.x == x && h.y == y) return false;\n    }\n    \n    // Check if adjacent to any pet\n    for (auto& p : pets) {\n        for (int d = 0; d < 4; d++) {\n            if (p.x + dx[d] == x && p.y + dy[d] == y) return false;\n        }\n    }\n    return true;\n}\n\n// BFS to find path to target, returns next move direction or -1 if unreachable\nint bfs_next_move(int sx, int sy, int tx, int ty, vector<pair<int,int>>& other_positions) {\n    if (sx == tx && sy == ty) return -1;\n    \n    queue<pair<int,int>> q;\n    int dist[32][32];\n    int parent[32][32];\n    memset(dist, -1, sizeof(dist));\n    \n    q.push({sx, sy});\n    dist[sx][sy] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (!is_passable(nx, ny)) continue;\n            if (dist[nx][ny] != -1) continue;\n            \n            // Avoid other humans' current positions (simple collision avoidance)\n            bool occupied = false;\n            for (auto& pos : other_positions) {\n                if (pos.first == nx && pos.second == ny) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (occupied) continue;\n            \n            dist[nx][ny] = dist[x][y] + 1;\n            parent[nx][ny] = d;\n            if (nx == tx && ny == ty) {\n                // Backtrack to find first move\n                int cur_x = nx, cur_y = ny;\n                while (dist[cur_x][cur_y] > 1) {\n                    int pd = parent[cur_x][cur_y];\n                    cur_x -= dx[pd];\n                    cur_y -= dy[pd];\n                }\n                return parent[cur_x][cur_y];\n            }\n            q.push({nx, ny});\n        }\n    }\n    return -1; // unreachable\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Input\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    memset(blocked, false, sizeof(blocked));\n    \n    // Define target fortress rectangle around initial human positions\n    int min_x = 30, max_x = 1, min_y = 30, max_y = 1;\n    for (auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n    \n    // Expand by 2 to give some room, but keep within bounds [2,29]\n    min_x = max(2, min_x - 2);\n    max_x = min(29, max_x + 2);\n    min_y = max(2, min_y - 2);\n    max_y = min(29, max_y + 2);\n    \n    // Generate target wall positions (perimeter of rectangle)\n    vector<pair<int,int>> wall_targets;\n    // Top and bottom\n    for (int y = min_y; y <= max_y; y++) {\n        wall_targets.push_back({min_x, y});\n        wall_targets.push_back({max_x, y});\n    }\n    // Left and right (avoid corners duplicate)\n    for (int x = min_x + 1; x <= max_x - 1; x++) {\n        wall_targets.push_back({x, min_y});\n        wall_targets.push_back({x, max_y});\n    }\n    \n    // Assign targets to humans (round-robin or closest)\n    vector<vector<pair<int,int>>> assigned(M);\n    for (int i = 0; i < (int)wall_targets.size(); i++) {\n        assigned[i % M].push_back(wall_targets[i]);\n    }\n    \n    // Sort each human's targets by distance from start position\n    for (int i = 0; i < M; i++) {\n        sort(assigned[i].begin(), assigned[i].end(), [&](auto& a, auto& b) {\n            int da = abs(a.first - humans[i].x) + abs(a.second - humans[i].y);\n            int db = abs(b.first - humans[i].x) + abs(b.second - humans[i].y);\n            return da < db;\n        });\n        if (!assigned[i].empty()) {\n            humans[i].target_x = assigned[i][0].first;\n            humans[i].target_y = assigned[i][0].second;\n        }\n    }\n    \n    // Simulation\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        vector<pair<int,int>> planned_moves(M, {-1, -1});\n        vector<bool> will_block(M, false);\n        \n        // First pass: determine actions\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            \n            // Check if we need to update target (current target already blocked)\n            while (!assigned[i].empty() && \n                   blocked[assigned[i][0].first][assigned[i][0].second]) {\n                assigned[i].erase(assigned[i].begin());\n            }\n            if (!assigned[i].empty()) {\n                humans[i].target_x = assigned[i][0].first;\n                humans[i].target_y = assigned[i][0].second;\n            } else {\n                humans[i].target_x = -1;\n                humans[i].target_y = -1;\n            }\n            \n            // Try to build wall if at target\n            if (humans[i].target_x != -1) {\n                int tx = humans[i].target_x;\n                int ty = humans[i].target_y;\n                \n                // Check if adjacent to target\n                if (abs(hx - tx) + abs(hy - ty) == 1) {\n                    // Determine direction\n                    int d = -1;\n                    if (tx == hx - 1) d = 0;\n                    else if (tx == hx + 1) d = 1;\n                    else if (ty == hy - 1) d = 2;\n                    else if (ty == hy + 1) d = 3;\n                    \n                    if (d != -1 && can_place_wall(tx, ty)) {\n                        actions[i] = wall_cmd[d];\n                        will_block[i] = true;\n                        planned_moves[i] = {hx, hy}; // stays\n                        continue;\n                    }\n                }\n                \n                // Move toward target\n                vector<pair<int,int>> others;\n                for (int j = 0; j < M; j++) {\n                    if (i != j) others.push_back({humans[j].x, humans[j].y});\n                }\n                int nd = bfs_next_move(hx, hy, tx, ty, others);\n                if (nd != -1) {\n                    actions[i] = move_cmd[nd];\n                    planned_moves[i] = {hx + dx[nd], hy + dy[nd]};\n                } else {\n                    actions[i] = '.';\n                    planned_moves[i] = {hx, hy};\n                }\n            } else {\n                // No target, just stay or wander\n                actions[i] = '.';\n                planned_moves[i] = {hx, hy};\n            }\n        }\n        \n        // Check for conflicts: moving into a cell being blocked this turn\n        for (int i = 0; i < M; i++) {\n            if (actions[i] >= 'A' && actions[i] <= 'Z') { // Moving\n                for (int j = 0; j < M; j++) {\n                    if (i != j && will_block[j]) {\n                        int bx = humans[j].x, by = humans[j].y;\n                        if (actions[j] == 'u') bx--;\n                        else if (actions[j] == 'd') bx++;\n                        else if (actions[j] == 'l') by--;\n                        else if (actions[j] == 'r') by++;\n                        \n                        if (planned_moves[i].first == bx && planned_moves[i].second == by) {\n                            // Conflict: cancel move\n                            actions[i] = '.';\n                            planned_moves[i] = {humans[i].x, humans[i].y};\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Output actions\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n        \n        // Update grid and positions\n        for (int i = 0; i < M; i++) {\n            // Apply blocking\n            if (actions[i] == 'u') blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        \n        for (int i = 0; i < M; i++) {\n            // Apply movement\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    double score;                 // accumulated expected score so far\n    double value;                 // score + heuristic (for ordering)\n    array<double, 400> prob;      // distribution over cells\n    string s;                     // built string\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    const int N = 20;\n    auto ID = [&](int i, int j) { return i * N + j; };\n    const int target = ID(ti, tj);\n    const int start  = ID(si, sj);\n    \n    /*------------------------------------------------------------\n        1. Shortest path distances from the target (BFS)\n      ------------------------------------------------------------*/\n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    q.emplace(ti, tj);\n    dist[ti][tj] = 0;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) {               // U : check v[i-1][j]\n                if (i == 0) wall = true;\n                else wall = (v[i-1][j] == '1');\n            } else if (dir == 1) {        // D : check v[i][j]\n                if (i == 19) wall = true;\n                else wall = (v[i][j] == '1');\n            } else if (dir == 2) {        // L : check h[i][j-1]\n                if (j == 0) wall = true;\n                else wall = (h[i][j-1] == '1');\n            } else {                      // R : check h[i][j]\n                if (j == 19) wall = true;\n                else wall = (h[i][j] == '1');\n            }\n            if (wall) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        2. Pre\u2011compute moves (wall handling)\n      ------------------------------------------------------------*/\n    int nxt[400][4];\n    bool can_move[400][4];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int id = ID(i, j);\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                bool wall = false;\n                if (dir == 0) {\n                    if (i == 0) wall = true;\n                    else wall = (v[i-1][j] == '1');\n                } else if (dir == 1) {\n                    if (i == 19) wall = true;\n                    else wall = (v[i][j] == '1');\n                } else if (dir == 2) {\n                    if (j == 0) wall = true;\n                    else wall = (h[i][j-1] == '1');\n                } else {\n                    if (j == 19) wall = true;\n                    else wall = (h[i][j] == '1');\n                }\n                if (wall) {\n                    can_move[id][dir] = false;\n                    nxt[id][dir] = id;          // stay\n                } else {\n                    can_move[id][dir] = true;\n                    nxt[id][dir] = ID(ni, nj);\n                }\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        3. Beam Search\n      ------------------------------------------------------------*/\n    const int BEAM = 30;          // beam width, safe for 2\u2011second limit\n    vector<State> beam;\n    State init;\n    init.score = 0.0;\n    init.prob.fill(0.0);\n    init.prob[start] = 1.0;\n    init.s.clear();\n    beam.push_back(init);\n    \n    auto heuristic = [&](const array<double,400>& pr, int step)->double {\n        double h = 0.0;\n        for (int i = 0; i < 400; ++i) {\n            if (pr[i] < 1e-15) continue;\n            int r = i / 20, c = i % 20;\n            int d = dist[r][c];\n            if (d < 0) continue;          // should not happen (grid is connected)\n            int arrival = step + d;\n            if (arrival < 401) {\n                h += pr[i] * (401 - arrival);\n            }\n        }\n        return h;\n    };\n    \n    for (int step = 1; step <= 200; ++step) {\n        vector<State> cand;\n        cand.reserve(beam.size() * 4);\n        for (const State &st : beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                State ns;\n                ns.score = st.score;\n                ns.prob.fill(0.0);\n                // transition\n                for (int i = 0; i < 400; ++i) {\n                    double cur = st.prob[i];\n                    if (cur < 1e-15) continue;\n                    // forgot -> stay\n                    ns.prob[i] += cur * p;\n                    // try to move\n                    if (can_move[i][dir]) {\n                        int to = nxt[i][dir];\n                        if (to == target) {\n                            ns.score += cur * (1.0 - p) * (401 - step);\n                        } else {\n                            ns.prob[to] += cur * (1.0 - p);\n                        }\n                    } else {\n                        // blocked by wall -> stay\n                        ns.prob[i] += cur * (1.0 - p);\n                    }\n                }\n                ns.s = st.s + dc[dir];\n                double heu = heuristic(ns.prob, step);\n                ns.value = ns.score + heu;\n                cand.push_back(ns);\n            }\n        }\n        sort(cand.begin(), cand.end(),\n             [](const State& a, const State& b){ return a.value > b.value; });\n        beam.clear();\n        for (int i = 0; i < min(BEAM, (int)cand.size()); ++i) {\n            beam.push_back(cand[i]);\n        }\n        if (beam.empty()) break;\n    }\n    \n    // pick the one with best exact expected score\n    const State *best = &beam[0];\n    for (const State &st : beam) {\n        if (st.score > best->score) best = &st;\n    }\n    \n    cout << best->s << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Tile connection definitions\n// to[t][d]: exit direction when entering tile type t from direction d\n// d: 0=left, 1=up, 2=right, 3=down\n// exit: 0=left, 1=up, 2=right, 3=down, -1=no connection\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0: left-up corner\n    {3, -1, -1, 0},  // 1: left-down corner\n    {-1, -1, 3, 2},  // 2: right-down corner\n    {-1, 2, 1, -1},  // 3: up-right corner\n    {1, 0, 3, 2},    // 4: double curve (LU + RD)\n    {3, 2, 1, 0},    // 5: double curve (LD + RU)\n    {2, -1, 0, -1},  // 6: horizontal straight\n    {-1, 3, -1, 1}   // 7: vertical straight\n};\n\nconst int di[4] = {0, -1, 0, 1};  // row change for exit direction\nconst int dj[4] = {-1, 0, 1, 0};  // col change for exit direction\n\n// Rotate tile type t by r steps (90 deg CCW per step)\nint rotate_type(int t, int r) {\n    r &= 3; // r % 4\n    if (t < 4) {\n        return (t + r) & 3;\n    } else if (t < 6) {\n        // 4 <-> 5\n        return (r & 1) ? (t == 4 ? 5 : 4) : t;\n    } else {\n        // 6 <-> 7\n        return (r & 1) ? (t == 6 ? 7 : 6) : t;\n    }\n}\n\n// Fast evaluation of a configuration\n// Returns score = L1 * L2\nint evaluate(const array<array<int, 30>, 30>& rot, \n             const array<array<int, 30>, 30>& init,\n             vector<int>& cycles) {\n    static short nxt[3600];\n    static int dist[3600];\n    static unsigned short vis[3600];\n    static unsigned short vis_token = 1;\n    \n    // Build transition graph\n    // State: (i*30 + j)*4 + d\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = rotate_type(init[i][j], rot[i][j]);\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                int d2 = to[t][d];\n                if (d2 == -1) {\n                    nxt[base + d] = -1;\n                } else {\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                        nxt[base + d] = -1;\n                    } else {\n                        int nd = (d2 + 2) & 3; // opposite direction\n                        nxt[base + d] = (ni * 30 + nj) * 4 + nd;\n                    }\n                }\n            }\n        }\n    }\n    \n    cycles.clear();\n    \n    // Find cycles in functional graph\n    for (int s = 0; s < 3600; s++) {\n        if (vis[s] == vis_token) continue;\n        \n        int cur = s;\n        vector<int> path;\n        path.reserve(100);\n        \n        while (cur != -1) {\n            if (vis[cur] == vis_token) {\n                // Already visited - check if in current path\n                if (dist[cur] >= 0) {\n                    cycles.push_back((int)path.size() - dist[cur]);\n                }\n                break;\n            }\n            vis[cur] = vis_token;\n            dist[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        // Reset dist for path nodes\n        for (int node : path) {\n            dist[node] = -1;\n        }\n    }\n    \n    vis_token++;\n    if (vis_token == 0) {\n        memset(vis, 0, sizeof(vis));\n        vis_token = 1;\n    }\n    \n    // Get two largest cycles\n    nth_element(cycles.begin(), cycles.begin() + min(2, (int)cycles.size()), cycles.end(), greater<int>());\n    int L1 = cycles.size() > 0 ? cycles[0] : 0;\n    int L2 = cycles.size() > 1 ? cycles[1] : 0;\n    return L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    array<array<int, 30>, 30> init{};\n    for (int i = 0; i < 30; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < 30; j++) {\n            init[i][j] = s[j] - '0';\n        }\n    }\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_pos(0, 29);\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n    \n    vector<int> cycles;\n    cycles.reserve(1000);\n    \n    // Best solution found\n    array<array<int, 30>, 30> best_rot{};\n    int best_score = -1;\n    \n    // Try multiple restarts\n    const int NUM_RESTARTS = 3;\n    const double TIME_LIMIT = 1.9;\n    clock_t start_time = clock();\n    double time_per_restart = TIME_LIMIT / NUM_RESTARTS;\n    \n    for (int restart = 0; restart < NUM_RESTARTS; restart++) {\n        // Initialize random solution\n        array<array<int, 30>, 30> cur_rot{};\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cur_rot[i][j] = dist_rot(rng);\n            }\n        }\n        \n        int cur_score = evaluate(cur_rot, init, cycles);\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            best_rot = cur_rot;\n        }\n        \n        // Simulated Annealing parameters\n        double temp = 1000.0;\n        const double cooling = 0.99995;\n        \n        double restart_start = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        double restart_end = restart_start + time_per_restart;\n        \n        int iter = 0;\n        while (true) {\n            double now = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n            if (now >= restart_end || now >= TIME_LIMIT) break;\n            \n            // Pick random tile and change rotation\n            int i = dist_pos(rng);\n            int j = dist_pos(rng);\n            int old_r = cur_rot[i][j];\n            int new_r = dist_rot(rng);\n            if (old_r == new_r) continue;\n            \n            cur_rot[i][j] = new_r;\n            int new_score = evaluate(cur_rot, init, cycles);\n            \n            int delta = new_score - cur_score;\n            if (delta > 0 || dist_prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rot = cur_rot;\n                }\n            } else {\n                cur_rot[i][j] = old_r;\n            }\n            \n            temp *= cooling;\n            iter++;\n        }\n    }\n    \n    // Output result\n    string ans;\n    ans.reserve(900);\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            ans += char('0' + best_rot[i][j]);\n        }\n    }\n    cout << ans << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, T;\n    int er, ec;\n    array<array<int, 10>, 10> bd;\n    string moves;\n    int cur_score;\n    \n    int best_score;\n    string best_moves;\n    \n    mt19937 rng;\n    chrono::time_point<chrono::steady_clock> start_time;\n    \n    Solver(int n, int t, const vector<string>& board) : N(n), T(t), rng(123456789) {\n        best_score = -1;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = board[i][j];\n                int val = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n                bd[i][j] = val;\n                if (val == 0) {\n                    er = i;\n                    ec = j;\n                }\n            }\n        }\n        moves = \"\";\n        cur_score = calc_score();\n        update_best();\n    }\n    \n    int calc_score() {\n        int V = N * N;\n        vector<int> parent(V);\n        iota(parent.begin(), parent.end(), 0);\n        \n        function<int(int)> find = [&](int x) -> int {\n            return parent[x] == x ? x : parent[x] = find(parent[x]);\n        };\n        \n        auto unite = [&](int x, int y) {\n            x = find(x);\n            y = find(y);\n            if (x != y) parent[x] = y;\n        };\n        \n        // Connect components based on matching edges\n        // Right connections: current has right(4), next has left(1)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    unite(i * N + j, i * N + (j + 1));\n                }\n            }\n        }\n        // Down connections: current has down(8), below has up(2)\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    unite(i * N + j, (i + 1) * N + j);\n                }\n            }\n        }\n        \n        // Count vertices per component\n        vector<int> verts(V, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] != 0) {\n                    verts[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        // Count edges per component\n        vector<int> edges(V, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        // Find largest tree (connected and edges = vertices - 1)\n        int best = 0;\n        for (int i = 0; i < V; i++) {\n            if (verts[i] > 0 && edges[i] == verts[i] - 1) {\n                best = max(best, verts[i]);\n            }\n        }\n        return best;\n    }\n    \n    void update_best() {\n        if (cur_score > best_score || (cur_score == best_score && moves.size() < best_moves.size())) {\n            best_score = cur_score;\n            best_moves = moves;\n        }\n    }\n    \n    bool in_bounds(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    char reverse_move(char c) {\n        if (c == 'U') return 'D';\n        if (c == 'D') return 'U';\n        if (c == 'L') return 'R';\n        return 'L';\n    }\n    \n    void apply_move(char c) {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else if (c == 'R') nc++;\n        \n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n        moves.push_back(c);\n    }\n    \n    void undo_move() {\n        if (moves.empty()) return;\n        char c = moves.back();\n        moves.pop_back();\n        int nr = er, nc = ec;\n        if (c == 'U') nr++;\n        else if (c == 'D') nr--;\n        else if (c == 'L') nc++;\n        else if (c == 'R') nc++;\n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n    }\n    \n    string simplify(const string& s) {\n        // Remove consecutive opposite moves (e.g., \"UD\" or \"DU\")\n        string res = s;\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            string next;\n            for (size_t i = 0; i < res.size(); ) {\n                if (i + 1 < res.size() && res[i] == reverse_move(res[i+1])) {\n                    i += 2;\n                    changed = true;\n                } else {\n                    next.push_back(res[i]);\n                    i++;\n                }\n            }\n            res = next;\n        }\n        return res;\n    }\n    \n    void solve() {\n        start_time = chrono::steady_clock::now();\n        const double TL = 2.8; // Time limit in seconds\n        \n        double temp = 50.0;\n        const double cooling = 0.99995;\n        int iter = 0;\n        \n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > TL) break;\n            \n            // Reset if path gets too long\n            if ((int)moves.size() >= T - 10) {\n                while (!moves.empty()) undo_move();\n                cur_score = calc_score();\n                temp = 50.0;\n                continue;\n            }\n            \n            // Generate valid candidate moves (not reversing previous)\n            char prev_rev = moves.empty() ? 'X' : reverse_move(moves.back());\n            vector<pair<char, int>> candidates; // move, delta_score\n            \n            for (char c : {'U', 'D', 'L', 'R'}) {\n                if (c == prev_rev) continue;\n                int nr = er, nc = ec;\n                if (c == 'U') nr--;\n                else if (c == 'D') nr++;\n                else if (c == 'L') nc--;\n                else if (c == 'R') nc++;\n                if (!in_bounds(nr, nc)) continue;\n                \n                // Try move temporarily\n                swap(bd[er][ec], bd[nr][nc]);\n                int new_score = calc_score();\n                swap(bd[er][ec], bd[nr][nc]); // restore\n                \n                candidates.push_back({c, new_score - cur_score});\n            }\n            \n            if (candidates.empty()) {\n                if (!moves.empty()) {\n                    undo_move();\n                    cur_score = calc_score();\n                }\n                continue;\n            }\n            \n            // Sort by improvement\n            sort(candidates.begin(), candidates.end(), \n                 [](const auto& a, const auto& b) { return a.second > b.second; });\n            \n            char chosen;\n            int new_score;\n            bool do_move = false;\n            \n            if (candidates[0].second >= 0) {\n                // Greedy: take best improving move\n                chosen = candidates[0].first;\n                new_score = cur_score + candidates[0].second;\n                do_move = true;\n            } else {\n                // Simulated annealing: pick random and accept with probability\n                uniform_int_distribution<int> dist(0, candidates.size() - 1);\n                int idx = dist(rng);\n                chosen = candidates[idx].first;\n                new_score = cur_score + candidates[idx].second;\n                \n                double prob = exp((new_score - cur_score) / temp);\n                if (uniform_real_distribution<double>(0, 1)(rng) < prob) {\n                    do_move = true;\n                }\n            }\n            \n            if (do_move) {\n                apply_move(chosen);\n                cur_score = new_score;\n                update_best();\n            }\n            \n            temp *= cooling;\n            \n            // Periodic restart to escape local optima\n            if (++iter % 10000 == 0) {\n                if (best_score < N * N - 1 && (rng() & 0xFF) < 30) {\n                    while (!moves.empty()) undo_move();\n                    cur_score = calc_score();\n                    temp = 50.0;\n                }\n            }\n        }\n        \n        // Simplify if perfect solution found\n        if (best_score == N * N - 1) {\n            string simp = simplify(best_moves);\n            if (simp.size() < best_moves.size()) best_moves = simp;\n        }\n    }\n    \n    string get_result() {\n        return best_moves;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    cin >> N >> T;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    Solver solver(N, T, board);\n    solver.solve();\n    cout << solver.get_result() << \"\\n\";\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long x1, y1, x2, y2;\n};\n\nint N, K;\nint target[11];\nvector<Point> pts;\nvector<Line> cuts;\n\n// Current partition: piece_id[i] = index of piece for strawberry i\nvector<int> piece_id;\n// List of pieces (each is list of indices)\nvector<vector<int>> pieces;\nint cur_cnt[12]; // cur_cnt[d] for d=1..10, cur_cnt[0] for >10 or empty\n\nint calc_score() {\n    int res = 0;\n    for (int d = 1; d <= 10; d++) {\n        res += min(cur_cnt[d], target[d]);\n    }\n    return res;\n}\n\n// side: -1 for left, 1 for right, 0 for on line\nint side(const Point& p, const Line& ln) {\n    long long v1x = ln.x2 - ln.x1;\n    long long v1y = ln.y2 - ln.y1;\n    long long v2x = p.x - ln.x1;\n    long long v2y = p.y - ln.y1;\n    long long cr = v1x * v2y - v1y * v2x;\n    if (cr < 0) return -1;\n    if (cr > 0) return 1;\n    return 0;\n}\n\n// Apply cut and update state\nvoid apply_cut(const Line& ln) {\n    vector<vector<int>> new_pieces;\n    vector<int> new_id(N);\n    new_pieces.reserve(pieces.size() * 2);\n    \n    int pid = 0;\n    for (auto& pc : pieces) {\n        vector<int> left, right;\n        left.reserve(pc.size());\n        right.reserve(pc.size());\n        for (int idx : pc) {\n            int s = side(pts[idx], ln);\n            if (s == 0) {\n                // Should not happen if we generate lines correctly\n                // Put to left arbitrarily\n                left.push_back(idx);\n            } else if (s < 0) {\n                left.push_back(idx);\n            } else {\n                right.push_back(idx);\n            }\n        }\n        if (!left.empty()) {\n            for (int idx : left) new_id[idx] = pid;\n            new_pieces.push_back(move(left));\n            pid++;\n        }\n        if (!right.empty()) {\n            for (int idx : right) new_id[idx] = pid;\n            new_pieces.push_back(move(right));\n            pid++;\n        }\n    }\n    \n    pieces = move(new_pieces);\n    piece_id = move(new_id);\n    \n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    for (auto& pc : pieces) {\n        int s = pc.size();\n        if (1 <= s && s <= 10) cur_cnt[s]++;\n        else if (s > 10) cur_cnt[0]++;\n    }\n}\n\n// Generate a random line attempting to split a specific piece\n// Returns line and the expected sizes (approximate)\nLine generate_cut_for_piece(const vector<int>& pc, int& out_left, int& out_right) {\n    int n = pc.size();\n    out_left = n/2;\n    out_right = n - n/2;\n    \n    if (n < 2) return {0,0,0,0};\n    \n    // Random projection direction\n    double theta = (double)rand() / RAND_MAX * 2.0 * M_PI;\n    long long dx = (long long)(cos(theta) * 1000000);\n    long long dy = (long long)(sin(theta) * 1000000);\n    \n    // Project\n    vector<pair<long long, int>> proj;\n    proj.reserve(n);\n    for (int idx : pc) {\n        long long dot = pts[idx].x * dx + pts[idx].y * dy;\n        proj.emplace_back(dot, idx);\n    }\n    sort(proj.begin(), proj.end());\n    \n    // Try to cut at various positions\n    vector<int> try_pos;\n    // Try to isolate small groups that are needed\n    for (int d = 1; d <= min(10, n-1); d++) {\n        if (target[d] > cur_cnt[d]) {\n            try_pos.push_back(d);\n        }\n    }\n    // Also try middle\n    try_pos.push_back(n/2);\n    \n    for (int d : try_pos) {\n        if (d <= 0 || d >= n) continue;\n        // Cut between d-1 and d\n        // Find perpendicular direction\n        // Original direction: (dx, dy), perpendicular: (-dy, dx)\n        long long px = -dy;\n        long long py = dx;\n        \n        // Midpoint between proj[d-1] and proj[d]\n        long long midx = (pts[proj[d-1].second].x + pts[proj[d].second].x) / 2;\n        long long midy = (pts[proj[d-1].second].y + pts[proj[d].second].y) / 2;\n        \n        // Line: passes through (midx, midy), direction (px, py)\n        // Use points far away to ensure integer coordinates and range\n        Line ln;\n        ln.x1 = midx - px;\n        ln.y1 = midy - py;\n        ln.x2 = midx + px;\n        ln.y2 = midy + py;\n        \n        // Check range\n        if (abs(ln.x1) > 1e9 || abs(ln.y1) > 1e9 || abs(ln.x2) > 1e9 || abs(ln.y2) > 1e9) {\n            // Scale down or skip\n            continue;\n        }\n        \n        // Verify no point on line\n        bool ok = true;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) == 0) {\n                ok = false;\n                break;\n            }\n        }\n        if (!ok) continue;\n        \n        // Count actual split\n        int lc = 0, rc = 0;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) < 0) lc++;\n            else rc++;\n        }\n        if (lc == 0 || rc == 0) continue;\n        \n        out_left = lc;\n        out_right = rc;\n        return ln;\n    }\n    \n    return {0,0,0,0};\n}\n\n// Generate completely random line\nLine generate_random_cut() {\n    Line ln;\n    ln.x1 = (rand() % 2000000000) - 1000000000;\n    ln.y1 = (rand() % 2000000000) - 1000000000;\n    ln.x2 = (rand() % 2000000000) - 1000000000;\n    ln.y2 = (rand() % 2000000000) - 1000000000;\n    if (ln.x1 == ln.x2 && ln.y1 == ln.y2) {\n        ln.x2++;\n    }\n    \n    // Ensure no point on line\n    bool bad = true;\n    int attempts = 0;\n    while (bad && attempts < 10) {\n        bad = false;\n        for (int i = 0; i < N; i++) {\n            if (side(pts[i], ln) == 0) {\n                bad = true;\n                ln.x2 += (rand() % 10) - 5;\n                ln.y2 += (rand() % 10) - 5;\n                attempts++;\n                break;\n            }\n        }\n    }\n    return ln;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(42); // Fixed seed for reproducibility, can use time(0) in contest\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> target[i];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n    \n    // Initial state: one piece containing all\n    pieces.resize(1);\n    pieces[0].resize(N);\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n    piece_id.assign(N, 0);\n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    if (N <= 10) cur_cnt[N] = 1;\n    else cur_cnt[0] = 1;\n    \n    int current_score = calc_score();\n    \n    for (int iter = 0; iter < K; iter++) {\n        Line best_ln = {0,0,0,0};\n        int best_new_score = current_score;\n        bool found = false;\n        \n        // Identify candidate pieces to split\n        vector<int> cand_pieces;\n        for (int i = 0; i < pieces.size(); i++) {\n            int s = pieces[i].size();\n            if (s > 1) {\n                // Split if too large or we have excess of this size\n                if (s > 10 || (s <= 10 && cur_cnt[s] > target[s])) {\n                    cand_pieces.push_back(i);\n                }\n            }\n        }\n        \n        if (cand_pieces.empty()) {\n            // Try to improve by splitting any piece that might allow better distribution\n            for (int i = 0; i < pieces.size(); i++) {\n                if (pieces[i].size() > 1) cand_pieces.push_back(i);\n            }\n        }\n        \n        if (cand_pieces.empty()) break;\n        \n        // Try candidates from specific pieces\n        for (int pid : cand_pieces) {\n            for (int t = 0; t < 30; t++) {\n                int lc, rc;\n                Line ln = generate_cut_for_piece(pieces[pid], lc, rc);\n                if (ln.x1 == 0 && ln.y1 == 0) continue;\n                \n                // Quick evaluation: compute delta score\n                int delta = 0;\n                int s = pieces[pid].size();\n                \n                // Remove s\n                if (s <= 10) {\n                    delta -= min(cur_cnt[s], target[s]) - min(cur_cnt[s]-1, target[s]);\n                }\n                // Add lc, rc\n                if (lc <= 10 && lc >= 1) {\n                    delta += min(cur_cnt[lc]+1, target[lc]) - min(cur_cnt[lc], target[lc]);\n                }\n                if (rc <= 10 && rc >= 1 && rc != lc) {\n                    delta += min(cur_cnt[rc]+1, target[rc]) - min(cur_cnt[rc], target[rc]);\n                } else if (rc == lc && rc <= 10 && rc >= 1) {\n                    // If both sides same size, we added 2, but above counted 1\n                    delta += min(cur_cnt[rc]+2, target[rc]) - min(cur_cnt[rc]+1, target[rc]);\n                }\n                \n                // But this delta calculation ignores other pieces being split!\n                // The generate_cut_for_piece only checks the target piece.\n                // We need full simulation.\n                \n                // Full simulation\n                auto old_pieces = pieces;\n                auto old_pid = piece_id;\n                auto old_cnt = cur_cnt;\n                int old_score = current_score;\n                \n                apply_cut(ln);\n                int new_score = calc_score();\n                \n                if (new_score > best_new_score) {\n                    best_new_score = new_score;\n                    best_ln = ln;\n                    found = true;\n                }\n                \n                // Restore\n                pieces = old_pieces;\n                piece_id = old_pid;\n                memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n                current_score = old_score;\n            }\n        }\n        \n        // Also try some random cuts\n        for (int t = 0; t < 20; t++) {\n            Line ln = generate_random_cut();\n            \n            auto old_pieces = pieces;\n            auto old_pid = piece_id;\n            auto old_cnt = cur_cnt;\n            \n            apply_cut(ln);\n            int new_score = calc_score();\n            \n            if (new_score > best_new_score) {\n                best_new_score = new_score;\n                best_ln = ln;\n                found = true;\n            }\n            \n            pieces = old_pieces;\n            piece_id = old_pid;\n            memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n        }\n        \n        if (!found) break;\n        \n        apply_cut(best_ln);\n        cuts.push_back(best_ln);\n        current_score = best_new_score;\n    }\n    \n    cout << cuts.size() << \"\\n\";\n    for (auto& ln : cuts) {\n        cout << ln.x1 << \" \" << ln.y1 << \" \" << ln.x2 << \" \" << ln.y2 << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint C;                          // centre (N-1)/2\nvector<vector<bool>> has_dot;   // true if a dot exists\nvector<vector<bool>> edge_h;    // horizontal (x,y)-(x+1,y)\nvector<vector<bool>> edge_v;    // vertical   (x,y)-(x,y+1)\nvector<vector<bool>> edge_d1;   // diagonal /   (x,y)-(x+1,y+1)\nvector<vector<bool>> edge_d2;   // diagonal \\   (x,y)-(x+1,y-1)\n\nstruct Operation {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\nvector<Operation> ops;\n\n// check axis-aligned rectangle (p1,p2,p3,p4) = (x1,y1),(x2,y1),(x2,y2),(x1,y2)\nbool check_axis(int x1, int y1, int x2, int y2) {\n    if (x1 == x2 || y1 == y2) return false;               // degenerate\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n\n    // condition 2: no other dots on the perimeter\n    // bottom side (y = yl)\n    for (int x = xl + 1; x < xr; ++x) if (has_dot[x][yl]) return false;\n    // top side (y = yr)\n    for (int x = xl + 1; x < xr; ++x) if (has_dot[x][yr]) return false;\n    // left side (x = xl)\n    for (int y = yl + 1; y < yr; ++y) if (has_dot[xl][y]) return false;\n    // right side (x = xr)\n    for (int y = yl + 1; y < yr; ++y) if (has_dot[xr][y]) return false;\n\n    // condition 3: edges must be unused\n    // bottom\n    for (int x = xl; x < xr; ++x) if (edge_h[x][yl]) return false;\n    // top\n    for (int x = xl; x < xr; ++x) if (edge_h[x][yr]) return false;\n    // left\n    for (int y = yl; y < yr; ++y) if (edge_v[xl][y]) return false;\n    // right\n    for (int y = yl; y < yr; ++y) if (edge_v[xr][y]) return false;\n\n    return true;\n}\n\n// mark edges of axis-aligned rectangle\nvoid add_axis(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    for (int x = xl; x < xr; ++x) edge_h[x][yl] = true;\n    for (int x = xl; x < xr; ++x) edge_h[x][yr] = true;\n    for (int y = yl; y < yr; ++y) edge_v[xl][y] = true;\n    for (int y = yl; y < yr; ++y) edge_v[xr][y] = true;\n}\n\n// check 45-degree rectangle.\n// p1=(x1,y1), p3=(x3,y3).  a=(dx+dy)/2, b=(dx-dy)/2.\n// p2 = (x1+a, y1+a), p4 = (x1+b, y1-b)\nbool check_45(int x1, int y1, int a, int b, int &x2, int &y2, int &x3, int &y3, int &x4, int &y4) {\n    if (a == 0 || b == 0) return false;\n    x2 = x1 + a; y2 = y1 + a;\n    x4 = x1 + b; y4 = y1 - b;\n    x3 = x1 + a + b; y3 = y1 + a - b;\n\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) return false;\n    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) return false;\n\n    if (!has_dot[x2][y2] || !has_dot[x4][y4] || !has_dot[x3][y3]) return false;\n\n    // Helper to walk a 45-degree segment from (xs,ys) to (xt,yt) (exclusive of ends) checking dots and edges.\n    auto walk = [&](int xs, int ys, int xt, int yt) -> bool {\n        int dx = (xt > xs) ? 1 : -1;\n        int dy = (yt > ys) ? 1 : -1;\n        int len = abs(xt - xs); // = abs(yt-ys)\n        for (int i = 1; i < len; ++i) {\n            int x = xs + i * dx;\n            int y = ys + i * dy;\n            if (has_dot[x][y]) return false;\n        }\n        // edges\n        for (int i = 0; i < len; ++i) {\n            int x = xs + i * dx;\n            int y = ys + i * dy;\n            if (dx == dy) { // up-right or down-left -> d1\n                if (edge_d1[x][y]) return false;\n            } else { // up-left or down-right -> d2\n                if (edge_d2[x][y]) return false;\n            }\n        }\n        return true;\n    };\n\n    // four sides: p1-p2, p2-p3, p3-p4, p4-p1\n    if (!walk(x1, y1, x2, y2)) return false;\n    if (!walk(x2, y2, x3, y3)) return false;\n    if (!walk(x3, y3, x4, y4)) return false;\n    if (!walk(x4, y4, x1, y1)) return false;\n\n    return true;\n}\n\n// mark edges of 45-degree rectangle\nvoid add_45(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto mark = [&](int xs, int ys, int xt, int yt) {\n        int dx = (xt > xs) ? 1 : -1;\n        int dy = (yt > ys) ? 1 : -1;\n        int len = abs(xt - xs);\n        for (int i = 0; i < len; ++i) {\n            int x = xs + i * dx;\n            int y = ys + i * dy;\n            if (dx == dy) edge_d1[x][y] = true;\n            else          edge_d2[x][y] = true;\n        }\n    };\n    mark(x1, y1, x2, y2);\n    mark(x2, y2, x3, y3);\n    mark(x3, y3, x4, y4);\n    mark(x4, y4, x1, y1);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    C = (N - 1) / 2;\n\n    has_dot.assign(N, vector<bool>(N, false));\n    vector<pair<int,int>> dots;\n    dots.reserve(N * N);\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        has_dot[x][y] = true;\n        dots.emplace_back(x, y);\n    }\n\n    edge_h.assign(N, vector<bool>(N, false));\n    edge_v.assign(N, vector<bool>(N, false));\n    edge_d1.assign(N, vector<bool>(N, false));\n    edge_d2.assign(N, vector<bool>(N, false));\n\n    // list all empty cells sorted by weight descending (high weight = far from centre)\n    vector<tuple<int,int,int>> cand; // (weight, x, y)\n    cand.reserve(N * N);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y < N; ++y) {\n            if (!has_dot[x][y]) {\n                int w = (x - C) * (x - C) + (y - C) * (y - C) + 1;\n                cand.emplace_back(w, x, y);\n            }\n        }\n    }\n    sort(cand.rbegin(), cand.rend());\n\n    // try to fill every cell in order of decreasing weight\n    for (auto &[w, x1, y1] : cand) {\n        if (has_dot[x1][y1]) continue; // already filled by previous operation\n\n        bool placed = false;\n        int bx2, by2, bx3, by3, bx4, by4;\n        bool is_axis = false;\n\n        // --- try axis aligned (p3 is diagonal) ---\n        // iterate over existing dots as p3\n        for (auto [x3, y3] : dots) {\n            if (x3 == x1 || y3 == y1) continue; // must be diagonal\n            int x2 = x3, y2 = y1;\n            int x4 = x1, y4 = y3;\n            if (!has_dot[x2][y2] || !has_dot[x4][y4]) continue;\n            if (check_axis(x1, y1, x3, y3)) {\n                placed = true;\n                bx2 = x2; by2 = y2;\n                bx3 = x3; by3 = y3;\n                bx4 = x4; by4 = y4;\n                is_axis = true;\n                break; // take the first valid one\n            }\n        }\n\n        // --- try 45-degree ---\n        if (!placed) {\n            for (auto [x3, y3] : dots) {\n                int dx = x3 - x1;\n                int dy = y3 - y1;\n                if ( (dx + dy) & 1 ) continue;\n                if ( (dx - dy) & 1 ) continue;\n                int a = (dx + dy) >> 1;\n                int b = (dx - dy) >> 1;\n                int x2, y2, x4, y4;\n                if (check_45(x1, y1, a, b, x2, y2, x3, y3, x4, y4)) {\n                    placed = true;\n                    bx2 = x2; by2 = y2;\n                    bx3 = x3; by3 = y3;\n                    bx4 = x4; by4 = y4;\n                    is_axis = false;\n                    break;\n                }\n            }\n        }\n\n        if (placed) {\n            ops.push_back({x1, y1, bx2, by2, bx3, by3, bx4, by4});\n            has_dot[x1][y1] = true;\n            dots.emplace_back(x1, y1);\n            if (is_axis) {\n                add_axis(x1, y1, bx3, by3);\n            } else {\n                add_45(x1, y1, bx2, by2, bx3, by3, bx4, by4);\n            }\n        }\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto &op : ops) {\n        cout << op.x1 << ' ' << op.y1 << ' '\n             << op.x2 << ' ' << op.y2 << ' '\n             << op.x3 << ' ' << op.y3 << ' '\n             << op.x4 << ' ' << op.y4 << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Grid {\n    uint8_t a[10][10];\n    Grid() {\n        memset(a, 0, sizeof(a));\n    }\n    Grid(const Grid& o) {\n        memcpy(a, o.a, sizeof(a));\n    }\n    \n    void place(int p, int f) {\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') {\n            for (int j = 0; j < 10; j++) {\n                int write = 0;\n                for (int i = 0; i < 10; i++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write++][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'B') {\n            for (int j = 0; j < 10; j++) {\n                int write = 9;\n                for (int i = 9; i >= 0; i--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write--][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'L') {\n            for (int i = 0; i < 10; i++) {\n                int write = 0;\n                for (int j = 0; j < 10; j++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write++] = val;\n                    }\n                }\n            }\n        } else if (dir == 'R') {\n            for (int i = 0; i < 10; i++) {\n                int write = 9;\n                for (int j = 9; j >= 0; j--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write--] = val;\n                    }\n                }\n            }\n        }\n    }\n    \n    long long calcScore() {\n        bool vis[10][10] = {};\n        long long res = 0;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] != 0 && !vis[i][j]) {\n                    uint8_t f = a[i][j];\n                    int sz = 0;\n                    int q[100];\n                    int qs = 0, qe = 0;\n                    q[qe++] = i * 10 + j;\n                    vis[i][j] = true;\n                    while (qs < qe) {\n                        int cur = q[qs++];\n                        int x = cur / 10, y = cur % 10;\n                        sz++;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !vis[nx][ny] && a[nx][ny] == f) {\n                                vis[nx][ny] = true;\n                                q[qe++] = nx * 10 + ny;\n                            }\n                        }\n                    }\n                    res += 1LL * sz * sz;\n                }\n            }\n        }\n        return res;\n    }\n    \n    void getEmpties(vector<pair<int,int>>& res) {\n        res.clear();\n        for (int i = 0; i < 10; i++)\n            for (int j = 0; j < 10; j++)\n                if (a[i][j] == 0)\n                    res.push_back({i, j});\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> f[i];\n    }\n    \n    Grid grid;\n    vector<pair<int,int>> empties;\n    empties.reserve(100);\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        grid.place(p, f[t]);\n        \n        if (t == 99) {\n            cout << \"F\\n\";\n            break;\n        }\n        \n        // Adaptive simulation count based on remaining steps\n        int remaining = 99 - t;\n        int sims = max(20, min(80, 2000 / (remaining + 1)));\n        \n        char bestDir = 'F';\n        double bestAvg = -1.0;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid test = grid;\n            test.tilt(dir);\n            \n            long long totalScore = 0;\n            \n            for (int s = 0; s < sims; s++) {\n                Grid sim = test;\n                // Simulate future steps\n                for (int tt = t + 1; tt < 100; tt++) {\n                    sim.getEmpties(empties);\n                    if (empties.empty()) break;\n                    uniform_int_distribution<int> dist(0, empties.size() - 1);\n                    auto [x, y] = empties[dist(rng)];\n                    sim.a[x][y] = f[tt];\n                    // Greedy or random tilt for rollout\n                    char d = \"FBRL\"[rng() & 3];\n                    sim.tilt(d);\n                }\n                totalScore += sim.calcScore();\n            }\n            \n            double avg = (double)totalScore / sims;\n            if (avg > bestAvg) {\n                bestAvg = avg;\n                bestDir = dir;\n            }\n        }\n        \n        grid.tilt(bestDir);\n        cout << bestDir << \"\\n\" << flush;\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\n\nusing namespace std;\n\nint N, M;\ndouble eps;\n\nstruct Graph {\n    vector<bitset<4950>> adj; // adjacency matrix as bitset per row (max N=100, max edges=4950)\n    vector<int> degree;\n    vector<int> order; // canonical order: permutation to apply to get canonical form\n    string canonical_str; // edge string in canonical order\n};\n\nvector<Graph> graphs;\n\n// Convert (i, j) to index in edge string, assuming i < j\ninline int edge_idx(int i, int j, int n) {\n    return i * n - i * (i + 1) / 2 + (j - i - 1);\n}\n\n// Build canonical string from adjacency matrix (symmetric) and vertex order\nstring build_canonical_string(const vector<bitset<4950>>& adj, const vector<int>& order, int n) {\n    string s;\n    s.reserve(n * (n - 1) / 2);\n    int m = order.size();\n    for (int ii = 0; ii < m; ++ii) {\n        for (int jj = ii + 1; jj < m; ++jj) {\n            int i = order[ii];\n            int j = order[jj];\n            s.push_back(adj[i].test(j) ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Compute degree sequence from adjacency matrix\nvector<int> compute_degrees(const vector<bitset<4950>>& adj, int n) {\n    vector<int> deg(n, 0);\n    for (int i = 0; i < n; ++i) {\n        deg[i] = adj[i].count();\n    }\n    return deg;\n}\n\n// Get canonical order by (degree, sum of neighbor degrees) descending\nvector<int> get_canonical_order(const vector<bitset<4950>>& adj, const vector<int>& deg, int n) {\n    vector<long long> neighbor_sum(n, 0);\n    for (int i = 0; i < n; ++i) {\n        long long sum = 0;\n        for (int j = 0; j < n; ++j) {\n            if (adj[i].test(j)) sum += deg[j];\n        }\n        neighbor_sum[i] = sum;\n    }\n    \n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (deg[a] != deg[b]) return deg[a] > deg[b];\n        if (neighbor_sum[a] != neighbor_sum[b]) return neighbor_sum[a] > neighbor_sum[b];\n        return a < b; // tie-breaker\n    });\n    return order;\n}\n\n// Parse edge string to adjacency matrix\nvector<bitset<4950>> parse_graph(const string& s, int n) {\n    vector<bitset<4950>> adj(n);\n    int pos = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[pos++] == '1') {\n                adj[i].set(j);\n                adj[j].set(i);\n            }\n        }\n    }\n    return adj;\n}\n\n// Hamming distance between two edge strings\nint hamming_dist(const string& a, const string& b) {\n    int dist = 0;\n    // Process 64 bits at a time using uint64_t for speedup if needed, but simple loop is fine for 5000*100*100=50M\n    for (size_t i = 0; i < a.size(); ++i) {\n        dist += (a[i] != b[i]);\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> M >> eps;\n    \n    // Choose N based on epsilon: larger epsilon needs larger N for robustness\n    // Heuristic: N = 30 + 150 * eps, capped at 100, min 20\n    int N_calc = (int)(25 + 160 * eps);\n    N = max(20, min(100, N_calc));\n    if (N < 4) N = 4;\n    \n    // Generate M graphs\n    graphs.resize(M);\n    mt19937 rng(42);\n    \n    for (int idx = 0; idx < M; ++idx) {\n        // Generate random graph G(N, 0.5) with seed = idx\n        mt19937 gen(idx);\n        bernoulli_distribution d(0.5);\n        \n        vector<bitset<4950>> adj(N);\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (d(gen)) {\n                    adj[i].set(j);\n                    adj[j].set(i);\n                }\n            }\n        }\n        \n        graphs[idx].adj = adj;\n        graphs[idx].degree = compute_degrees(adj, N);\n        graphs[idx].order = get_canonical_order(adj, graphs[idx].degree, N);\n        graphs[idx].canonical_str = build_canonical_string(adj, graphs[idx].order, N);\n    }\n    \n    // Output\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << graphs[i].canonical_str << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        // Parse H\n        auto h_adj = parse_graph(h_str, N);\n        auto h_deg = compute_degrees(h_adj, N);\n        auto h_order = get_canonical_order(h_adj, h_deg, N);\n        string h_canonical = build_canonical_string(h_adj, h_order, N);\n        \n        // Find best match by Hamming distance\n        int best_idx = 0;\n        int min_dist = N * N; // large\n        \n        for (int i = 0; i < M; ++i) {\n            int dist = hamming_dist(h_canonical, graphs[i].canonical_str);\n            if (dist < min_dist) {\n                min_dist = dist;\n                best_idx = i;\n            }\n        }\n        \n        cout << best_idx << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N); // (to, edge_id)\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    // Read and ignore coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    const long long INF = (long long)1e12;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Precompute original distances (needed for priority calculation and final check)\n    vector<vector<long long>> orig_dist(N, vector<long long>(N, INF));\n    for (int s = 0; s < N; s++) {\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        orig_dist[s][s] = 0;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != orig_dist[s][u]) continue;\n            for (auto [v, eid] : adj[u]) {\n                int w = edges[eid].w;\n                if (orig_dist[s][v] > d + w) {\n                    orig_dist[s][v] = d + w;\n                    pq.push({orig_dist[s][v], v});\n                }\n            }\n        }\n    }\n    \n    // Calculate edge priority (importance) using sampling\n    // Priority is roughly the number of shortest path trees the edge appears in\n    vector<double> priority(M, 0.0);\n    const int NUM_SAMPLES = 50;\n    for (int iter = 0; iter < NUM_SAMPLES; iter++) {\n        int s = rng() % N;\n        vector<long long> dist = orig_dist[s]; // Already computed\n        \n        // Identify edges in shortest path DAG from s\n        for (int i = 0; i < M; i++) {\n            int u = edges[i].u, v = edges[i].v, w = edges[i].w;\n            if (dist[u] + w == dist[v] || dist[v] + w == dist[u]) {\n                priority[i] += 1.0;\n            }\n        }\n    }\n    \n    // Normalize priorities\n    double max_prio = *max_element(priority.begin(), priority.end());\n    if (max_prio > 0) {\n        for (int i = 0; i < M; i++) priority[i] /= max_prio;\n    }\n    \n    // Initial solution: greedy assignment balancing priority sums\n    vector<int> assign(M, -1);\n    vector<vector<int>> day_edges(D);\n    vector<double> day_load(D, 0.0);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    // Sort by priority descending to distribute important edges first\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return priority[a] > priority[b];\n    });\n    \n    for (int eid : order) {\n        // Find day with minimum load that has capacity\n        int best_day = -1;\n        double min_load = 1e100;\n        for (int d = 0; d < D; d++) {\n            if ((int)day_edges[d].size() < K && day_load[d] < min_load) {\n                min_load = day_load[d];\n                best_day = d;\n            }\n        }\n        if (best_day == -1) {\n            // Fallback: find any day with capacity (should not happen)\n            for (int d = 0; d < D; d++) {\n                if ((int)day_edges[d].size() < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n        }\n        assign[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_load[best_day] += priority[eid];\n    }\n    \n    // Helper to calculate day score (sum of priorities)\n    auto calc_day_score = [&](int day) -> double {\n        return day_load[day];\n    };\n    \n    // Local search: swap edges between days to balance loads\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 5.0; // seconds\n    \n    int iterations = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        iterations++;\n        \n        // Select two random days\n        int d1 = rng() % D;\n        int d2 = rng() % D;\n        if (d1 == d2) continue;\n        if (day_edges[d1].empty() || day_edges[d2].empty()) continue;\n        \n        // Select random edges\n        int idx1 = rng() % day_edges[d1].size();\n        int idx2 = rng() % day_edges[d2].size();\n        int e1 = day_edges[d1][idx1];\n        int e2 = day_edges[d2][idx2];\n        \n        double old_score = day_load[d1] + day_load[d2];\n        \n        // Tentative swap\n        double new_load1 = day_load[d1] - priority[e1] + priority[e2];\n        double new_load2 = day_load[d2] - priority[e2] + priority[e1];\n        double new_score = new_load1 + new_load2;\n        \n        // Accept if reduces variance (sum of squares) or simply balances\n        // Actually, we want to minimize max load, but sum is good proxy for balancing\n        // Accept if max(new_load1, new_load2) < max(day_load[d1], day_load[d2]) \n        // or if the range decreases\n        double old_max = max(day_load[d1], day_load[d2]);\n        double new_max = max(new_load1, new_load2);\n        \n        if (new_max < old_max || (new_max == old_max && new_score < old_score)) {\n            // Accept swap\n            assign[e1] = d2;\n            assign[e2] = d1;\n            day_edges[d1][idx1] = e2;\n            day_edges[d2][idx2] = e1;\n            day_load[d1] = new_load1;\n            day_load[d2] = new_load2;\n        }\n    }\n    \n    // Optional: Try some refinement using actual distance calculations if time permits\n    // For now, output the result\n    \n    // Verify constraints\n    vector<int> count(D, 0);\n    for (int i = 0; i < M; i++) {\n        count[assign[i]]++;\n    }\n    for (int d = 0; d < D; d++) {\n        if (count[d] > K) {\n            // Fix by moving excess to other days (should not happen with swap)\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << assign[i] + 1; // convert to 1-indexed\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<vector<string>> f(2, vector<string>(D));\nvector<vector<string>> r(2, vector<string>(D));\n\n// 24 rotation matrices (3x3)\nvector<array<array<int,3>,3>> rotations;\n\nvoid init_rotations() {\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int parity[6] = {1, -1, -1, 1, 1, -1}; // determinant sign of permutation matrix\n    \n    for (int p=0; p<6; p++) {\n        for (int sx : {1, -1}) {\n            for (int sy : {1, -1}) {\n                for (int sz : {1, -1}) {\n                    if (sx * sy * sz * parity[p] == 1) {\n                        array<array<int,3>,3> mat = {};\n                        mat[0][perms[p][0]] = sx;\n                        mat[1][perms[p][1]] = sy;\n                        mat[2][perms[p][2]] = sz;\n                        rotations.push_back(mat);\n                    }\n                }\n            }\n        }\n    }\n    assert(rotations.size() == 24);\n}\n\nvector<array<int,3>> normalize_shape(vector<array<int,3>> cells) {\n    if (cells.empty()) return cells;\n    \n    // Translate to origin\n    int minx = 1e9, miny = 1e9, minz = 1e9;\n    for (auto& c : cells) {\n        minx = min(minx, c[0]);\n        miny = min(miny, c[1]);\n        minz = min(minz, c[2]);\n    }\n    for (auto& c : cells) {\n        c[0] -= minx;\n        c[1] -= miny;\n        c[2] -= minz;\n    }\n    \n    vector<vector<array<int,3>>> candidates;\n    for (auto& rot : rotations) {\n        vector<array<int,3>> cur;\n        for (auto& c : cells) {\n            int x = c[0], y = c[1], z = c[2];\n            int nx = rot[0][0]*x + rot[0][1]*y + rot[0][2]*z;\n            int ny = rot[1][0]*x + rot[1][1]*y + rot[1][2]*z;\n            int nz = rot[2][0]*x + rot[2][1]*y + rot[2][2]*z;\n            cur.push_back({nx, ny, nz});\n        }\n        // Translate to origin again\n        int mix = 1e9, miy = 1e9, miz = 1e9;\n        for (auto& c : cur) {\n            mix = min(mix, c[0]);\n            miy = min(miy, c[1]);\n            miz = min(miz, c[2]);\n        }\n        for (auto& c : cur) {\n            c[0] -= mix;\n            c[1] -= miy;\n            c[2] -= miz;\n        }\n        sort(cur.begin(), cur.end());\n        candidates.push_back(cur);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\nstruct Component {\n    vector<array<int,3>> cells;\n    vector<array<int,3>> shape; // canonical form\n};\n\nvector<Component> extract_components(const vector<vector<vector<bool>>>& valid) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<Component> comps;\n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid[x][y][z] && !vis[x][y][z]) {\n                    Component comp;\n                    queue<array<int,3>> q;\n                    q.push({x,y,z});\n                    vis[x][y][z] = true;\n                    while (!q.empty()) {\n                        auto cur = q.front(); q.pop();\n                        comp.cells.push_back(cur);\n                        int cx=cur[0], cy=cur[1], cz=cur[2];\n                        for (int dir=0; dir<6; dir++) {\n                            int nx=cx+dx[dir], ny=cy+dy[dir], nz=cz+dz[dir];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && valid[nx][ny][nz] && !vis[nx][ny][nz]) {\n                                vis[nx][ny][nz] = true;\n                                q.push({nx,ny,nz});\n                            }\n                        }\n                    }\n                    comps.push_back(comp);\n                }\n            }\n        }\n    }\n    return comps;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotations();\n    \n    cin >> D;\n    for (int i=0; i<2; i++) {\n        f[i].resize(D);\n        r[i].resize(D);\n        for (int j=0; j<D; j++) cin >> f[i][j];\n        for (int j=0; j<D; j++) cin >> r[i][j];\n    }\n    \n    // Compute valid cells for each object\n    vector<vector<vector<bool>>> valid1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> valid2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1') valid1[x][y][z] = true;\n                if (f[1][z][x] == '1' && r[1][z][y] == '1') valid2[x][y][z] = true;\n            }\n        }\n    }\n    \n    // Compute intersection C = P1 \u2229 P2\n    vector<vector<vector<bool>>> validC(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid1[x][y][z] && valid2[x][y][z]) validC[x][y][z] = true;\n            }\n        }\n    }\n    \n    // R1 = P1 \\ C, R2 = P2 \\ C\n    vector<vector<vector<bool>>> validR1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> validR2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid1[x][y][z] && !validC[x][y][z]) validR1[x][y][z] = true;\n                if (valid2[x][y][z] && !validC[x][y][z]) validR2[x][y][z] = true;\n            }\n        }\n    }\n    \n    auto compsC = extract_components(validC);\n    auto compsR1 = extract_components(validR1);\n    auto compsR2 = extract_components(validR2);\n    \n    int n = 0;\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    \n    auto idx = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n    \n    // Assign IDs to C components (shared)\n    for (auto& comp : compsC) {\n        n++;\n        for (auto& c : comp.cells) {\n            b1[idx(c[0], c[1], c[2])] = n;\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    // Process R1 and R2 with matching\n    // Build map from shape to list of R1 components\n    map<vector<array<int,3>>, vector<Component*>> shape_map;\n    for (auto& comp : compsR1) {\n        comp.shape = normalize_shape(comp.cells);\n        shape_map[comp.shape].push_back(&comp);\n    }\n    \n    // Match with R2\n    vector<Component*> unmatched_R2;\n    for (auto& comp : compsR2) {\n        auto shape = normalize_shape(comp.cells);\n        if (shape_map.count(shape) && !shape_map[shape].empty()) {\n            // Found match\n            Component* c1 = shape_map[shape].back();\n            shape_map[shape].pop_back();\n            n++;\n            for (auto& c : c1->cells) {\n                b1[idx(c[0], c[1], c[2])] = n;\n            }\n            for (auto& c : comp.cells) {\n                b2[idx(c[0], c[1], c[2])] = n;\n            }\n        } else {\n            unmatched_R2.push_back(&comp);\n        }\n    }\n    \n    // Output remaining R1 components (unmatched)\n    for (auto& [shape, vec] : shape_map) {\n        for (auto* comp : vec) {\n            n++;\n            for (auto& c : comp->cells) {\n                b1[idx(c[0], c[1], c[2])] = n;\n            }\n        }\n    }\n    \n    // Output remaining R2 components (unmatched)\n    for (auto* comp : unmatched_R2) {\n        n++;\n        for (auto& c : comp->cells) {\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    cout << n << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b2[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {int x, y;};\nstruct Edge{int u, v; int w;};\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    void unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a!=b) p[a]=b;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<Point> V(N);\n    for(int i=0;i<N;i++) cin>>V[i].x>>V[i].y;\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++) {\n        int u,v,w;\n        cin>>u>>v>>w;\n        u--; v--;\n        edges[i] = {u,v,w};\n        adj[u].push_back({v,i});\n        adj[v].push_back({u,i});\n    }\n    vector<Point> R(K);\n    for(int i=0;i<K;i++) cin>>R[i].x>>R[i].y;\n    \n    const int COVER_DIST2 = 5000*5000;\n    const long long INF = (1LL<<60);\n    \n    // Precompute shortest paths between vertices (Dijkstra from each)\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    vector<vector<int>> parent_edge(N, vector<int>(N, -1)); // edge id to parent in Dijkstra tree from s\n    \n    for(int s=0; s<N; s++) {\n        distV[s][s] = 0;\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u] = pq.top(); pq.pop();\n            if(d!=distV[s][u]) continue;\n            for(auto [v,eid]: adj[u]){\n                long long nd = d + edges[eid].w;\n                if(nd < distV[s][v]){\n                    distV[s][v] = nd;\n                    parent_edge[s][v] = eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // Precompute resident-vertex distances and required P\n    vector<vector<int>> resVdist2(K, vector<int>(N));\n    vector<vector<int>> needP(K, vector<int>(N));\n    for(int i=0;i<K;i++){\n        for(int j=0;j<N;j++){\n            long long dx = (long long)R[i].x - V[j].x;\n            long long dy = (long long)R[i].y - V[j].y;\n            int d2 = (int)(dx*dx + dy*dy);\n            resVdist2[i][j] = d2;\n            needP[i][j] = (int)ceil(sqrt((double)d2) - 1e-9);\n        }\n    }\n    \n    // Evaluation function: returns {cost, feasible}\n    auto evaluate = [&](const vector<int>& S)->pair<long long,bool>{\n        int sz = (int)S.size();\n        if(sz==0) return {INF,false};\n        vector<int> maxP(N,0);\n        // Assign each resident to closest vertex in S\n        for(int r=0;r<K;r++){\n            int bestv = -1;\n            int bestd2 = COVER_DIST2+1;\n            for(int v: S){\n                if(resVdist2[r][v] < bestd2){\n                    bestd2 = resVdist2[r][v];\n                    bestv = v;\n                }\n            }\n            if(bestv==-1 || bestd2 > COVER_DIST2) return {INF,false};\n            int p = needP[r][bestv];\n            if(p>5000) return {INF,false};\n            maxP[bestv] = max(maxP[bestv], p);\n        }\n        long long fac_cost = 0;\n        for(int v: S) fac_cost += 1LL*maxP[v]*maxP[v];\n        \n        // Tree cost: MST on S using metric distV\n        long long tree_cost = 0;\n        if(sz>1){\n            vector<bool> used(sz,false);\n            used[0] = true;\n            for(int iter=1; iter<sz; iter++){\n                long long best = INF;\n                int bestj = -1;\n                for(int i=0;i<sz;i++) if(used[i]){\n                    for(int j=0;j<sz;j++) if(!used[j]){\n                        long long d = distV[S[i]][S[j]];\n                        if(d < best){\n                            best = d;\n                            bestj = j;\n                        }\n                    }\n                }\n                if(bestj==-1) return {INF,false};\n                tree_cost += best;\n                used[bestj] = true;\n            }\n        }\n        return {tree_cost + fac_cost, true};\n    };\n    \n    // Initial greedy solution (set cover with connection heuristic)\n    vector<int> S;\n    vector<bool> inS(N,false);\n    S.push_back(0);\n    inS[0] = true;\n    vector<bool> covered(K,false);\n    \n    // Precompute which residents each vertex can cover\n    vector<vector<int>> cov Residents(N);\n    for(int v=0;v<N;v++){\n        for(int r=0;r<K;r++){\n            if(resVdist2[r][v] <= COVER_DIST2) covResidents[v].push_back(r);\n        }\n    }\n    \n    while(true){\n        bool all = true;\n        for(bool c: covered) if(!c){all=false; break;}\n        if(all) break;\n        \n        int bestv = -1;\n        double best_score = -1.0;\n        long long best_conn = INF;\n        \n        for(int v=0; v<N; v++) if(!inS[v]){\n            // Newly covered residents\n            int newly = 0;\n            int max_need = 0;\n            for(int r: covResidents[v]){\n                if(!covered[r]){\n                    newly++;\n                    max_need = max(max_need, needP[r][v]);\n                }\n            }\n            if(newly==0) continue;\n            // Connection cost to current S\n            long long conn = INF;\n            for(int u: S) conn = min(conn, distV[u][v]);\n            long long total_cost = conn + 1LL*max_need*max_need;\n            double score = (double)newly / (double)total_cost;\n            if(score > best_score){\n                best_score = score;\n                bestv = v;\n                best_conn = conn;\n            }\n        }\n        \n        if(bestv==-1) break; // Should not happen due to problem guarantee\n        \n        inS[bestv] = true;\n        S.push_back(bestv);\n        for(int r: covResidents[bestv]){\n            covered[r] = true;\n        }\n    }\n    \n    // Ensure all covered (safety)\n    for(int r=0;r<K;r++){\n        bool ok=false;\n        for(int v: S) if(resVdist2[r][v]<=COVER_DIST2){ok=true; break;}\n        if(!ok){\n            // Add best vertex for this resident\n            int bestv=-1, bestd2=COVER_DIST2+1;\n            for(int v=0;v<N;v++) if(!inS[v] && resVdist2[r][v]<bestd2){\n                bestd2=resVdist2[r][v]; bestv=v;\n            }\n            if(bestv!=-1){\n                inS[bestv]=true;\n                S.push_back(bestv);\n            }\n        }\n    }\n    \n    // Local search (hill climbing)\n    bool improved = true;\n    auto [cur_cost, _] = evaluate(S);\n    \n    for(int iter=0; iter<200 && improved; iter++){\n        improved = false;\n        // Try remove\n        for(size_t i=0;i<S.size();i++){\n            if(S[i]==0) continue; // cannot remove root\n            vector<int> S2 = S;\n            S2.erase(S2.begin()+i);\n            auto [c2,f2] = evaluate(S2);\n            if(f2 && c2 < cur_cost){\n                inS[S[i]] = false;\n                S = S2;\n                cur_cost = c2;\n                improved = true;\n                break;\n            }\n        }\n        if(improved) continue;\n        // Try add\n        for(int v=0;v<N;v++) if(!inS[v]){\n            vector<int> S2 = S;\n            S2.push_back(v);\n            auto [c2,f2] = evaluate(S2);\n            if(f2 && c2 < cur_cost){\n                inS[v] = true;\n                S = S2;\n                cur_cost = c2;\n                improved = true;\n                break;\n            }\n        }\n    }\n    \n    // Build final output\n    int sz = S.size();\n    vector<int> P(N,0);\n    // Assign residents to compute P\n    for(int r=0;r<K;r++){\n        int bestv=-1, bestd2=COVER_DIST2+1;\n        for(int v: S){\n            if(resVdist2[r][v] < bestd2){\n                bestd2 = resVdist2[r][v];\n                bestv = v;\n            }\n        }\n        if(bestv!=-1){\n            P[bestv] = max(P[bestv], needP[r][bestv]);\n        }\n    }\n    \n    // Build tree edges via MST on metric closure\n    vector<int> B(M,0);\n    if(sz>1){\n        // Prim on S to get metric MST edges\n        vector<long long> min_edge(sz, INF);\n        vector<bool> used(sz,false);\n        vector<int> parent_metric(sz,-1);\n        min_edge[0]=0;\n        for(int iter=0; iter<sz; iter++){\n            int v=-1;\n            for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_edge[i]<min_edge[v])) v=i;\n            used[v]=true;\n            for(int i=0;i<sz;i++) if(!used[i]){\n                long long d = distV[S[v]][S[i]];\n                if(d < min_edge[i]){\n                    min_edge[i]=d;\n                    parent_metric[i]=v;\n                }\n            }\n        }\n        \n        // Collect edges from paths\n        vector<bool> edge_active(M,false);\n        for(int i=1;i<sz;i++){\n            int u = S[parent_metric[i]];\n            int v = S[i];\n            // Trace back from v to u in Dijkstra tree of u\n            int cur = v;\n            while(cur != u){\n                int e = parent_edge[u][cur];\n                if(e==-1) break; // should not happen\n                edge_active[e] = true;\n                int pu = edges[e].u == cur ? edges[e].v : edges[e].u;\n                cur = pu;\n            }\n        }\n        \n        // MST on the active edges to get tree\n        vector<int> active_list;\n        for(int i=0;i<M;i++) if(edge_active[i]) active_list.push_back(i);\n        sort(active_list.begin(), active_list.end(), [&](int a, int b){return edges[a].w < edges[b].w;});\n        \n        DSU dsu(N);\n        for(int e: active_list){\n            int u=edges[e].u, v=edges[e].v;\n            if(dsu.find(u)!=dsu.find(v)){\n                dsu.unite(u,v);\n                B[e]=1;\n            }\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int i=0;i<M;i++){\n        if(i) cout << ' ';\n        cout << B[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    const int BALLS = N * (N + 1) / 2; // 465\n    \n    // grid[x][y] = current value at (x,y)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // pos[v] = current coordinates of value v\n    vector<pair<int,int>> pos(BALLS);\n    \n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v; \n            if(!(cin >> v)) return 0;\n            grid[x][y] = v;\n            pos[v] = {x, y};\n        }\n    }\n    \n    vector<array<int,4>> ops;\n    vector<vector<bool>> fixed(N, vector<bool>(N, false));\n    \n    // Process from bottom-right to top-left\n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = x; y >= 0; --y) {\n            int target_val = x * (x + 1) / 2 + y;\n            auto [cx, cy] = pos[target_val];\n            \n            // Route the ball to (x,y) through the unfixed region\n            while (cx != x || cy != y) {\n                int nx, ny;\n                if (cx < x) {\n                    if (cy > y) {\n                        // Need to decrease y first (move left)\n                        nx = cx;\n                        ny = cy - 1;\n                    } else if (cy < y) {\n                        // Can go down-right\n                        nx = cx + 1;\n                        ny = cy + 1;\n                    } else { // cy == y\n                        // Go down-left\n                        nx = cx + 1;\n                        ny = cy;\n                    }\n                } else if (cx > x) {\n                    // This case should not appear with the processing order,\n                    // but we keep it for safety.\n                    if (cy > y) {\n                        nx = cx - 1;\n                        ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx - 1;\n                        ny = cy;\n                    } else {\n                        nx = cx - 1;\n                        ny = cy;\n                    }\n                } else { // cx == x\n                    if (cy < y) {\n                        // Move right along the row\n                        nx = cx;\n                        ny = cy + 1;\n                    } else {\n                        // cy > y, should not happen\n                        nx = cx;\n                        ny = cy - 1;\n                    }\n                }\n                \n                // Perform the swap\n                int v1 = grid[cx][cy];\n                int v2 = grid[nx][ny];\n                \n                swap(grid[cx][cy], grid[nx][ny]);\n                pos[v1] = {nx, ny};\n                pos[v2] = {cx, cy};\n                \n                ops.push_back({cx, cy, nx, ny});\n                \n                cx = nx;\n                cy = ny;\n            }\n            \n            fixed[x][y] = true;\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op[0] << ' ' << op[1] << ' ' << op[2] << ' ' << op[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D;\n    int N;\n    if (!(cin >> D >> N)) return 0;\n    \n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    \n    const int si = 0;\n    const int sj = (D - 1) / 2;\n    const int M = D * D - 1 - N;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // BFS to compute distances from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (dist[ni][nj] != -1) continue;\n            dist[ni][nj] = dist[i][j] + 1;\n            q.push({ni, nj});\n        }\n    }\n    \n    // Collect valid cells (non-entrance, non-obstacle)\n    vector<pair<int, int>> cells;\n    cells.reserve(M);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == si && j == sj) continue;\n            if (obstacle[i][j]) continue;\n            cells.push_back({i, j});\n        }\n    }\n    \n    // Sort by distance descending (farther cells first)\n    sort(cells.begin(), cells.end(), [&](const pair<int, int> &a, const pair<int, int> &b) {\n        return dist[a.first][a.second] > dist[b.first][b.second];\n    });\n    \n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    vector<vector<int>> value_at(D, vector<int>(D, -1));\n    \n    // Helper to check if a cell is on the frontier (adjacent to entrance or occupied)\n    auto is_frontier = [&](int i, int j) -> bool {\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni == si && nj == sj) return true;\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && occupied[ni][nj]) return true;\n        }\n        return false;\n    };\n    \n    // Helper to compute reachability from entrance through empty cells\n    auto compute_reachable = [&]() -> vector<vector<bool>> {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        vis[si][sj] = true;\n        qq.push({si, sj});\n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (vis[ni][nj]) continue;\n                vis[ni][nj] = true;\n                qq.push({ni, nj});\n            }\n        }\n        return vis;\n    };\n    \n    // Online placement phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        \n        // Target index in the sorted cells array\n        // Small t should be placed near the end (close to entrance)\n        // Large t should be placed near the beginning (far from entrance)\n        int target_idx = M - 1 - t;\n        \n        auto reachable = compute_reachable();\n        pair<int, int> chosen = {-1, -1};\n        int best_delta = M + 1;\n        \n        // Find reachable frontier cell with index closest to target_idx\n        for (int idx = 0; idx < M; idx++) {\n            auto [i, j] = cells[idx];\n            if (occupied[i][j]) continue;\n            if (!reachable[i][j]) continue;\n            if (!is_frontier(i, j)) continue;\n            \n            int delta = abs(idx - target_idx);\n            if (delta < best_delta) {\n                best_delta = delta;\n                chosen = {i, j};\n            }\n        }\n        \n        // Fallback: should not happen if logic is correct, but take any reachable\n        if (chosen.first == -1) {\n            for (int idx = 0; idx < M; idx++) {\n                auto [i, j] = cells[idx];\n                if (occupied[i][j]) continue;\n                if (!reachable[i][j]) continue;\n                chosen = {i, j};\n                break;\n            }\n        }\n        \n        occupied[chosen.first][chosen.second] = true;\n        value_at[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << \"\\n\";\n    }\n    \n    // Retrieval phase: greedy using priority queue (always take smallest available value)\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[si][sj] = true;\n    \n    using State = pair<int, pair<int, int>>; // (value, position)\n    priority_queue<State, vector<State>, greater<State>> pq;\n    \n    // Initialize with cells adjacent to entrance\n    for (int k = 0; k < 4; k++) {\n        int ni = si + di[k], nj = sj + dj[k];\n        if (ni >= 0 && ni < D && nj >= 0 && nj < D && value_at[ni][nj] != -1) {\n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    }\n    \n    vector<pair<int, int>> retrieval_order;\n    retrieval_order.reserve(M);\n    vector<vector<bool>> retrieved(D, vector<bool>(D, false));\n    \n    while (!pq.empty()) {\n        auto [val, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        \n        if (retrieved[i][j]) continue; // Skip if already processed\n        \n        retrieved[i][j] = true;\n        is_empty[i][j] = true;\n        retrieval_order.push_back(pos);\n        \n        // Add neighbors that now become accessible\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (is_empty[ni][nj]) continue;      // Already empty\n            if (retrieved[ni][nj]) continue;     // Already retrieved\n            if (value_at[ni][nj] == -1) continue; // No container there\n            \n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    }\n    \n    // Output retrieval order\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc024":"","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    vector<double> score(N, 1.0);  // Estimated weight for each item\n    vector<int> belong(N, 0);      // Current group assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    auto do_query = [&](const vector<int>& L, const vector<int>& R) -> char {\n        cout << L.size() << \" \" << R.size();\n        for (int x : L) cout << \" \" << x;\n        for (int x : R) cout << \" \" << x;\n        cout << endl;\n        char res;\n        cin >> res;\n        return res;\n    };\n    \n    // Determine query budget for each phase\n    // Phase 1: Estimate weights via pairwise comparisons\n    // Phase 3: Refine partition by comparing groups and swapping\n    int refine_budget = 0;\n    if (Q > 150) {\n        refine_budget = min(Q / 3, 600);  // Reserve up to 1/3 or 600 for refinement\n    }\n    int phase1_budget = Q - refine_budget;\n    \n    // Phase 1: Pairwise comparisons to estimate relative weights\n    // First, ensure every item is compared at least once (connectivity)\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; i++) {\n        pairs.emplace_back(i, (i + 1) % N);\n    }\n    // Add random pairs for remaining budget\n    while ((int)pairs.size() < phase1_budget) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a != b) {\n            if (a > b) swap(a, b);\n            pairs.emplace_back(a, b);\n        }\n    }\n    shuffle(pairs.begin(), pairs.end(), rng);\n    \n    for (int q = 0; q < phase1_budget && q < (int)pairs.size(); q++) {\n        auto [a, b] = pairs[q];\n        char res = do_query({a}, {b});\n        const double delta = 1.0;\n        if (res == '>') {\n            score[a] += delta;\n            score[b] -= delta;\n        } else if (res == '<') {\n            score[a] -= delta;\n            score[b] += delta;\n        }\n    }\n    \n    // Normalize scores to positive values\n    double min_score = *min_element(score.begin(), score.end());\n    for (double& s : score) {\n        s = s - min_score + 1.0;\n    }\n    \n    // Phase 2: Initial partition using LPT (Longest Processing Time) rule\n    // Sort items by estimated weight descending\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    vector<double> group_sum(D, 0.0);\n    for (int idx : items) {\n        // Assign to the currently lightest group\n        int best_g = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_g]) best_g = g;\n        }\n        belong[idx] = best_g;\n        group_sum[best_g] += score[idx];\n    }\n    \n    // Phase 3: Refinement using remaining queries\n    // Compare heavy vs light groups and swap items to balance\n    for (int q = phase1_budget; q < Q; q++) {\n        // Find currently heaviest and lightest groups by estimate\n        int heavy_g = max_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        int light_g = min_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        \n        if (heavy_g == light_g) break;  // Already balanced\n        \n        // Collect items in these groups\n        vector<int> heavy_items, light_items;\n        for (int i = 0; i < N; i++) {\n            if (belong[i] == heavy_g) heavy_items.push_back(i);\n            else if (belong[i] == light_g) light_items.push_back(i);\n        }\n        \n        if (heavy_items.empty() || light_items.empty()) continue;\n        \n        // Pick candidate items: heaviest in heavy group, lightest in light group\n        int h_item = *max_element(heavy_items.begin(), heavy_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        int l_item = *min_element(light_items.begin(), light_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        \n        // Compare the two groups to check actual imbalance direction\n        char res = do_query(heavy_items, light_items);\n        \n        // Also update individual scores based on group comparison (small adjustment)\n        const double eps = 0.1;\n        if (res == '>') {\n            // Heavy group is indeed heavier\n            for (int x : heavy_items) score[x] += eps;\n            for (int x : light_items) score[x] -= eps;\n            \n            // Swap heaviest from heavy with lightest from light\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else if (res == '<') {\n            // Opposite of estimate: light group is actually heavier\n            for (int x : heavy_items) score[x] -= eps;\n            for (int x : light_items) score[x] += eps;\n            \n            // Swap in opposite direction (move \"light\" from heavy to light, \"heavy\" from light to heavy)\n            // Actually, swap the candidates we picked (which might be wrong, but let's swap anyway to fix)\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else {\n            // Equal, do a random beneficial swap or nothing\n            // Swap to explore\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        }\n    }\n    \n    // Output final partition\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << belong[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> st(m);\n    vector<int> pos(n + 1); // pos[v] = which stack (0-indexed) contains v\n    \n    for (int i = 0; i < m; ++i) {\n        int h = n / m;\n        for (int j = 0; j < h; ++j) {\n            int x; \n            cin >> x;\n            st[i].push_back(x);\n            pos[x] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops; // (v, i). i=0 for removal, else 1-indexed destination stack\n    \n    for (int target = 1; target <= n; ++target) {\n        int s = pos[target];\n        \n        // Find position of target in its stack\n        int idx = -1;\n        for (int i = 0; i < (int)st[s].size(); ++i) {\n            if (st[s][i] == target) {\n                idx = i;\n                break;\n            }\n        }\n        \n        // Move boxes above target until it becomes the top\n        while (idx < (int)st[s].size() - 1) {\n            int w = st[s].back(); // current top, will become top of moved segment\n            \n            int best_d = -1;\n            int min_valid_top = INT_MAX;\n            int max_top = -1;\n            \n            for (int d = 0; d < m; ++d) {\n                if (d == s) continue;\n                if (st[d].empty()) {\n                    best_d = d;          // empty is ideal\n                    break;\n                }\n                int top_d = st[d].back();\n                if (top_d > w) {         // valid: won't block existing top\n                    if (top_d < min_valid_top) {\n                        min_valid_top = top_d;\n                        best_d = d;\n                    }\n                }\n                if (top_d > max_top) {\n                    max_top = top_d;\n                }\n            }\n            \n            if (best_d == -1) {          // no empty and no valid top>w\n                for (int d = 0; d < m; ++d) {\n                    if (d == s) continue;\n                    if (st[d].back() == max_top) {\n                        best_d = d;\n                        break;\n                    }\n                }\n            }\n            \n            // The box immediately above target\n            int u = st[s][idx + 1];\n            \n            // Perform move: take suffix starting at idx+1\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            st[s].resize(idx + 1);\n            \n            for (int x : seg) pos[x] = best_d;\n            st[best_d].insert(st[best_d].end(), seg.begin(), seg.end());\n            \n            ops.emplace_back(u, best_d + 1); // convert to 1-indexed for output\n            // After this, target is at top of stack s (loop will exit)\n        }\n        \n        // Remove target (Operation 2)\n        st[s].pop_back();\n        ops.emplace_back(target, 0);\n    }\n    \n    for (auto [v, i] : ops) {\n        cout << v << ' ' << i << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n    \n    auto id = [&](int i, int j){ return i*N + j; };\n    int V = N*N;\n    vector<vector<pair<int,char>>> adj(V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n    const int rev[4] = {1,0,3,2};\n    \n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                bool ok = false;\n                if (dir == 0) { // up\n                    ok = h[ni][j] == '0'; // h[ni][j] is wall between (ni,j) and (ni+1,j)=(i,j)\n                } else if (dir == 1) { // down\n                    ok = h[i][j] == '0';\n                } else if (dir == 2) { // left\n                    ok = v[i][nj] == '0';\n                } else { // right\n                    ok = v[i][j] == '0';\n                }\n                if (ok) {\n                    adj[id(i,j)].push_back({id(ni,nj), dc[dir]});\n                }\n            }\n        }\n    }\n    \n    // Build BFS tree from root (0,0)\n    int root = 0;\n    vector<int> parent(V, -1);\n    vector<vector<int>> children(V);\n    vector<char> move_to_parent(V, 0);\n    {\n        queue<int> q;\n        q.push(root);\n        parent[root] = -2;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, c] : adj[u]) {\n                if (parent[v] == -1) {\n                    parent[v] = u;\n                    move_to_parent[v] = dc[rev[strchr(dc, c) - dc]];\n                    children[u].push_back(v);\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    vector<double> dval(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            dval[id(i,j)] = sqrt((double)d[i][j]);\n    \n    // Binary search for multiplier c\n    double lo = 0, hi = 1e6;\n    vector<int> k(V, 1);\n    for (int iter = 0; iter < 60; ++iter) {\n        double mid = (lo + hi) * 0.5;\n        long long L = 0;\n        for (int v = 0; v < V; ++v) {\n            if (v == root) continue;\n            long long kv = (long long)(mid * dval[v]);\n            if (kv < 1) kv = 1;\n            L += 2 * kv;\n            if (L > 100000) break;\n        }\n        if (L <= 100000) lo = mid;\n        else hi = mid;\n    }\n    double c = lo;\n    long long total_L = 0;\n    for (int v = 0; v < V; ++v) {\n        if (v == root) continue;\n        long long kv = (long long)(c * dval[v]);\n        if (kv < 1) kv = 1;\n        k[v] = (int)kv;\n        total_L += 2 * kv;\n    }\n    // Compute k for root = sum of children k\n    long long sum_child_root = 0;\n    for (int v : children[root]) sum_child_root += k[v];\n    k[root] = (int)sum_child_root;\n    total_L = 2 * (total_L / 2); // not needed but keep consistency\n    \n    // Build schedules: schedule[u][slot] = list of children to visit in that slot\n    vector<vector<vector<int>>> schedule(V);\n    for (int u = 0; u < V; ++u) {\n        if (children[u].empty()) {\n            schedule[u].resize(k[u]); // empty slots\n            continue;\n        }\n        // Collect all excursions: k[v] copies of child v\n        vector<int> excursions;\n        excursions.reserve(10000);\n        for (int v : children[u]) {\n            for (int i = 0; i < k[v]; ++i) excursions.push_back(v);\n        }\n        schedule[u].resize(k[u]);\n        // Distribute round-robin into k[u] slots\n        for (size_t i = 0; i < excursions.size(); ++i) {\n            int slot = i % k[u];\n            schedule[u][slot].push_back(excursions[i]);\n        }\n    }\n    \n    string ans;\n    ans.reserve(100000);\n    vector<int> cur_slot(V, 0);\n    \n    // Directions: need to map (u,v) to char\n    auto get_char = [&](int u, int v)->char {\n        for (auto [to, c] : adj[u]) if (to == v) return c;\n        return '?';\n    };\n    \n    function<void(int)> visit = [&](int u) {\n        // We are at node u, this is the cur_slot[u]-th visit\n        int slot = cur_slot[u]++;\n        for (int v : schedule[u][slot]) {\n            ans.push_back(get_char(u, v));\n            visit(v);\n            ans.push_back(get_char(v, u));\n        }\n    };\n    \n    // Start from root: execute all its slots\n    for (int slot = 0; slot < k[root]; ++slot) {\n        for (int v : schedule[root][slot]) {\n            ans.push_back(get_char(root, v));\n            visit(v);\n            ans.push_back(get_char(v, root));\n        }\n    }\n    \n    // Verify\n    if ((int)ans.size() > 100000) {\n        // Should not happen, but truncate if it does (will be WA, but avoid crash)\n        ans.resize(100000);\n    }\n    cout << ans << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint calc_overlap(const string& a, const string& b) {\n    // If b is already a substring of a, we don't need to add anything\n    if (a.find(b) != string::npos) return (int)b.length();\n    // Find maximum k such that suffix of a matches prefix of b\n    int max_k = min((int)a.length(), (int)b.length());\n    for (int k = max_k; k > 0; --k) {\n        if (a.compare(a.length() - k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    int si, sj;\n    cin >> N >> M >> si >> sj;\n    \n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n    }\n    \n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n    \n    // Build superstring using greedy SCS (Shortest Common Superstring)\n    vector<string> pool = targets;\n    while (pool.size() > 1) {\n        int n = pool.size();\n        int best_ov = -1;\n        int best_i = -1, best_j = -1;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(pool[i], pool[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        \n        // Merge pool[best_i] and pool[best_j]\n        string merged = pool[best_i] + pool[best_j].substr(best_ov);\n        \n        // Remove best_j and best_i (remove higher index first to keep indices valid)\n        if (best_i > best_j) swap(best_i, best_j);\n        pool.erase(pool.begin() + best_j);\n        pool.erase(pool.begin() + best_i);\n        pool.push_back(merged);\n    }\n    \n    const string& U = pool[0];\n    const int L = U.size();\n    \n    // Precompute positions for each character\n    vector<vector<int>> pos(26); // store cell indices (i*N + j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int c = grid[i][j] - 'A';\n            pos[c].push_back(i * N + j);\n        }\n    }\n    \n    // Precompute Manhattan distances between all cells\n    const int V = N * N;\n    vector<vector<int>> dist(V, vector<int>(V));\n    for (int i = 0; i < V; ++i) {\n        int i1 = i / N, j1 = i % N;\n        for (int j = 0; j < V; ++j) {\n            int i2 = j / N, j2 = j % N;\n            dist[i][j] = abs(i1 - i2) + abs(j1 - j2);\n        }\n    }\n    \n    const int INF = 1e9;\n    // dp_curr[v] = min cost to reach cell v at current step\n    vector<int> dp_prev(V, INF), dp_curr(V, INF);\n    // parent[step][v] = previous cell index that achieved dp_curr[v]\n    vector<vector<int>> parent(L, vector<int>(V, -1));\n    \n    // Initialize for first character\n    int first_c = U[0] - 'A';\n    for (int v : pos[first_c]) {\n        int vi = v / N, vj = v % N;\n        dp_curr[v] = dist[si * N + sj][v] + 1;\n    }\n    \n    // DP for subsequent characters\n    for (int step = 1; step < L; ++step) {\n        dp_prev = dp_curr;\n        fill(dp_curr.begin(), dp_curr.end(), INF);\n        \n        int curr_c = U[step] - 'A';\n        int prev_c = U[step - 1] - 'A';\n        \n        for (int v : pos[curr_c]) {\n            int best = INF;\n            int best_u = -1;\n            for (int u : pos[prev_c]) {\n                if (dp_prev[u] == INF) continue;\n                int cost = dp_prev[u] + dist[u][v] + 1;\n                if (cost < best) {\n                    best = cost;\n                    best_u = u;\n                }\n            }\n            if (best < INF) {\n                dp_curr[v] = best;\n                parent[step][v] = best_u;\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_v = -1;\n    int best_cost = INF;\n    for (int v = 0; v < V; ++v) {\n        if (dp_curr[v] < best_cost) {\n            best_cost = dp_curr[v];\n            best_v = v;\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int, int>> path;\n    int cur = best_v;\n    for (int step = L - 1; step >= 0; --step) {\n        int i = cur / N;\n        int j = cur % N;\n        path.push_back({i, j});\n        if (step > 0) {\n            cur = parent[step][cur];\n        }\n    }\n    reverse(path.begin(), path.end());\n    \n    // Output\n    for (auto [i, j] : path) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ------------------------------------------------------------\n// Problem parameters\nint N, M;\ndouble eps;\nconst int MAX_N2 = 400; // 20*20\n\nstruct Placement {\n    bitset<MAX_N2> cells;\n    int area; // popcount\n};\n\nvector<vector<Placement>> placements; // [field][placement_idx]\nvector<int> num_placements; // [field]\n\n// ------------------------------------------------------------\n// Particle\nstruct Particle {\n    vector<int> pos; // size M, index of placement for each field\n    double weight;\n    Particle(int M_) : pos(M_), weight(1.0) {}\n};\n\nvector<Particle> particles;\nconst int NUM_PARTICLES = 2000;\n\n// ------------------------------------------------------------\n// Utilities\nint flat(int i, int j) { return i * N + j; }\n\n// ------------------------------------------------------------\n// Random generator\nmt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\ndouble rand_double() {\n    return uniform_real_distribution<double>(0.0, 1.0)(rng);\n}\n\n// ------------------------------------------------------------\n// Enumerate all valid placements for each field\nvoid enumerate_placements(const vector<vector<pair<int,int>>>& shapes) {\n    placements.resize(M);\n    num_placements.resize(M);\n    for (int k = 0; k < M; ++k) {\n        const auto& shape = shapes[k];\n        int h = 0, w = 0;\n        for (auto [i, j] : shape) {\n            h = max(h, i);\n            w = max(w, j);\n        }\n        // translations\n        for (int di = 0; di + h < N; ++di) {\n            for (int dj = 0; dj + w < N; ++dj) {\n                Placement p;\n                p.area = (int)shape.size();\n                for (auto [i, j] : shape) {\n                    int ni = di + i;\n                    int nj = dj + j;\n                    p.cells.set(flat(ni, nj));\n                }\n                placements[k].push_back(p);\n            }\n        }\n        num_placements[k] = (int)placements[k].size();\n        if (num_placements[k] == 0) {\n            // should not happen with valid input\n        }\n    }\n}\n\n// ------------------------------------------------------------\n// Initialize particles uniformly at random\nvoid init_particles(const vector<int>& forced_val = {}) {\n    particles.clear();\n    particles.reserve(NUM_PARTICLES);\n    for (int i = 0; i < NUM_PARTICLES; ++i) {\n        Particle p(M);\n        for (int k = 0; k < M; ++k) {\n            p.pos[k] = rand_int(0, num_placements[k] - 1);\n        }\n        p.weight = 1.0;\n        particles.push_back(p);\n    }\n}\n\n// ------------------------------------------------------------\n// Compute cell probabilities from particles\n// Returns vector<double> prob (size N*N), and also fills drilled constraints\nvector<double> compute_cell_probs(const vector<int>& drilled_val) {\n    vector<double> prob(N*N, 0.0);\n    for (const auto& p : particles) {\n        // coverage bitset of this particle\n        bitset<MAX_N2> cov;\n        for (int k = 0; k < M; ++k) {\n            cov |= placements[k][p.pos[k]].cells;\n        }\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (cov[idx]) prob[idx] += 1.0;\n        }\n    }\n    double invP = 1.0 / particles.size();\n    for (int i = 0; i < N*N; ++i) prob[i] *= invP;\n    return prob;\n}\n\n// ------------------------------------------------------------\n// Resample particles according to weights\nvoid resample() {\n    double sumw = 0.0;\n    for (auto& p : particles) sumw += p.weight;\n    if (sumw == 0) {\n        // all weights zero, reinitialize\n        init_particles();\n        return;\n    }\n    for (auto& p : particles) p.weight /= sumw;\n    \n    vector<Particle> new_parts;\n    new_parts.reserve(particles.size());\n    double step = 1.0 / particles.size();\n    double r = rand_double() * step;\n    double csum = 0.0;\n    size_t idx = 0;\n    for (size_t i = 0; i < particles.size(); ++i) {\n        double target = r + i * step;\n        while (idx < particles.size() && csum + particles[idx].weight < target) {\n            csum += particles[idx].weight;\n            ++idx;\n        }\n        if (idx >= particles.size()) idx = particles.size() - 1;\n        new_parts.push_back(particles[idx]);\n        new_parts.back().weight = 1.0;\n    }\n    particles.swap(new_parts);\n}\n\n// ------------------------------------------------------------\n// Filter particles by a drilled cell (exact value v)\nvoid filter_by_drill(int cell, int v) {\n    vector<Particle> filtered;\n    filtered.reserve(particles.size());\n    for (const auto& p : particles) {\n        int cnt = 0;\n        for (int k = 0; k < M; ++k) {\n            if (placements[k][p.pos[k]].cells[cell]) ++cnt;\n        }\n        if (cnt == v) filtered.push_back(p);\n    }\n    if ((int)filtered.size() < 10) {\n        // keep some random ones to avoid collapse, or reinitialize with constraint\n        // For simplicity, if too few, we keep original but this is rare\n        if (filtered.empty()) {\n            // total collapse, reinitialize and hope for the best\n            init_particles();\n            return;\n        }\n    }\n    particles.swap(filtered);\n    // reset weights\n    for (auto& p : particles) p.weight = 1.0;\n}\n\n// ------------------------------------------------------------\n// Main\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---- Input ------------------------------------------------\n    if (!(cin >> N >> M >> eps)) return 0;\n    vector<vector<pair<int,int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n    \n    enumerate_placements(shapes);\n    init_particles();\n    \n    vector<char> is_drilled(N*N, 0);\n    vector<int> drilled_val(N*N, -1);\n    \n    const int MAX_Q = 2 * N * N;\n    \n    for (int qcnt = 0; qcnt < MAX_Q - 5; ++qcnt) {\n        // Compute current beliefs\n        vector<double> prob = compute_cell_probs(drilled_val);\n        \n        // Identify uncertain cells\n        vector<int> uncertain;\n        uncertain.reserve(N*N);\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (is_drilled[idx]) continue;\n            if (prob[idx] > 0.1 && prob[idx] < 0.9) {\n                uncertain.push_back(idx);\n            }\n        }\n        \n        // Decide action\n        bool do_answer = false;\n        bool do_drill = false;\n        int drill_cell = -1;\n        vector<int> query_cells; // for divine\n        \n        // If almost all cells are certain, try to answer\n        if ((int)uncertain.size() <= 3 || qcnt > MAX_Q - 10) {\n            do_answer = true;\n        } else if (qcnt < 30) {\n            // Exploration: random large divine query\n            bitset<MAX_N2> mask;\n            for (int i = 0; i < N*N; ++i) {\n                if (rand_int(0,1)) query_cells.push_back(i);\n            }\n            if ((int)query_cells.size() < 2) {\n                query_cells.push_back(0);\n                query_cells.push_back(1);\n            }\n        } else {\n            // Exploitation: divine a batch of uncertain cells\n            // Take up to 25 cells to keep noise moderate (sigma ~ 0.5 for eps=0.01)\n            int take = min((int)uncertain.size(), 25);\n            // Sort by closest to 0.5\n            sort(uncertain.begin(), uncertain.end(), [&](int a, int b){\n                double da = abs(prob[a] - 0.5);\n                double db = abs(prob[b] - 0.5);\n                return da < db;\n            });\n            query_cells.assign(uncertain.begin(), uncertain.begin() + take);\n        }\n        \n        if (do_answer) {\n            vector<int> ans_cells;\n            for (int idx = 0; idx < N*N; ++idx) {\n                if (is_drilled[idx]) {\n                    if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n                } else {\n                    if (prob[idx] > 0.5) ans_cells.push_back(idx);\n                }\n            }\n            // Output answer\n            cout << \"a \" << ans_cells.size();\n            for (int idx : ans_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            int resp; cin >> resp;\n            if (resp == 1) {\n                return 0; // success\n            } else {\n                // Wrong answer, penalized 1 cost, continue\n                continue;\n            }\n        }\n        \n        if (!query_cells.empty() && !do_drill) {\n            // Divine query\n            int k = (int)query_cells.size();\n            cout << \"q \" << k;\n            for (int idx : query_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            \n            int obs; cin >> obs;\n            \n            // Prepare query mask\n            bitset<MAX_N2> qmask;\n            for (int idx : query_cells) qmask.set(idx);\n            \n            // Update weights\n            double kdbl = k;\n            double mu0 = kdbl * eps;\n            double sigma2 = kdbl * eps * (1.0 - eps);\n            double sigma = sqrt(sigma2);\n            if (sigma < 1e-9) sigma = 1e-9;\n            \n            for (auto& p : particles) {\n                int v = 0;\n                for (int m = 0; m < M; ++m) {\n                    v += (placements[m][p.pos[m]].cells & qmask).count();\n                }\n                double mu = mu0 + v * (1.0 - 2.0 * eps);\n                // Gaussian likelihood (ignoring round/max)\n                double z = (obs - mu) / sigma;\n                double w = exp(-0.5 * z * z);\n                p.weight = w;\n            }\n            resample();\n        } else if (do_drill && drill_cell >= 0) {\n            // Single drill\n            cout << \"q 1 \" << drill_cell / N << \" \" << drill_cell % N << endl;\n            int val; cin >> val;\n            is_drilled[drill_cell] = 1;\n            drilled_val[drill_cell] = val;\n            filter_by_drill(drill_cell, val);\n        }\n    }\n    \n    // Fallback: if we exit loop without answering, just answer with current belief\n    vector<int> ans_cells;\n    vector<double> prob = compute_cell_probs(drilled_val);\n    for (int idx = 0; idx < N*N; ++idx) {\n        if (is_drilled[idx]) {\n            if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n        } else {\n            if (prob[idx] > 0.5) ans_cells.push_back(idx);\n        }\n    }\n    cout << \"a \" << ans_cells.size();\n    for (int idx : ans_cells) {\n        cout << \" \" << idx / N << \" \" << idx % N;\n    }\n    cout << endl;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> day_dist(0, D-1);\n    uniform_int_distribution<int> strip_dist(0, N-1);\n    \n    // Heights h[d][k] for each day and strip\n    vector<vector<int>> h(D, vector<int>(N, 1));\n    \n    // Initialize: greedy allocation to minimize area deficit\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> needs;\n        for (int k = 0; k < N; k++) {\n            int need = (a[d][k] + W - 1) / W; // ceil(a/W)\n            needs.push_back({need, k});\n        }\n        // Sort by need descending\n        sort(needs.rbegin(), needs.rend());\n        \n        int remaining = W - N; // each strip gets at least 1\n        for (auto &[need, k] : needs) {\n            int give = min(remaining, max(0, need - 1));\n            h[d][k] = 1 + give;\n            remaining -= give;\n        }\n        // If still remaining (shouldn't happen often), distribute\n        int idx = 0;\n        while (remaining > 0) {\n            h[d][idx % N]++;\n            remaining--;\n            idx++;\n        }\n    }\n    \n    // Cumulative positions y[d][k] = sum_{i<k} h[d][i], with y[d][0]=0, y[d][N]=W\n    vector<vector<int>> y(D, vector<int>(N+1));\n    for (int d = 0; d < D; d++) {\n        y[d][0] = 0;\n        for (int k = 0; k < N; k++) y[d][k+1] = y[d][k] + h[d][k];\n    }\n    \n    // Calculate current cost\n    auto calc_cost = [&]() -> long long {\n        long long cost = 0;\n        // Area cost\n        for (int d = 0; d < D; d++) {\n            for (int k = 0; k < N; k++) {\n                long long area = 1LL * h[d][k] * W;\n                if (area < a[d][k]) cost += 100LL * (a[d][k] - area);\n            }\n        }\n        // Partition change cost\n        for (int d = 1; d < D; d++) {\n            for (int k = 1; k < N; k++) { // boundaries between strips\n                if (y[d][k] != y[d-1][k]) cost += 2LL * W;\n            }\n        }\n        return cost;\n    };\n    \n    long long current_cost = calc_cost();\n    long long best_cost = current_cost;\n    auto best_h = h;\n    auto best_y = y;\n    \n    // Simulated annealing parameters\n    const double TIME_LIMIT = 2.8;\n    clock_t start_time = clock();\n    double T = 1e9; // Initial temperature\n    \n    int iterations = 0;\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Adaptive cooling\n        T = 1e9 * (1.0 - elapsed / TIME_LIMIT);\n        if (T < 1e-3) T = 1e-3;\n        \n        // Select random day and two different strips\n        int d = day_dist(rng);\n        int i = strip_dist(rng);\n        int j = strip_dist(rng);\n        if (i == j) continue;\n        if (h[d][i] <= 1) continue; // cannot decrease below 1\n        \n        // Determine range affected\n        int l = min(i, j);\n        int r = max(i, j);\n        int delta = (i < j) ? -1 : +1; // shift direction for y[d][l..r-1]\n        \n        // Calculate delta cost (O(N) but N<=50)\n        long long delta_cost = 0;\n        \n        // Area cost change for strip i (decrease by 1)\n        long long old_area_i = 1LL * h[d][i] * W;\n        long long new_area_i = 1LL * (h[d][i] - 1) * W;\n        if (old_area_i < a[d][i]) delta_cost -= 100LL * (a[d][i] - old_area_i);\n        if (new_area_i < a[d][i]) delta_cost += 100LL * (a[d][i] - new_area_i);\n        \n        // Area cost change for strip j (increase by 1)\n        long long old_area_j = 1LL * h[d][j] * W;\n        long long new_area_j = 1LL * (h[d][j] + 1) * W;\n        if (old_area_j < a[d][j]) delta_cost -= 100LL * (a[d][j] - old_area_j);\n        if (new_area_j < a[d][j]) delta_cost += 100LL * (a[d][j] - new_area_j);\n        \n        // Partition cost change for boundaries in [l, r-1]\n        for (int k = l; k < r; k++) {\n            int old_y = y[d][k];\n            int new_y = old_y + delta;\n            \n            // Compare with previous day\n            if (d > 0) {\n                bool old_eq = (old_y == y[d-1][k]);\n                bool new_eq = (new_y == y[d-1][k]);\n                if (old_eq && !new_eq) delta_cost += 2LL * W;\n                else if (!old_eq && new_eq) delta_cost -= 2LL * W;\n            }\n            // Compare with next day\n            if (d < D - 1) {\n                bool old_eq = (old_y == y[d+1][k]);\n                bool new_eq = (new_y == y[d+1][k]);\n                if (old_eq && !new_eq) delta_cost += 2LL * W;\n                else if (!old_eq && new_eq) delta_cost -= 2LL * W;\n            }\n        }\n        \n        // Accept or reject\n        bool accept = false;\n        if (delta_cost < 0) {\n            accept = true;\n        } else {\n            // SA acceptance probability\n            double prob = exp(-(double)delta_cost / T);\n            if (uniform_real_distribution<double>(0, 1)(rng) < prob) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            // Apply the move\n            h[d][i]--;\n            h[d][j]++;\n            // Update y[d] (only need to update range [l, r-1] by delta, but recompute for safety)\n            for (int k = l; k < r; k++) {\n                y[d][k] += delta;\n            }\n            // Update cumulative sums after r as well? No, the net effect on y[r] is:\n            // y[r] = y[r-1] + h[r-1]...\n            // Actually, if we decrease h[i] and increase h[j] with i<j:\n            // y[i], y[i+1], ..., y[j-1] all decrease by 1\n            // y[j] = y[j-1] + h[j] (both y[j-1] and h[j] changed: -1 and +1, so y[j] unchanged)\n            // So only [l, r-1] changes.\n            \n            current_cost += delta_cost;\n            \n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_h = h;\n                best_y = y;\n            }\n        }\n        \n        iterations++;\n    }\n    \n    // Output the best solution\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            int i1 = best_y[d][k];\n            int i2 = best_y[d][k+1];\n            int j1 = 0;\n            int j2 = W;\n            cout << i1 << \" \" << j1 << \" \" << i2 << \" \" << j2 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Stamp {\n    int s[3][3];\n};\n\nstruct Solver {\n    int N, M, K;\n    vector<vector<long long>> grid;\n    vector<Stamp> stamps;\n    vector<tuple<int, int, int>> ops; // (stamp_id, p, q)\n    long long current_score = 0;\n    mt19937 rng;\n\n    Solver(int n, int m, int k, const vector<vector<long long>>& init_grid, const vector<Stamp>& st)\n        : N(n), M(m), K(k), grid(init_grid), stamps(st), rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        // Calculate initial score\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                current_score += grid[i][j] % MOD;\n            }\n        }\n    }\n\n    // Compute delta if we add stamp m at position (p, q)\n    long long compute_delta_add(int m, int p, int q) const {\n        long long d = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                long long old_val = grid[r][c];\n                long long new_val = old_val + stamps[m].s[i][j];\n                d += (new_val % MOD) - (old_val % MOD);\n            }\n        }\n        return d;\n    }\n\n    // Compute delta if we remove stamp m at position (p, q)\n    // Note: assumes this stamp was previously added and grid reflects its contribution\n    long long compute_delta_remove(int m, int p, int q) const {\n        long long d = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                long long old_val = grid[r][c];\n                long long new_val = old_val - stamps[m].s[i][j];\n                // Since we only add non-negative values and start non-negative, new_val >= 0\n                d += (new_val % MOD) - (old_val % MOD);\n            }\n        }\n        return d;\n    }\n\n    void apply_add(int m, int p, int q) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                grid[r][c] += stamps[m].s[i][j];\n            }\n        }\n        ops.push_back({m, p, q});\n    }\n\n    void apply_remove(int idx) {\n        auto [m, p, q] = ops[idx];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                grid[r][c] -= stamps[m].s[i][j];\n            }\n        }\n        ops[idx] = ops.back();\n        ops.pop_back();\n    }\n\n    void solve() {\n        // --- Greedy Phase ---\n        for (int iter = 0; iter < K; ++iter) {\n            long long best_delta = 0;\n            int best_m = -1, best_p = -1, best_q = -1;\n\n            for (int m = 0; m < M; ++m) {\n                for (int p = 0; p <= N - 3; ++p) {\n                    for (int q = 0; q <= N - 3; ++q) {\n                        long long d = compute_delta_add(m, p, q);\n                        if (d > best_delta) {\n                            best_delta = d;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n\n            if (best_delta <= 0) break;\n            apply_add(best_m, best_p, best_q);\n            current_score += best_delta;\n        }\n\n        // --- Simulated Annealing Phase ---\n        const int MAX_ITER = 20000;\n        double temp = 1000.0; // Initial temperature\n        uniform_real_distribution<double> dist(0.0, 1.0);\n\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            int move_type = rng() % 3; // 0: add, 1: remove, 2: replace\n\n            if (move_type == 0 && (int)ops.size() < K) {\n                int m = rng() % M;\n                int p = rng() % (N - 2);\n                int q = rng() % (N - 2);\n                long long d = compute_delta_add(m, p, q);\n\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    apply_add(m, p, q);\n                    current_score += d;\n                }\n            } \n            else if (move_type == 1 && !ops.empty()) {\n                int idx = rng() % ops.size();\n                auto [m, p, q] = ops[idx];\n                long long d = compute_delta_remove(m, p, q);\n\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    apply_remove(idx);\n                    current_score += d;\n                }\n            } \n            else if (move_type == 2 && !ops.empty()) {\n                // Replace operation\n                int idx = rng() % ops.size();\n                auto [m_old, p_old, q_old] = ops[idx];\n                \n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n\n                // Remove old\n                long long d_remove = compute_delta_remove(m_old, p_old, q_old);\n                apply_remove(idx);\n                \n                // Compute add delta on modified grid\n                long long d_add = compute_delta_add(m_new, p_new, q_new);\n                \n                long long total_d = d_remove + d_add;\n                \n                if (total_d > 0 || exp(total_d / temp) > dist(rng)) {\n                    apply_add(m_new, p_new, q_new);\n                    current_score += total_d;\n                } else {\n                    // Revert: add old back\n                    apply_add(m_old, p_old, q_old);\n                }\n            }\n\n            // Cool down\n            temp = 1000.0 * (1.0 - (double)(iter + 1) / MAX_ITER);\n            if (temp < 0.1) temp = 0.1;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Process exactly 150 test cases as per problem statement\n    for (int tc = 0; tc < 150; ++tc) {\n        int N, M, K;\n        if (!(cin >> N >> M >> K)) return 0;\n\n        vector<vector<long long>> grid(N, vector<long long>(N));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cin >> grid[i][j];\n            }\n        }\n\n        vector<Stamp> stamps(M);\n        for (int m = 0; m < M; ++m) {\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    cin >> stamps[m].s[i][j];\n                }\n            }\n        }\n\n        Solver solver(N, M, K, grid, stamps);\n        solver.solve();\n\n        cout << solver.ops.size() << '\\n';\n        for (const auto& [m, p, q] : solver.ops) {\n            cout << m << ' ' << p << ' ' << q << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    int turn = 0;\n    // Crane 0 (large) position\n    int cr = 0, cc = 0;\n    bool holding = false;\n    int held = -1;\n    \n    // Grid: -1 empty, else container id\n    vector<vector<int>> grid;\n    // ptr[g] = next index to receive from gate g\n    vector<int> ptr;\n    // A[g][j]\n    vector<vector<int>> A;\n    \n    vector<string> ops; // operations per crane\n    \n    State(int n, const vector<vector<int>>& A_) : A(A_) {\n        grid.assign(n, vector<int>(n, -1));\n        ptr.assign(n, 0);\n        // Initial grid: receiving gates have first container\n        for (int i=0;i<n;i++) {\n            grid[i][0] = A[i][0];\n        }\n        ops.resize(n);\n    }\n    \n    void add_op(int crane, char c) {\n        if ((int)ops[crane].size() <= turn) {\n            ops[crane].push_back(c);\n        } else {\n            ops[crane][turn] = c;\n        }\n    }\n    \n    void simulate_turn(const vector<char>& actions) {\n        // Step 1: Receiving\n        for (int i=0;i<(int)grid.size();i++) {\n            if (ptr[i]+1 < (int)A[i].size() && grid[i][0] == -1) {\n                // Check no crane holding at (i,0) - only crane 0 exists\n                grid[i][0] = A[i][ptr[i]+1];\n                ptr[i]++;\n            } else if (ptr[i] < (int)A[i].size() && grid[i][0] == -1 && ptr[i] == 0) {\n                 // Initial state already handled, but for completeness\n            }\n        }\n        // Actually, receiving happens if square empty AND no crane holding there\n        // We handle by ptr logic: grid[i][0] contains A[i][ptr[i]] if ptr[i] < 5, else -1\n        \n        // Step 2: Actions (we generate them, so we trust validity)\n        // Step 3: Dispatch\n        for (int i=0;i<(int)grid.size();i++) {\n            if (grid[i][4] != -1) {\n                grid[i][4] = -1; // dispatched\n            }\n        }\n        turn++;\n    }\n    \n    // Find parking column in row r (0..4), prefer 2,3,1,0\n    // Returns -1 if full (shouldn't happen)\n    int find_parking_col(int r) {\n        vector<int> order = {2, 3, 1, 0};\n        for (int c : order) {\n            if (grid[r][c] == -1) return c;\n        }\n        return -1; \n    }\n    \n    // Move crane to (tr, tc), appending moves\n    void move_to(int tr, int tc, int crane_idx) {\n        while (cr != tr) {\n            if (cr < tr) { add_op(crane_idx, 'D'); cr++; }\n            else { add_op(crane_idx, 'U'); cr--; }\n        }\n        while (cc != tc) {\n            if (cc < tc) { add_op(crane_idx, 'R'); cc++; }\n            else { add_op(crane_idx, 'L'); cc--; }\n        }\n    }\n    \n    void pickup(int crane_idx) {\n        add_op(crane_idx, 'P');\n        int val = grid[cr][cc];\n        grid[cr][cc] = -1;\n        holding = true;\n        held = val;\n    }\n    \n    void drop(int crane_idx) {\n        add_op(crane_idx, 'Q');\n        grid[cr][cc] = held;\n        holding = false;\n        held = -1;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if(!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) cin >> A[i][j];\n    \n    State st(N, A);\n    int n = N;\n    \n    // Precompute location of each container\n    vector<pair<int,int>> loc(n*n); // (gate, pos)\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        loc[A[i][j]] = {i, j};\n    }\n    \n    // Bomb small cranes 1..n-1 in first turn\n    for (int i=1;i<n;i++) st.add_op(i, 'B');\n    st.add_op(0, '.'); // wait\n    st.simulate_turn({'.', 'B', 'B', 'B', 'B'}); // simulate first turn\n    \n    vector<int> dispatched(n, 0); // how many dispatched from each row\n    vector<int> gate_ptr(n, 0); // next to pick from gate (0..5)\n    \n    // Initialize grid with first containers\n    for (int i=0;i<n;i++) {\n        st.grid[i][0] = A[i][0];\n    }\n    \n    for (int target_row = 0; target_row < n; target_row++) {\n        // Helper to dispatch if next needed\n        auto try_dispatch = [&](int c) -> bool {\n            int need = target_row * n + dispatched[target_row];\n            if (c == need) {\n                // move to dispatch\n                st.move_to(target_row, n-1, 0);\n                st.drop(0);\n                dispatched[target_row]++;\n                return true;\n            }\n            return false;\n        };\n        \n        // First, clear own gate to free column 0\n        while (gate_ptr[target_row] < n) {\n            int c = A[target_row][gate_ptr[target_row]];\n            st.move_to(target_row, 0, 0);\n            st.pickup(0);\n            gate_ptr[target_row]++;\n            if (!try_dispatch(c)) {\n                int col = st.find_parking_col(target_row);\n                if (col == -1) col = 0; // force, though gate not clear yet? Shouldn't happen early\n                st.move_to(target_row, col, 0);\n                st.drop(0);\n            }\n        }\n        \n        // Process other gates for containers belonging to target_row\n        for (int g=0; g<n; g++) {\n            if (g == target_row) continue;\n            // Check if any container at gate g belongs to target_row\n            while (gate_ptr[g] < n) {\n                int c = A[g][gate_ptr[g]];\n                if (c / n != target_row) break;\n                \n                // Need to clear blockers before c at gate g\n                auto [src_g, src_pos] = loc[c];\n                // src_g should be g, src_pos is gate_ptr[g] ideally\n                // But blockers are A[g][0..gate_ptr[g]-1] already cleared\n                // Actually we need to clear up to c's position\n                // loc[c].second is the original position, but ptr has moved\n                // We need to find current position in the sequence\n                int need_pos = -1;\n                for (int j=gate_ptr[g]; j<n; j++) if (A[g][j] == c) { need_pos = j; break; }\n                \n                // Clear blockers\n                while (gate_ptr[g] < need_pos) {\n                    int c2 = A[g][gate_ptr[g]];\n                    st.move_to(g, 0, 0);\n                    st.pickup(0);\n                    gate_ptr[g]++;\n                    int t2 = c2 / n;\n                    int col = st.find_parking_col(t2);\n                    // If no room, use col 0 of t2 if gate cleared, else we have problem\n                    if (col == -1) {\n                        if (gate_ptr[t2] == n) col = 0;\n                        else {\n                            // Find any empty spot\n                            for (int rr=0; rr<n; rr++) {\n                                for (int cc=0; cc<n; cc++) {\n                                    if (st.grid[rr][cc] == -1 && !(rr==st.cr && cc==st.cc)) {\n                                        col = cc; t2 = rr; break;\n                                    }\n                                }\n                                if (col != -1) break;\n                            }\n                        }\n                    }\n                    st.move_to(t2, col, 0);\n                    st.drop(0);\n                }\n                \n                // Now pick up c\n                st.move_to(g, 0, 0);\n                st.pickup(0);\n                gate_ptr[g]++;\n                if (!try_dispatch(c)) {\n                    int col = st.find_parking_col(target_row);\n                    if (col == -1) col = 0; // gate target_row is cleared now\n                    st.move_to(target_row, col, 0);\n                    st.drop(0);\n                }\n            }\n        }\n        \n        // Dispatch remaining in this row\n        while (dispatched[target_row] < n) {\n            int need = target_row * n + dispatched[target_row];\n            // Find need in row target_row\n            int fc = -1;\n            for (int c=0; c<n; c++) {\n                if (st.grid[target_row][c] == need) {\n                    fc = c; break;\n                }\n            }\n            // Should be there\n            if (fc != -1) {\n                st.move_to(target_row, fc, 0);\n                st.pickup(0);\n                st.move_to(target_row, n-1, 0);\n                st.drop(0);\n                dispatched[target_row]++;\n            } else {\n                // Should not happen\n                break;\n            }\n        }\n    }\n    \n    // Pad output to same length\n    size_t max_len = 0;\n    for (auto& s : st.ops) max_len = max(max_len, s.size());\n    for (auto& s : st.ops) {\n        while (s.size() < max_len) s.push_back('.');\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int r = 0, c = 0;\n    long long load = 0;\n    \n    auto move_to = [&](int nr, int nc) {\n        while (r < nr) {\n            ops.emplace_back(\"D\");\n            ++r;\n        }\n        while (r > nr) {\n            ops.emplace_back(\"U\");\n            --r;\n        }\n        while (c < nc) {\n            ops.emplace_back(\"R\");\n            ++c;\n        }\n        while (c > nc) {\n            ops.emplace_back(\"L\");\n            --c;\n        }\n    };\n    \n    auto find_nearest = [&](bool need_positive) -> pair<int, int> {\n        int best_dist = 1e9;\n        pair<int, int> best = {-1, -1};\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                bool ok = need_positive ? (h[i][j] > 0) : (h[i][j] < 0);\n                if (ok) {\n                    int d = abs(i - r) + abs(j - c);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best = {i, j};\n                    }\n                }\n            }\n        }\n        return best;\n    };\n    \n    while (true) {\n        auto target = find_nearest(load == 0);\n        if (target.first == -1) break; // No more work\n        \n        move_to(target.first, target.second);\n        \n        if (h[r][c] > 0) {\n            // Load all soil from this cell\n            int d = h[r][c];\n            ops.emplace_back(\"+\" + to_string(d));\n            load += d;\n            h[r][c] = 0;\n        } else {\n            // Unload as much as needed/possible\n            int need = -h[r][c];\n            int d = (int)min<long long>(need, load);\n            ops.emplace_back(\"-\" + to_string(d));\n            load -= d;\n            h[r][c] += d; // h[r][c] was negative, now closer to 0\n        }\n    }\n    \n    for (const auto& s : ops) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Solver {\n    int N, M, T;\n    int SEED_COUNT;\n    struct Seed {\n        vector<int> x;\n        int sum;\n    };\n    vector<Seed> seeds;\n    mt19937 rng;\n    chrono::steady_clock::time_point start_time;\n\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        start_time = chrono::steady_clock::now();\n    }\n\n    ll edgeScore(int a, int b) {\n        ll s = 0;\n        for (int l = 0; l < M; l++) {\n            s += max(seeds[a].x[l], seeds[b].x[l]);\n        }\n        return s;\n    }\n\n    void solveOneTurn(int turn) {\n        // Select top N*N seeds by total sum\n        vector<int> idx(SEED_COUNT);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b) {\n            return seeds[a].sum > seeds[b].sum;\n        });\n        vector<int> selected(idx.begin(), idx.begin() + N * N);\n\n        // Grid placement: position -> seed index\n        vector<vector<int>> pos(N, vector<int>(N));\n        shuffle(selected.begin(), selected.end(), rng);\n        int cur = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                pos[i][j] = selected[cur++];\n            }\n        }\n\n        // Precompute neighbors\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        vector<vector<vector<pair<int,int>>>> neighbors(N, vector<vector<pair<int,int>>>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                        neighbors[i][j].push_back({ni, nj});\n                    }\n                }\n            }\n        }\n\n        auto calcLocal = [&](int i, int j) -> ll {\n            ll s = 0;\n            for (auto [ni, nj] : neighbors[i][j]) {\n                s += edgeScore(pos[i][j], pos[ni][nj]);\n            }\n            return s;\n        };\n\n        // Simulated Annealing\n        double temp = 500.0;\n        const double cooling = 0.9995;\n        \n        // Time management: aim to use roughly 1.8s total\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        double time_per_turn = (1.8 - elapsed) / (T - turn);\n        if (time_per_turn < 0.01) time_per_turn = 0.01;\n        \n        int iter = 0;\n        while (true) {\n            now = chrono::steady_clock::now();\n            double time_used = chrono::duration<double>(now - start_time).count();\n            if (time_used > 1.8 * (turn + 1) / T) break;\n            \n            int i1 = rng() % N;\n            int j1 = rng() % N;\n            int i2 = rng() % N;\n            int j2 = rng() % N;\n            if (i1 == i2 && j1 == j2) continue;\n\n            // Calculate contribution of affected cells before swap\n            ll oldLocal = calcLocal(i1, j1) + calcLocal(i2, j2);\n            // If adjacent, the edge between them is counted twice in oldLocal,\n            // but it will be counted twice in newLocal with the same value (since max is symmetric),\n            // so it cancels out in delta.\n\n            swap(pos[i1][j1], pos[i2][j2]);\n\n            ll newLocal = calcLocal(i1, j1) + calcLocal(i2, j2);\n            ll delta = newLocal - oldLocal;\n\n            if (delta > 0 || exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                // Accept swap\n            } else {\n                swap(pos[i1][j1], pos[i2][j2]); // Revert\n            }\n\n            temp *= cooling;\n            iter++;\n            if (iter > 50000) break; // Safety limit\n        }\n\n        // Output\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j > 0) cout << ' ';\n                cout << pos[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n    }\n\n    void solve() {\n        cin >> N >> M >> T;\n        SEED_COUNT = 2 * N * (N - 1);\n        seeds.resize(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].x.resize(M);\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].x[j];\n            }\n            seeds[i].sum = accumulate(seeds[i].x.begin(), seeds[i].x.end(), 0);\n        }\n\n        for (int turn = 0; turn < T; turn++) {\n            solveOneTurn(turn);\n\n            // Read next generation\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i].x[j];\n                }\n                seeds[i].sum = accumulate(seeds[i].x.begin(), seeds[i].x.end(), 0);\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V_limit;\nvector<string> s_grid, t_grid;\nvector<pair<int,int>> sources, targets;\n\n// Hungarian algorithm for assignment problem\n// Returns matching: match[i] = index of target matched to source i\nvector<int> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i=1; i<=n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INT_MAX);\n        vector<char> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INT_MAX, j1 = 0;\n            for (int j=1; j<=m; j++) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j=0; j<=m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> match(n);\n    for (int j=1; j<=m; j++) {\n        if (p[j] != 0) match[p[j]-1] = j-1;\n    }\n    return match;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> V_limit;\n    s_grid.resize(N);\n    for (int i=0; i<N; i++) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i=0; i<N; i++) cin >> t_grid[i];\n\n    // Collect positions\n    for (int i=0; i<N; i++) {\n        for (int j=0; j<N; j++) {\n            if (s_grid[i][j] == '1') sources.push_back({i, j});\n            if (t_grid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    // Build cost matrix for Hungarian\n    vector<vector<int>> cost(M, vector<int>(M));\n    for (int i=0; i<M; i++) {\n        for (int j=0; j<M; j++) {\n            cost[i][j] = abs(sources[i].first - targets[j].first) \n                       + abs(sources[i].second - targets[j].second);\n        }\n    }\n    \n    vector<int> match = hungarian(cost);\n    \n    // Create pairs (source, target)\n    vector<pair<pair<int,int>, pair<int,int>>> pairs;\n    for (int i=0; i<M; i++) {\n        pairs.push_back({sources[i], targets[match[i]]});\n    }\n\n    // Order pairs using greedy nearest neighbor\n    vector<pair<pair<int,int>, pair<int,int>>> ordered;\n    vector<bool> used(M, false);\n    int cur_x = 0, cur_y = 0; // current root position tracker for ordering\n    \n    for (int iter=0; iter<M; iter++) {\n        int best_i = -1;\n        int best_dist = INT_MAX;\n        for (int i=0; i<M; i++) {\n            if (used[i]) continue;\n            int d = abs(cur_x - pairs[i].first.first) \n                  + abs(cur_y - pairs[i].first.second);\n            if (d < best_dist) {\n                best_dist = d;\n                best_i = i;\n            }\n        }\n        used[best_i] = true;\n        ordered.push_back(pairs[best_i]);\n        cur_x = pairs[best_i].second.first;\n        cur_y = pairs[best_i].second.second;\n    }\n\n    // Output tree design: 2 vertices, edge length 1\n    cout << 2 << \"\\n\";\n    cout << \"0 1\\n\";  // parent of 1 is 0, length 1\n    cout << \"0 0\\n\";  // initial root position\n\n    // Simulation parameters\n    const int L = 1;  // edge length\n    int rx = 0, ry = 0;  // root position\n    int dir = 0;  // 0=right, 1=down, 2=left, 3=up\n    // Direction vectors: right, down, left, up\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    auto move_to = [&](int tx, int ty) {\n        // Find best target direction to minimize turns\n        int best_d = 0;\n        int best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = tx - dx[d] * L;\n            int ny = ty - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manhattan = abs(rx - nx) + abs(ry - ny);\n            int rot = min(abs(dir - d), 4 - abs(dir - d));\n            int cost = max(manhattan, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        \n        int nx = tx - dx[best_d] * L;\n        int ny = ty - dy[best_d] * L;\n        \n        // Generate moves\n        while (rx != nx || ry != ny || dir != best_d) {\n            string cmd(4, '.');  // V'=2, so 4 characters\n            \n            // Move root\n            if (rx < nx) { cmd[0] = 'D'; rx++; }\n            else if (rx > nx) { cmd[0] = 'U'; rx--; }\n            else if (ry < ny) { cmd[0] = 'R'; ry++; }\n            else if (ry > ny) { cmd[0] = 'L'; ry--; }\n            \n            // Rotate if needed\n            if (dir != best_d) {\n                int diff = (best_d - dir + 4) % 4;\n                if (diff == 1) {\n                    cmd[1] = 'R';  // clockwise\n                    dir = (dir + 1) % 4;\n                } else if (diff == 3) {\n                    cmd[1] = 'L';  // counter-clockwise\n                    dir = (dir + 3) % 4;\n                } else if (diff == 2) {\n                    // 180 degrees - rotate 90 now, rest next turn\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                }\n            }\n            cout << cmd << \"\\n\";\n        }\n    };\n    \n    auto perform_action = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P';  // fingertip is vertex 1\n        cout << cmd << \"\\n\";\n    };\n\n    // Execute operations\n    for (auto& [src, dst] : ordered) {\n        // Move to source and pick up\n        move_to(src.first, src.second);\n        perform_action();\n        \n        // Move to destination and drop\n        move_to(dst.first, dst.second);\n        perform_action();\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int sum = 0;\n    int best = 0;\n    int left_best = 0;\n    int right_best = 0;\n    int best_l = 0, best_r = 0;\n    int left_pos = 0;\n    int right_pos = 0;\n};\n\nclass SegTree {\n    int n;\n    vector<Node> tree;\npublic:\n    SegTree(int size) {\n        n = 1;\n        while (n < size) n <<= 1;\n        tree.resize(2 * n);\n        init(1, 0, n - 1);\n    }\n\n    void init(int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].left_pos = l;\n            tree[idx].right_pos = r;\n            tree[idx].best_l = l;\n            tree[idx].best_r = r;\n            return;\n        }\n        int mid = (l + r) >> 1;\n        init(idx << 1, l, mid);\n        init(idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    void pull(int idx, int left, int right) {\n        Node &res = tree[idx];\n        Node &L = tree[left];\n        Node &R = tree[right];\n\n        res.sum = L.sum + R.sum;\n\n        // Left prefix\n        if (L.left_best >= L.sum + R.left_best) {\n            res.left_best = L.left_best;\n            res.left_pos = L.left_pos;\n        } else {\n            res.left_best = L.sum + R.left_best;\n            res.left_pos = L.left_pos;\n        }\n\n        // Right suffix\n        if (R.right_best >= R.sum + L.right_best) {\n            res.right_best = R.right_best;\n            res.right_pos = R.right_pos;\n        } else {\n            res.right_best = R.sum + L.right_best;\n            res.right_pos = R.right_pos;\n        }\n\n        // Best subarray\n        res.best = L.best;\n        res.best_l = L.best_l;\n        res.best_r = L.best_r;\n\n        if (R.best > res.best) {\n            res.best = R.best;\n            res.best_l = R.best_l;\n            res.best_r = R.best_r;\n        }\n\n        int cross = L.right_best + R.left_best;\n        if (cross > res.best) {\n            res.best = cross;\n            res.best_l = L.right_pos;\n            res.best_r = R.left_pos;\n        }\n    }\n\n    void update(int pos, int val) { update(pos, val, 1, 0, n - 1); }\n\n    void update(int pos, int val, int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].sum += val;\n            tree[idx].best += val;\n            tree[idx].left_best += val;\n            tree[idx].right_best += val;\n            return;\n        }\n        int mid = (l + r) >> 1;\n        if (pos <= mid) update(pos, val, idx << 1, l, mid);\n        else update(pos, val, idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    const Node& query() const { return tree[1]; }\n};\n\nstruct Point {\n    int x, y;\n    int type; // +1 for mackerel, -1 for sardine\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    \n    vector<Point> points;\n    points.reserve(2 * N);\n    vector<int> all_x, all_y;\n    all_x.reserve(2 * N);\n    all_y.reserve(2 * N);\n\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Coordinate compression for y\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n    int Y = all_y.size();\n\n    // Group points by x-coordinate\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    \n    map<int, vector<pair<int, int>>> x_to_points; // x -> list of (y_idx, type)\n    for (const auto &p : points) {\n        int y_idx = lower_bound(all_y.begin(), all_y.end(), p.y) - all_y.begin();\n        x_to_points[p.x].push_back({y_idx, p.type});\n    }\n\n    // Select candidate x-coordinates (those with highest density)\n    vector<int> x_cands = all_x;\n    if (x_cands.size() > 300) {\n        vector<pair<int, int>> cnts;\n        for (int x : x_cands) {\n            cnts.push_back({(int)x_to_points[x].size(), x});\n        }\n        sort(cnts.rbegin(), cnts.rend());\n        x_cands.clear();\n        for (int i = 0; i < 300; ++i) x_cands.push_back(cnts[i].second);\n        sort(x_cands.begin(), x_cands.end());\n    }\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 1, best_y1 = 0, best_y2 = 1;\n\n    // Sweep line\n    for (size_t i = 0; i < x_cands.size(); ++i) {\n        SegTree seg(Y);\n        for (size_t j = i; j < x_cands.size(); ++j) {\n            int x = x_cands[j];\n            auto it = x_to_points.find(x);\n            if (it != x_to_points.end()) {\n                for (const auto &[y_idx, typ] : it->second) {\n                    seg.update(y_idx, typ);\n                }\n            }\n            \n            const Node &res = seg.query();\n            if (res.best > best_score) {\n                best_score = res.best;\n                best_x1 = x_cands[i];\n                best_x2 = x;\n                best_y1 = all_y[res.best_l];\n                best_y2 = all_y[res.best_r];\n                if (best_y1 > best_y2) swap(best_y1, best_y2);\n            }\n        }\n    }\n\n    // Ensure distinct vertices and valid polygon\n    if (best_x1 == best_x2) {\n        if (best_x1 > 0) best_x1--;\n        else best_x2++;\n    }\n    if (best_y1 == best_y2) {\n        if (best_y1 > 0) best_y1--;\n        else best_y2++;\n    }\n\n    // Output rectangle\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        double w, h;\n        cin >> w >> h;\n        w_est[i] = w;\n        h_est[i] = h;\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        vector<double> x(N, 0), y(N, 0);\n        vector<int> rot(N, 0);\n        vector<Placement> ops;\n        ops.reserve(N);\n        \n        double cur_W = 0, cur_H = 0;\n        \n        for (int i = 0; i < N; i++) {\n            double best_score = 1e300;\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            double best_x = 0, best_y = 0;\n            \n            for (int r = 0; r < 2; r++) {\n                double wi = r ? h_est[i] : w_est[i];\n                double hi = r ? w_est[i] : h_est[i];\n                \n                // Try both directions\n                for (char d : {'U', 'L'}) {\n                    // Try all possible bases\n                    for (int b = -1; b < i; b++) {\n                        double xi, yi;\n                        \n                        if (d == 'U') {\n                            // Fix x based on b\n                            if (b == -1) {\n                                xi = 0;\n                            } else {\n                                double wb = rot[b] ? h_est[b] : w_est[b];\n                                xi = x[b] + wb;\n                            }\n                            \n                            // Find y by checking overlaps (skyline)\n                            yi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check x-overlap: [xi, xi+wi) vs [xj, xj+wj)\n                                if (max(xi, xj) < min(xi + wi, xj + wj)) {\n                                    yi = max(yi, yj + hj);\n                                }\n                            }\n                        } else { // 'L'\n                            // Fix y based on b\n                            if (b == -1) {\n                                yi = 0;\n                            } else {\n                                double hb = rot[b] ? w_est[b] : h_est[b];\n                                yi = y[b] + hb;\n                            }\n                            \n                            // Find x by checking overlaps\n                            xi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check y-overlap: [yi, yi+hi) vs [yj, yj+hj)\n                                if (max(yi, yj) < min(yi + hi, yj + hj)) {\n                                    xi = max(xi, xj + wj);\n                                }\n                            }\n                        }\n                        \n                        double new_W = max(cur_W, xi + wi);\n                        double new_H = max(cur_H, yi + hi);\n                        double score = new_W + new_H;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            best_x = xi;\n                            best_y = yi;\n                        }\n                    }\n                }\n            }\n            \n            rot[i] = best_r;\n            x[i] = best_x;\n            y[i] = best_y;\n            ops.push_back({i, best_r, best_b, best_d});\n            \n            double wi = best_r ? h_est[i] : w_est[i];\n            double hi = best_r ? w_est[i] : h_est[i];\n            cur_W = max(cur_W, best_x + wi);\n            cur_H = max(cur_H, best_y + hi);\n        }\n        \n        // Output\n        cout << N << \"\\n\";\n        for (const auto& op : ops) {\n            cout << op.p << \" \" << op.r << \" \" << op.d << \" \" << op.b << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read feedback\n        double Wp, Hp;\n        cin >> Wp >> Hp;\n        \n        // Update estimates based on feedback\n        // Compute current max based on estimates\n        double max_right = 0;\n        double max_bottom = 0;\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            max_right = max(max_right, x[i] + wi);\n            max_bottom = max(max_bottom, y[i] + hi);\n        }\n        \n        // Update width estimates for critical rectangles\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            \n            // Check if this rectangle determines the width boundary\n            if (abs(x[i] + wi - max_right) < 1e-6) {\n                double target = Wp - x[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                } else {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                }\n            }\n            \n            // Check if this rectangle determines the height boundary\n            if (abs(y[i] + hi - max_bottom) < 1e-6) {\n                double target = Hp - y[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                } else {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> parent;\n    vector<int> depth;\n    vector<long long> sub_sum;\n    vector<int> height;\n    vector<vector<int>> children;\n    \n    void input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; i++) cin >> A[i];\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v; cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // Skip coordinates\n        for (int i = 0; i < N; i++) {\n            int x, y; cin >> x >> y;\n        }\n    }\n    \n    // Compute sub_sum and height for tree rooted at root\n    void dfs_info(int v) {\n        sub_sum[v] = A[v];\n        height[v] = 0;\n        for (int c : children[v]) {\n            dfs_info(c);\n            sub_sum[v] += sub_sum[c];\n            height[v] = max(height[v], height[c] + 1);\n        }\n    }\n    \n    void compute_all_info() {\n        children.assign(N, {});\n        for (int i = 0; i < N; i++) {\n            if (parent[i] != -1) {\n                children[parent[i]].push_back(i);\n            }\n        }\n        sub_sum.assign(N, 0);\n        height.assign(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) {\n                dfs_info(i);\n            }\n        }\n    }\n    \n    long long calc_score() {\n        long long res = 0;\n        for (int i = 0; i < N; i++) {\n            res += (long long)(depth[i] + 1) * A[i];\n        }\n        return res;\n    }\n    \n    bool is_ancestor(int u, int v) {\n        // check if u is ancestor of v\n        int cur = v;\n        while (cur != -1) {\n            if (cur == u) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n    \n    void update_depths(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) {\n            update_depths(c, delta);\n        }\n    }\n    \n    void greedy_construct() {\n        parent.assign(N, -1);\n        depth.assign(N, -1);\n        vector<long long> path_sum(N, 0);\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return A[i] > A[j];\n        });\n        \n        for (int v : order) {\n            int best_parent = -1;\n            int best_depth = -1;\n            long long best_path_sum = -1;\n            \n            for (int u : adj[v]) {\n                if (depth[u] != -1 && depth[u] < H) {\n                    if (depth[u] > best_depth || (depth[u] == best_depth && path_sum[u] > best_path_sum)) {\n                        best_depth = depth[u];\n                        best_parent = u;\n                        best_path_sum = path_sum[u];\n                    }\n                }\n            }\n            \n            if (best_parent == -1) {\n                parent[v] = -1;\n                depth[v] = 0;\n                path_sum[v] = A[v];\n            } else {\n                parent[v] = best_parent;\n                depth[v] = depth[best_parent] + 1;\n                path_sum[v] = path_sum[best_parent] + A[v];\n            }\n        }\n    }\n    \n    void local_search() {\n        // Steepest ascent local search\n        bool improved = true;\n        int max_iter = 50;\n        int iter = 0;\n        \n        while (improved && iter < max_iter) {\n            improved = false;\n            iter++;\n            \n            // Try all possible moves and pick the best\n            long long best_gain = 0;\n            int best_v = -1, best_new_parent = -1;\n            \n            // Randomize order to avoid bias\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            random_shuffle(order.begin(), order.end());\n            \n            for (int v : order) {\n                int cur_depth = depth[v];\n                long long cur_sub = sub_sum[v];\n                int cur_height = height[v];\n                \n                // Try all neighbors as new parent\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (depth[u] == -1) continue; // should not happen after greedy\n                    if (depth[u] >= H) continue; // cannot be parent\n                    \n                    int new_depth = depth[u] + 1;\n                    if (new_depth <= cur_depth) continue; // no improvement in depth\n                    \n                    // Check if u is in subtree of v (would create cycle)\n                    if (is_ancestor(v, u)) continue;\n                    \n                    // Check height constraint: new_depth + height[v] <= H\n                    if (new_depth + cur_height > H) continue;\n                    \n                    long long gain = (long long)(new_depth - cur_depth) * cur_sub;\n                    \n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_v = v;\n                        best_new_parent = u;\n                    }\n                }\n            }\n            \n            if (best_gain > 0) {\n                // Apply the move\n                int v = best_v;\n                int u = best_new_parent;\n                int old_parent = parent[v];\n                \n                // Remove from old parent\n                if (old_parent != -1) {\n                    auto& vec = children[old_parent];\n                    vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n                }\n                \n                // Add to new parent\n                parent[v] = u;\n                children[u].push_back(v);\n                \n                // Update depths for subtree v\n                int delta = depth[u] + 1 - depth[v];\n                update_depths(v, delta);\n                \n                // Recompute all info (sub_sum, height) from roots\n                // This is necessary because sub_sum and height of ancestors changed\n                compute_all_info();\n                \n                improved = true;\n            }\n        }\n    }\n    \n    void solve() {\n        input();\n        greedy_construct();\n        compute_all_info();\n        local_search();\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            if (i) cout << \" \";\n            cout << parent[i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // For local search randomization\n    srand(time(0));\n    \n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<string> C(N);\n    for (int i = 0; i < N; i++) cin >> C[i];\n    \n    vector<vector<bool>> is_oni(N, vector<bool>(N, false));\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (C[i][j] == 'x') {\n                is_oni[i][j] = true;\n            } else if (C[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    // Precompute safe ranges for each column\n    vector<int> max_up(N, -1);    // max row where Up is safe (no fuku in [0, row])\n    vector<int> min_down(N, N);   // min row where Down is safe (no fuku in [row, N-1])\n    \n    for (int j = 0; j < N; j++) {\n        int first_fuku = N;\n        for (int i = 0; i < N; i++) {\n            if (is_fuku[i][j]) {\n                first_fuku = i;\n                break;\n            }\n        }\n        max_up[j] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int i = N-1; i >= 0; i--) {\n            if (is_fuku[i][j]) {\n                last_fuku = i;\n                break;\n            }\n        }\n        min_down[j] = last_fuku + 1;\n    }\n    \n    // Precompute safe ranges for each row\n    vector<int> max_left(N, -1);  // max col where Left is safe\n    vector<int> min_right(N, N);  // min col where Right is safe\n    \n    for (int i = 0; i < N; i++) {\n        int first_fuku = N;\n        for (int j = 0; j < N; j++) {\n            if (is_fuku[i][j]) {\n                first_fuku = j;\n                break;\n            }\n        }\n        max_left[i] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int j = N-1; j >= 0; j--) {\n            if (is_fuku[i][j]) {\n                last_fuku = j;\n                break;\n            }\n        }\n        min_right[i] = last_fuku + 1;\n    }\n    \n    vector<pair<char, int>> ops;\n    \n    while (true) {\n        double best_eff = -1.0;\n        int best_gain = 0;\n        int best_cost = 0;\n        char best_dir = 0;\n        int best_idx = 0;\n        int best_limit = 0; // row for U/D, col for L/R\n        \n        // Check columns for Up\n        for (int j = 0; j < N; j++) {\n            if (max_up[j] < 0) continue;\n            int highest = -1;\n            int count = 0;\n            for (int i = 0; i <= max_up[j]; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    highest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (highest + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost) || best_gain == 0) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'U';\n                best_idx = j;\n                best_limit = highest;\n            }\n        }\n        \n        // Check columns for Down\n        for (int j = 0; j < N; j++) {\n            if (min_down[j] >= N) continue;\n            int lowest = N;\n            int count = 0;\n            for (int i = min_down[j]; i < N; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    lowest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - lowest);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'D';\n                best_idx = j;\n                best_limit = lowest;\n            }\n        }\n        \n        // Check rows for Left\n        for (int i = 0; i < N; i++) {\n            if (max_left[i] < 0) continue;\n            int rightmost = -1;\n            int count = 0;\n            for (int j = 0; j <= max_left[i]; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    rightmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (rightmost + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'L';\n                best_idx = i;\n                best_limit = rightmost;\n            }\n        }\n        \n        // Check rows for Right\n        for (int i = 0; i < N; i++) {\n            if (min_right[i] >= N) continue;\n            int leftmost = N;\n            int count = 0;\n            for (int j = min_right[i]; j < N; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    leftmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - leftmost);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'R';\n                best_idx = i;\n                best_limit = leftmost;\n            }\n        }\n        \n        if (best_gain == 0) break; // No more Oni\n        \n        // Apply the best operation\n        if (best_dir == 'U') {\n            int j = best_idx;\n            int h = best_limit;\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('U', j);\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('D', j);\n            for (int i = 0; i <= h; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'D') {\n            int j = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('D', j);\n            for (int k = 0; k < times; k++) ops.emplace_back('U', j);\n            for (int i = l; i < N; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'L') {\n            int i = best_idx;\n            int r = best_limit;\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('L', i);\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('R', i);\n            for (int j = 0; j <= r; j++) is_oni[i][j] = false;\n        } else if (best_dir == 'R') {\n            int i = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('R', i);\n            for (int k = 0; k < times; k++) ops.emplace_back('L', i);\n            for (int j = l; j < N; j++) is_oni[i][j] = false;\n        }\n    }\n    \n    // Output\n    for (auto &[d, p] : ops) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    // Best solution found\n    vector<int> best_a(N), best_b(N);\n    long long best_error = (1LL << 60);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_node(0, N-1);\n    uniform_int_distribution<int> dist_choice(0, 1);\n    \n    const auto TIME_LIMIT = 1900; // ms, leave some margin\n    \n    auto evaluate = [&](const vector<int>& a, const vector<int>& b) -> long long {\n        vector<int> cnt(N, 0);\n        int cur = 0;\n        for (int week = 0; week < L; ++week) {\n            cnt[cur]++;\n            if (week == L - 1) break;\n            // If count is odd (1, 3, 5...), go to a[cur]\n            // Since we just incremented, cnt[cur] is the current count\n            if (cnt[cur] & 1) {\n                cur = a[cur];\n            } else {\n                cur = b[cur];\n            }\n        }\n        long long err = 0;\n        for (int i = 0; i < N; ++i) {\n            err += llabs((long long)cnt[i] - T[i]);\n        }\n        return err;\n    };\n    \n    auto solve_one = [&](int seed) {\n        mt19937 local_rng(seed);\n        vector<int> a(N), b(N);\n        \n        // Greedy initialization based on flow approximation\n        // Each node i sends ceil(T[i]/2) to a[i] and floor(T[i]/2) to b[i]\n        // We want to satisfy demands T[j] for each node j\n        vector<long long> remaining(N);\n        for (int i = 0; i < N; ++i) remaining[i] = T[i];\n        \n        for (int i = 0; i < N; ++i) {\n            // Find node with max remaining demand for a[i]\n            int max_j = 0;\n            for (int j = 1; j < N; ++j) {\n                if (remaining[j] > remaining[max_j]) max_j = j;\n            }\n            a[i] = max_j;\n            remaining[max_j] -= (T[i] + 1) / 2; // ceil(T[i]/2)\n            \n            // Find node with max remaining demand for b[i]\n            max_j = 0;\n            for (int j = 1; j < N; ++j) {\n                if (remaining[j] > remaining[max_j]) max_j = j;\n            }\n            b[i] = max_j;\n            remaining[max_j] -= T[i] / 2; // floor(T[i]/2)\n        }\n        \n        // Ensure valid range\n        for (int i = 0; i < N; ++i) {\n            a[i] = max(0, min(N-1, a[i]));\n            b[i] = max(0, min(N-1, b[i]));\n        }\n        \n        long long cur_error = evaluate(a, b);\n        if (cur_error < best_error) {\n            best_error = cur_error;\n            best_a = a;\n            best_b = b;\n        }\n        \n        auto start_time = chrono::steady_clock::now();\n        int iter = 0;\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n            \n            ++iter;\n            \n            // Random modification\n            int idx = uniform_int_distribution<int>(0, N-1)(local_rng);\n            int choice = uniform_int_distribution<int>(0, 1)(local_rng);\n            int new_val = uniform_int_distribution<int>(0, N-1)(local_rng);\n            \n            int old_val;\n            if (choice == 0) {\n                old_val = a[idx];\n                a[idx] = new_val;\n            } else {\n                old_val = b[idx];\n                b[idx] = new_val;\n            }\n            \n            long long new_error = evaluate(a, b);\n            \n            if (new_error <= cur_error) {\n                cur_error = new_error;\n                if (cur_error < best_error) {\n                    best_error = cur_error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                // Revert\n                if (choice == 0) a[idx] = old_val;\n                else b[idx] = old_val;\n            }\n        }\n    };\n    \n    // Try multiple seeds\n    vector<int> seeds = {42, 123, 456, 789, 101112, 131415, 161718, 192021, 222324, 252627};\n    for (int s : seeds) {\n        auto start = chrono::steady_clock::now();\n        solve_one(s);\n        auto end = chrono::steady_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count();\n        if (elapsed > TIME_LIMIT) break; // Don't start new if almost out of time\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Estimated centers (integer)\n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n    \n    // Sort cities by estimated position to get spatially coherent groups\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        if (cx[a] != cx[b]) return cx[a] < cx[b];\n        return cy[a] < cy[b];\n    });\n    \n    // Build groups of required sizes\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].reserve(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(ord[pos++]);\n        }\n    }\n    \n    vector<vector<pair<int,int>>> groupEdges(M);\n    int queriesUsed = 0;\n    \n    for (int gi = 0; gi < M; ++gi) {\n        auto &grp = groups[gi];\n        int gsize = (int)grp.size();\n        if (gsize <= 1) continue; // no edges needed\n        \n        // Choose hub: city closest to the average position of the group\n        long long sumx = 0, sumy = 0;\n        for (int v : grp) {\n            sumx += cx[v];\n            sumy += cy[v];\n        }\n        double avgx = (double)sumx / gsize;\n        double avgy = (double)sumy / gsize;\n        \n        int hub = grp[0];\n        double bestDist = hypot((double)cx[hub] - avgx, (double)cy[hub] - avgy);\n        for (int v : grp) {\n            double d = hypot((double)cx[v] - avgx, (double)cy[v] - avgy);\n            if (d < bestDist) {\n                bestDist = d;\n                hub = v;\n            }\n        }\n        \n        // Build list of non-hub cities\n        vector<int> others;\n        others.reserve(gsize - 1);\n        for (int v : grp) {\n            if (v != hub) others.push_back(v);\n        }\n        \n        // Query in batches of size (L-1)\n        for (int i = 0; i < (int)others.size(); i += L - 1) {\n            int batchEnd = min(i + L - 1, (int)others.size());\n            vector<int> querySet;\n            querySet.reserve(batchEnd - i + 1);\n            querySet.push_back(hub);\n            for (int j = i; j < batchEnd; ++j) {\n                querySet.push_back(others[j]);\n            }\n            \n            // Output query\n            cout << \"? \" << (int)querySet.size();\n            for (int v : querySet) cout << ' ' << v;\n            cout << '\\n';\n            cout.flush();\n            \n            // Read edges (batchSize edges)\n            int batchSize = (int)querySet.size() - 1;\n            for (int j = 0; j < batchSize; ++j) {\n                int a, b;\n                cin >> a >> b;\n                groupEdges[gi].emplace_back(a, b);\n            }\n            ++queriesUsed;\n        }\n    }\n    \n    // Final output\n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << ' ';\n            cout << grp[i];\n        }\n        cout << '\\n';\n        for (auto [a, b] : groupEdges[gi]) {\n            cout << a << ' ' << b << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.emplace_back(r, c);\n    }\n    \n    vector<pair<char,char>> ans;\n    auto add_move = [&](char d, int cnt) {\n        for (int i = 0; i < cnt; i++) ans.emplace_back('M', d);\n    };\n    auto add_slide = [&](char d) {\n        ans.emplace_back('S', d);\n    };\n    \n    int cr = r0, cc = c0;\n    const int MAXC = N - 1; // 19\n    \n    for (auto [tr, tc] : targets) {\n        int dr = tr - cr;\n        int dc = tc - cc;\n        int abs_dr = abs(dr);\n        int abs_dc = abs(dc);\n        \n        // Direct Manhattan\n        int best_cost = abs_dr + abs_dc;\n        int strategy = 0; // 0=direct, 1=top, 2=bot, 3=left, 4=right, 5=corner\n        \n        // Via Top: slide up to row 0, walk horiz, walk down to tr\n        int cost_top = 1 + abs_dc + tr;\n        if (cost_top < best_cost) {\n            best_cost = cost_top;\n            strategy = 1;\n        }\n        \n        // Via Bottom: slide down to row 19, walk horiz, walk up to tr\n        int cost_bot = 1 + abs_dc + (MAXC - tr);\n        if (cost_bot < best_cost) {\n            best_cost = cost_bot;\n            strategy = 2;\n        }\n        \n        // Via Left: slide left to col 0, walk vert, walk right to tc\n        int cost_left = 1 + abs_dr + tc;\n        if (cost_left < best_cost) {\n            best_cost = cost_left;\n            strategy = 3;\n        }\n        \n        // Via Right: slide right to col 19, walk vert, walk left to tc\n        int cost_right = 1 + abs_dr + (MAXC - tc);\n        if (cost_right < best_cost) {\n            best_cost = cost_right;\n            strategy = 4;\n        }\n        \n        // Via Corner: 2 slides to a corner, then walk\n        int dist_from_corner = min(tr, MAXC - tr) + min(tc, MAXC - tc);\n        int cost_corner = 2 + dist_from_corner;\n        if (cost_corner < best_cost) {\n            best_cost = cost_corner;\n            strategy = 5;\n        }\n        \n        if (strategy == 0) {\n            // Direct: move vertical then horizontal (order doesn't matter)\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n        } else if (strategy == 1) {\n            // Via top\n            add_slide('U');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('D', tr); // down from row 0 to tr\n        } else if (strategy == 2) {\n            // Via bottom\n            add_slide('D');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('U', MAXC - tr); // up from row 19 to tr\n        } else if (strategy == 3) {\n            // Via left\n            add_slide('L');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('R', tc); // right from col 0 to tc\n        } else if (strategy == 4) {\n            // Via right\n            add_slide('R');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('L', MAXC - tc); // left from col 19 to tc\n        } else if (strategy == 5) {\n            // Via best corner\n            // Determine which corner is best (gives min walking distance)\n            int best_corner = 0; // 0:TL, 1:TR, 2:BL, 3:BR\n            int best_corner_cost = 1000;\n            // TL (0,0): walk down tr, right tc. Cost: tr + tc\n            if (tr + tc < best_corner_cost) { best_corner_cost = tr + tc; best_corner = 0; }\n            // TR (0,19): down tr, left (19-tc)\n            if (tr + (MAXC - tc) < best_corner_cost) { best_corner_cost = tr + (MAXC - tc); best_corner = 1; }\n            // BL (19,0): up (19-tr), right tc\n            if ((MAXC - tr) + tc < best_corner_cost) { best_corner_cost = (MAXC - tr) + tc; best_corner = 2; }\n            // BR (19,19): up (19-tr), left (19-tc)\n            if ((MAXC - tr) + (MAXC - tc) < best_corner_cost) { best_corner_cost = (MAXC - tr) + (MAXC - tc); best_corner = 3; }\n            \n            if (best_corner == 0) {\n                add_slide('U');\n                add_slide('L');\n                add_move('D', tr);\n                add_move('R', tc);\n            } else if (best_corner == 1) {\n                add_slide('U');\n                add_slide('R');\n                add_move('D', tr);\n                add_move('L', MAXC - tc);\n            } else if (best_corner == 2) {\n                add_slide('D');\n                add_slide('L');\n                add_move('U', MAXC - tr);\n                add_move('R', tc);\n            } else {\n                add_slide('D');\n                add_slide('R');\n                add_move('U', MAXC - tr);\n                add_move('L', MAXC - tc);\n            }\n        }\n        \n        cr = tr;\n        cc = tc;\n    }\n    \n    for (auto [a, d] : ans) {\n        cout << a << ' ' << d << \"\\n\";\n    }\n    \n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int l, r, b, t;\n    long long area() const { return 1LL * (r - l) * (t - b); }\n};\n\nint n;\nvector<int> X, Y, R;\nvector<Rect> rects; // current rectangles for leaves\n\nstruct Node {\n    bool leaf = false;\n    int idx = -1;          // if leaf\n    bool vert = false;     // if internal: true=vertical cut\n    int child[2] = {-1, -1}; // left/bottom and right/top children\n    int cut = 0;           // cut coordinate (x if vert, y if !vert)\n    // static bounds of points inside this subtree\n    int min_x = 10000, max_x = -1;\n    int min_y = 10000, max_y = -1;\n    long long sum_r = 0;\n};\nvector<Node> tree;\nint root;\n\n// build topology and static point bounds, return node id\nint build(vector<int>& ids) {\n    Node node;\n    for (int id : ids) {\n        node.min_x = min(node.min_x, X[id]);\n        node.max_x = max(node.max_x, X[id]);\n        node.min_y = min(node.min_y, Y[id]);\n        node.max_y = max(node.max_y, Y[id]);\n        node.sum_r += R[id];\n    }\n    if ((int)ids.size() == 1) {\n        node.leaf = true;\n        node.idx = ids[0];\n        int id = (int)tree.size();\n        tree.push_back(node);\n        return id;\n    }\n    // decide orientation based on spread of points\n    bool vert = (node.max_x - node.min_x) >= (node.max_y - node.min_y);\n    if (vert) {\n        sort(ids.begin(), ids.end(), [&](int a, int b){ return X[a] < X[b]; });\n    } else {\n        sort(ids.begin(), ids.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n    }\n    // split by area (balanced)\n    long long half = node.sum_r / 2;\n    long long cur = 0;\n    int split_pos = 1;\n    for (int i = 0; i < (int)ids.size(); ++i) {\n        cur += R[ids[i]];\n        if (cur >= half && i + 1 < (int)ids.size()) {\n            split_pos = i + 1;\n            break;\n        }\n    }\n    vector<int> left_ids(ids.begin(), ids.begin() + split_pos);\n    vector<int> right_ids(ids.begin() + split_pos, ids.end());\n    node.vert = vert;\n    int node_id = (int)tree.size();\n    tree.push_back(node); // placeholder to get index\n    int lch = build(left_ids);\n    int rch = build(right_ids);\n    tree[node_id].child[0] = lch;\n    tree[node_id].child[1] = rch;\n    return node_id;\n}\n\n// current bounding boxes for internal nodes during recalc\nvector<int> cur_x1, cur_y1, cur_x2, cur_y2;\n\n// recompute rects from cuts, also fills cur_x/y for internal nodes\n// returns total score sum\ndouble recalc(int v, int x1, int y1, int x2, int y2) {\n    cur_x1[v] = x1; cur_y1[v] = y1; cur_x2[v] = x2; cur_y2[v] = y2;\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        long long s = rects[node.idx].area();\n        long long r = R[node.idx];\n        double ratio = (s <= r) ? (double)s / r : (double)r / s;\n        double d = 1.0 - ratio;\n        return 1.0 - d * d;\n    }\n    double sum = 0;\n    if (node.vert) {\n        // left: [x1, cut), right: [cut, x2)\n        sum += recalc(node.child[0], x1, y1, node.cut, y2);\n        sum += recalc(node.child[1], node.cut, y1, x2, y2);\n    } else {\n        // bottom: [y1, cut), top: [cut, y2)\n        sum += recalc(node.child[0], x1, y1, x2, node.cut);\n        sum += recalc(node.child[1], x1, node.cut, x2, y2);\n    }\n    return sum;\n}\n\n// initialize cuts to be area-proportional (clamped to valid range)\nvoid init_cuts(int v, int x1, int y1, int x2, int y2) {\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        return;\n    }\n    int lch = node.child[0], rch = node.child[1];\n    if (node.vert) {\n        int lo = max(x1, tree[lch].max_x + 1);\n        int hi = min(x2, tree[rch].min_x);\n        if (lo > hi) lo = hi = (x1 + x2) / 2; // fallback, should not happen\n        // ideal cut based on area proportion\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(x1 + (x2 - x1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, node.cut, y2);\n        init_cuts(rch, node.cut, y1, x2, y2);\n    } else {\n        int lo = max(y1, tree[lch].max_y + 1);\n        int hi = min(y2, tree[rch].min_y);\n        if (lo > hi) lo = hi = (y1 + y2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(y1 + (y2 - y1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, x2, node.cut);\n        init_cuts(rch, x1, node.cut, x2, y2);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---------- input ----------\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; ++i) cin >> X[i] >> Y[i] >> R[i];\n    rects.resize(n);\n    \n    // ---------- build tree ----------\n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    tree.reserve(2 * n);\n    cur_x1.resize(2 * n);\n    cur_y1.resize(2 * n);\n    cur_x2.resize(2 * n);\n    cur_y2.resize(2 * n);\n    root = build(ids);\n    \n    // ---------- initial layout ----------\n    init_cuts(root, 0, 0, 10000, 10000);\n    double current_score = recalc(root, 0, 0, 10000, 10000);\n    \n    // ---------- Simulated Annealing ----------\n    mt19937 rng(1234567);\n    uniform_int_distribution<int> dist_node(0, (int)tree.size() - 1);\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    \n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n    long long iter = 0;\n    \n    // Precompute list of internal nodes for faster sampling\n    vector<int> internal_nodes;\n    for (int i = 0; i < (int)tree.size(); ++i) if (!tree[i].leaf) internal_nodes.push_back(i);\n    uniform_int_distribution<int> dist_internal(0, (int)internal_nodes.size() - 1);\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        ++iter;\n        // Temperature: high at start, low at end\n        double progress = elapsed / TIME_LIMIT;\n        double T = pow(0.001, progress); // from 1.0 down to 0.001\n        \n        // pick random internal node\n        int v = internal_nodes[dist_internal(rng)];\n        Node& node = tree[v];\n        \n        // get current bounds\n        int x1 = cur_x1[v], y1 = cur_y1[v], x2 = cur_x2[v], y2 = cur_y2[v];\n        int lo, hi;\n        if (node.vert) {\n            lo = max(x1, tree[node.child[0]].max_x + 1);\n            hi = min(x2, tree[node.child[1]].min_x);\n        } else {\n            lo = max(y1, tree[node.child[0]].max_y + 1);\n            hi = min(y2, tree[node.child[1]].min_y);\n        }\n        if (lo >= hi) continue; // cannot move\n        \n        int old_cut = node.cut;\n        int new_cut;\n        \n        // Move strategy: 50% small step, 50% random jump\n        if (dist_real(rng) < 0.5) {\n            int max_step = max(1, (int)(T * 200));\n            uniform_int_distribution<int> d(-max_step, max_step);\n            new_cut = old_cut + d(rng);\n        } else {\n            uniform_int_distribution<int> d(lo, hi);\n            new_cut = d(rng);\n        }\n        new_cut = clamp(new_cut, lo, hi);\n        if (new_cut == old_cut) continue;\n        \n        // apply change\n        node.cut = new_cut;\n        double new_score = recalc(root, 0, 0, 10000, 10000);\n        double delta = new_score - current_score;\n        \n        if (delta > 0 || exp(delta / T) > dist_real(rng)) {\n            current_score = new_score; // accept\n        } else {\n            node.cut = old_cut; // reject, revert and recompute\n            recalc(root, 0, 0, 10000, 10000);\n        }\n    }\n    \n    // ---------- output ----------\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].l << ' ' << rects[i].b << ' '\n             << rects[i].r << ' ' << rects[i].t << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int H = 50, W = 50;\n    int si, sj;\n    vector<vector<int>> tile;\n    vector<vector<int>> val;\n    int M; // number of tiles\n    \n    const vector<int> di = {-1, 1, 0, 0};\n    const vector<int> dj = {0, 0, -1, 1};\n    const vector<char> dc = {'U', 'D', 'L', 'R'};\n    \n    // Calculate score of a path for validation/comparison\n    long long calc_score(const string& path) {\n        vector<bool> vis(M, false);\n        int i = si, j = sj;\n        vis[tile[i][j]] = true;\n        long long score = val[i][j];\n        \n        for (char c : path) {\n            int d = 0;\n            if (c == 'U') d = 0;\n            else if (c == 'D') d = 1;\n            else if (c == 'L') d = 2;\n            else if (c == 'R') d = 3;\n            else return -1;\n            \n            int ni = i + di[d];\n            int nj = j + dj[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) return -1;\n            int nt = tile[ni][nj];\n            if (vis[nt]) return -1; // visited same tile\n            \n            i = ni; j = nj;\n            vis[nt] = true;\n            score += val[i][j];\n        }\n        return score;\n    }\n    \n    // Greedy walk with specified heuristic type\n    string greedy_walk(int heuristic_type) {\n        vector<bool> visited(M, false);\n        int i = si, j = sj;\n        visited[tile[i][j]] = true;\n        string path;\n        \n        while (true) {\n            struct Candidate {\n                double score;\n                int dir;\n                int ni, nj;\n                bool operator<(const Candidate& other) const {\n                    return score < other.score; // for max-heap\n                }\n            };\n            vector<Candidate> cand;\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n                int nt = tile[ni][nj];\n                if (visited[nt]) continue;\n                \n                // Calculate degree (number of unvisited adjacent tiles)\n                int degree = 0;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int ni2 = ni + di[d2];\n                    int nj2 = nj + dj[d2];\n                    if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                    if (!visited[tile[ni2][nj2]]) degree++;\n                }\n                \n                double h = 0;\n                if (heuristic_type == 0) {\n                    // Pure value\n                    h = val[ni][nj];\n                } else if (heuristic_type == 1) {\n                    // Value + small degree bonus\n                    h = val[ni][nj] + degree * 10.0;\n                } else if (heuristic_type == 2) {\n                    // Value + large degree bonus\n                    h = val[ni][nj] + degree * 50.0;\n                } else if (heuristic_type == 3) {\n                    // Avoid dead ends strongly\n                    if (degree == 0) h = val[ni][nj] - 1000000.0;\n                    else h = val[ni][nj];\n                } else if (heuristic_type == 4) {\n                    // Lookahead: value + 0.5 * best next value\n                    double best_next = 0;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int ni2 = ni + di[d2];\n                        int nj2 = nj + dj[d2];\n                        if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                        int nt2 = tile[ni2][nj2];\n                        if (nt2 == nt) continue; // same tile, will be visited\n                        if (!visited[nt2]) {\n                            best_next = max(best_next, (double)val[ni2][nj2]);\n                        }\n                    }\n                    h = val[ni][nj] + best_next * 0.5;\n                }\n                cand.push_back({h, d, ni, nj});\n            }\n            \n            if (cand.empty()) break;\n            // Select max\n            auto best = *max_element(cand.begin(), cand.end());\n            \n            // Move\n            i = best.ni;\n            j = best.nj;\n            visited[tile[i][j]] = true;\n            path.push_back(dc[best.dir]);\n        }\n        return path;\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Try different heuristics\n        for (int h = 0; h < 5; ++h) {\n            string path = greedy_walk(h);\n            long long sc = calc_score(path);\n            if (sc > best_score) {\n                best_score = sc;\n                best_path = path;\n            }\n        }\n        return best_path;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Process all test cases until EOF\n    // (Each test case: si sj, then 50x50 tile grid, then 50x50 value grid)\n    while (true) {\n        int si, sj;\n        if (!(cin >> si >> sj)) break;\n        \n        vector<vector<int>> t(50, vector<int>(50));\n        vector<vector<int>> p(50, vector<int>(50));\n        \n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                cin >> p[i][j];\n        \n        Solver solver;\n        solver.si = si;\n        solver.sj = sj;\n        solver.tile = t;\n        solver.val = p;\n        \n        // Determine number of tiles M\n        int max_id = 0;\n        for (int i = 0; i < 50; ++i)\n            for (int j = 0; j < 50; ++j)\n                max_id = max(max_id, t[i][j]);\n        solver.M = max_id + 1;\n        \n        string ans = solver.solve();\n        cout << ans << \"\\n\";\n    }\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    constexpr int N = 30;          // grid size\n    constexpr int Q = 1000;        // number of queries\n    constexpr double LR = 0.3;     // base learning rate\n    constexpr double SIGMA0 = 2000.0; // prior std\u2011dev (\u2248 D_max)\n    constexpr double WMIN = 100.0;\n    constexpr double WMAX = 10000.0;\n    \n    // estimated weights and visit counters\n    double H[N][N - 1];\n    double V[N - 1][N];\n    int    CntH[N][N - 1] = {};\n    int    CntV[N - 1][N] = {};\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            H[i][j] = 5000.0;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            V[i][j] = 5000.0;\n    \n    // random generator for Thompson sampling\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    std::normal_distribution<double> gauss(0.0, 1.0);\n    \n    // temporary sampled weights for the current query\n    double sampleH[N][N - 1];\n    double sampleV[N - 1][N];\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    for (int q = 0; q < Q; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n        \n        /* -------------------------------------------------------------\n           1. Thompson sampling: draw a perturbed weight for every edge.\n           The perturbation scales as 1/sqrt(visit_count), i.e. high\n           uncertainty for rarely used edges.\n           ------------------------------------------------------------- */\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                double sigma = SIGMA0 / sqrt((double)CntH[i][j] + 1.0);\n                double w = H[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sampleH[i][j] = w;\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double sigma = SIGMA0 / sqrt((double)CntV[i][j] + 1.0);\n                double w = V[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sampleV[i][j] = w;\n            }\n        }\n        \n        /* -------------------------------------------------------------\n           2. Shortest path on the sampled weights (Dijkstra).\n           ------------------------------------------------------------- */\n        double dist[N][N];\n        int    par_i[N][N];\n        int    par_j[N][N];\n        char   par_dir[N][N];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = 1e100;\n        \n        using State = tuple<double, int, int>;\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[si][sj] = 0.0;\n        pq.emplace(0.0, si, sj);\n        \n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j] + 1e-9) continue;\n            if (i == ti && j == tj) break;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                double w;\n                if (dir == 0) w = sampleV[i - 1][j];\n                else if (dir == 1) w = sampleV[i][j];\n                else if (dir == 2) w = sampleH[i][j - 1];\n                else               w = sampleH[i][j];\n                if (dist[ni][nj] > d + w) {\n                    dist[ni][nj] = d + w;\n                    par_i[ni][nj] = i;\n                    par_j[ni][nj] = j;\n                    par_dir[ni][nj] = dc[dir];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n        \n        // reconstruct path\n        string path;\n        int ci = ti, cj = tj;\n        while (ci != si || cj != sj) {\n            char c = par_dir[ci][cj];\n            path.push_back(c);\n            int pi = par_i[ci][cj];\n            int pj = par_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        \n        cout << path << '\\n';\n        cout.flush();\n        \n        /* -------------------------------------------------------------\n           3. Receive noisy observation and update estimates.\n           ------------------------------------------------------------- */\n        long long obs_in;\n        cin >> obs_in;\n        double obs = static_cast<double>(obs_in);\n        \n        // compute predicted length (using the current means, not the samples)\n        double lenEst = 0.0;\n        ci = si; cj = sj;\n        struct EdgeRef { char type; int i; int j; };\n        vector<EdgeRef> edges;\n        edges.reserve(path.size());\n        for (char c : path) {\n            if (c == 'U') {\n                lenEst += V[ci - 1][cj];\n                edges.push_back({'V', ci - 1, cj});\n                --ci;\n            } else if (c == 'D') {\n                lenEst += V[ci][cj];\n                edges.push_back({'V', ci, cj});\n                ++ci;\n            } else if (c == 'L') {\n                lenEst += H[ci][cj - 1];\n                edges.push_back({'H', ci, cj - 1});\n                --cj;\n            } else { // 'R'\n                lenEst += H[ci][cj];\n                edges.push_back({'H', ci, cj});\n                ++cj;\n            }\n        }\n        \n        double err = obs - lenEst;               // prediction error\n        int m = static_cast<int>(edges.size());  // path length in edges\n        \n        // SGD with per\u2011edge step = LR / (m * sqrt(cnt+1))\n        for (const auto &e : edges) {\n            double *wp;\n            int    *cp;\n            if (e.type == 'H') {\n                wp = &H[e.i][e.j];\n                cp = &CntH[e.i][e.j];\n            } else {\n                wp = &V[e.i][e.j];\n                cp = &CntV[e.i][e.j];\n            }\n            double step = LR * err / (m * sqrt(static_cast<double>(*cp) + 1.0));\n            *wp += step;\n            if (*wp < WMIN) *wp = WMIN;\n            if (*wp > WMAX) *wp = WMAX;\n            ++(*cp);\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int str_id;\n    uint8_t len;\n};\n\nstruct Ref {\n    int pid;\n    uint8_t req;          // 0 \u2026 7  (A \u2026 H)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;                 // Fixed by problem statement\n    int N_input, M;\n    if (!(cin >> N_input >> M)) return 0;\n    // N_input is guaranteed to be 20, but we use the const N for safety\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) cin >> strs[i];\n\n    auto ch2i = [](char c)->int{ return c - 'A'; };   // 'A'..'H' -> 0..7\n\n    const int C = N * N;                 // number of cells\n    vector<vector<Ref>> cell_refs(C);    // reverse index\n    vector<Placement> plc;               // all placements\n    plc.reserve(M * 2 * N * N);\n\n    /* -----------------------------------------------------------\n       generate all placements\n       ----------------------------------------------------------- */\n    for (int s = 0; s < M; ++s) {\n        const string &st = strs[s];\n        int L = (int)st.size();\n        // horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    int cid = r * N + cc;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n        // vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int rr = (r + p) % N;\n                    int cid = rr * N + c;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n    }\n\n    const int P = (int)plc.size();\n    vector<uint8_t> counter(P, 0);\n    vector<int> sat_cnt(M, 0);\n    int total_sat = 0;\n\n    /* -----------------------------------------------------------\n       random initial grid (only letters, 0..7)\n       ----------------------------------------------------------- */\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    vector<uint8_t> grid(C);\n    for (int i = 0; i < C; ++i) grid[i] = (uint8_t)(rng() & 7);\n\n    /* initial counting */\n    for (int cid = 0; cid < C; ++cid) {\n        uint8_t v = grid[cid];\n        for (const auto &rf : cell_refs[cid]) {\n            if (rf.req == v) ++counter[rf.pid];\n        }\n    }\n    for (int pid = 0; pid < P; ++pid) {\n        if (counter[pid] == plc[pid].len) {\n            ++sat_cnt[plc[pid].str_id];\n        }\n    }\n    for (int s = 0; s < M; ++s) if (sat_cnt[s] > 0) ++total_sat;\n\n    /* -----------------------------------------------------------\n       helper: apply change of one cell (old_val -> new_val)\n       updates counter[], sat_cnt[] and total_sat\n       ----------------------------------------------------------- */\n    auto apply_change = [&](int cid, uint8_t old_val, uint8_t new_val) {\n        if (old_val == new_val) return;\n        for (const auto &rf : cell_refs[cid]) {\n            bool old_match = (old_val == rf.req);\n            bool new_match = (new_val == rf.req);\n            if (old_match == new_match) continue;   // nothing changes\n\n            uint8_t &cnt = counter[rf.pid];\n            uint8_t len  = plc[rf.pid].len;\n            if (old_match) {                 // we lose one matching cell\n                --cnt;\n                if (cnt == len - 1) {        // was satisfied, now not\n                    int sid = plc[rf.pid].str_id;\n                    if (--sat_cnt[sid] == 0) --total_sat;\n                }\n            } else {                         // we gain one matching cell\n                ++cnt;\n                if (cnt == len) {            // becomes satisfied\n                    int sid = plc[rf.pid].str_id;\n                    if (sat_cnt[sid]++ == 0) ++total_sat;\n                }\n            }\n        }\n    };\n\n    /* -----------------------------------------------------------\n       Simulated Annealing\n       ----------------------------------------------------------- */\n    const double TIME_LIMIT = 2.5;            // seconds\n    auto start = chrono::steady_clock::now();\n    double temp = 0.8;                        // initial temperature\n    int iter = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        ++iter;\n        if ((iter & 127) == 0) temp *= 0.999; // slow cooling\n\n        int cid = (int)(rng() % C);\n        uint8_t oldv = grid[cid];\n        uint8_t newv = (uint8_t)(rng() & 7);\n        if (oldv == newv) continue;\n\n        int before = total_sat;\n        apply_change(cid, oldv, newv);\n        int after = total_sat;\n        int delta = after - before;\n\n        if (delta < 0) {\n            double accept_prob = exp(delta / temp);\n            if (uniform_real_distribution<double>(0.0, 1.0)(rng) > accept_prob) {\n                // reject: revert\n                apply_change(cid, newv, oldv);\n                // grid[cid] stays oldv\n                continue;\n            }\n        }\n        grid[cid] = newv;   // accept\n    }\n\n    /* -----------------------------------------------------------\n       Phase 2: try to turn cells into '.' (value 8) without breaking\n       ----------------------------------------------------------- */\n    if (total_sat == M) {\n        vector<int> order(C);\n        iota(order.begin(), order.end(), 0);\n        for (int rep = 0; rep < 3; ++rep) {\n            shuffle(order.begin(), order.end(), rng);\n            for (int cid : order) {\n                if (grid[cid] == 8) continue;          // already dot\n                uint8_t oldv = grid[cid];\n                apply_change(cid, oldv, 8);\n                if (total_sat == M) {\n                    grid[cid] = 8;                      // keep dot\n                } else {\n                    apply_change(cid, 8, oldv);         // revert\n                }\n            }\n        }\n    }\n\n    /* -----------------------------------------------------------\n       Output\n       ----------------------------------------------------------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        line.reserve(N);\n        for (int c = 0; c < N; ++c) {\n            int v = grid[r * N + c];\n            if (v == 8) line.push_back('.');\n            else        line.push_back(char('A' + v));\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastBitset {\n    static const int MAXR = 5000;\n    static const int WORDS = (MAXR + 63) / 64;\n    uint64_t w[WORDS];\n    FastBitset() { memset(w, 0, sizeof(w)); }\n    void set(int i) { w[i>>6] |= 1ULL << (i&63); }\n    bool test(int i) const { return (w[i>>6] >> (i&63)) & 1ULL; }\n    void clear() { memset(w, 0, sizeof(w)); }\n    int count() const {\n        int s = 0;\n        for (int i = 0; i < WORDS; i++) s += __builtin_popcountll(w[i]);\n        return s;\n    }\n    FastBitset operator&(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] & o.w[i];\n        return r;\n    }\n    FastBitset operator|(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] | o.w[i];\n        return r;\n    }\n    FastBitset operator~() const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = ~w[i];\n        return r;\n    }\n    FastBitset& operator&=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] &= o.w[i];\n        return *this;\n    }\n    FastBitset& operator|=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] |= o.w[i];\n        return *this;\n    }\n    bool any() const {\n        for (int i = 0; i < WORDS; i++) if (w[i]) return true;\n        return false;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = cells.size();\n                cells.emplace_back(i, j);\n            }\n        }\n    }\n    int R = cells.size();\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    // Horizontal and vertical segment IDs and coverage bitsets\n    vector<vector<int>> h_id(N, vector<int>(N, -1));\n    vector<vector<int>> v_id(N, vector<int>(N, -1));\n    vector<FastBitset> h_cover, v_cover;\n    \n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != '#') {\n                int l = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int r = j - 1;\n                FastBitset bs;\n                int sid = h_cover.size();\n                for (int k = l; k <= r; k++) {\n                    h_id[i][k] = sid;\n                    bs.set(id[i][k]);\n                }\n                h_cover.push_back(bs);\n            } else {\n                j++;\n            }\n        }\n    }\n    \n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != '#') {\n                int t = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int b = i - 1;\n                FastBitset bs;\n                int sid = v_cover.size();\n                for (int k = t; k <= b; k++) {\n                    v_id[k][j] = sid;\n                    bs.set(id[k][j]);\n                }\n                v_cover.push_back(bs);\n            } else {\n                i++;\n            }\n        }\n    }\n    \n    // Coverage for each cell\n    vector<FastBitset> cell_cover(R);\n    for (int idx = 0; idx < R; idx++) {\n        auto [i, j] = cells[idx];\n        cell_cover[idx] = h_cover[h_id[i][j]] | v_cover[v_id[i][j]];\n    }\n    \n    int start_idx = id[si][sj];\n    \n    // Greedy set cover\n    FastBitset uncovered;\n    for (int i = 0; i < R; i++) uncovered.set(i);\n    uncovered &= ~cell_cover[start_idx]; // start position is already visible\n    \n    vector<int> selected;\n    \n    // Pre-calculate which cells have any coverage of remaining uncovered cells\n    while (uncovered.any()) {\n        int best = -1;\n        int best_cnt = -1;\n        \n        // Find cell with maximum coverage of uncovered\n        for (int c = 0; c < R; c++) {\n            // Quick check: any overlap?\n            bool has_overlap = false;\n            for (int w = 0; w < FastBitset::WORDS; w++) {\n                if (cell_cover[c].w[w] & uncovered.w[w]) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            if (!has_overlap) continue;\n            \n            FastBitset inter = cell_cover[c] & uncovered;\n            int cnt = inter.count();\n            if (cnt > best_cnt) {\n                best_cnt = cnt;\n                best = c;\n            }\n        }\n        \n        if (best == -1) break; // Should not happen if roads are connected properly\n        selected.push_back(best);\n        uncovered &= ~cell_cover[best];\n    }\n    \n    // Build point list for TSP: start + selected\n    vector<int> points;\n    points.reserve(selected.size() + 1);\n    points.push_back(start_idx);\n    for (int idx : selected) points.push_back(idx);\n    int K = points.size();\n    \n    // Map from cell id to point index (0..K-1) or -1\n    vector<int> node_to_point(R, -1);\n    for (int i = 0; i < K; i++) node_to_point[points[i]] = i;\n    \n    const int INF = 1e9;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // Distance matrix between points\n    vector<vector<int>> dmat(K, vector<int>(K, INF));\n    \n    // Dijkstra from each point, stopping when all other points are settled\n    for (int pi = 0; pi < K; pi++) {\n        int src = points[pi];\n        vector<int> dist(R, INF);\n        dist[src] = 0;\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.emplace(0, src);\n        int settled = 0;\n        \n        while (!pq.empty() && settled < K) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (node_to_point[u] != -1) {\n                settled++;\n            }\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        for (int pj = 0; pj < K; pj++) {\n            dmat[pi][pj] = dist[points[pj]];\n        }\n    }\n    \n    // TSP: Nearest neighbor initialization\n    vector<int> tour;\n    tour.reserve(K);\n    vector<bool> used(K, false);\n    tour.push_back(0);\n    used[0] = true;\n    int cur = 0;\n    for (int iter = 1; iter < K; iter++) {\n        int nxt = -1;\n        int best_d = INF;\n        for (int i = 0; i < K; i++) if (!used[i]) {\n            if (dmat[cur][i] < best_d) {\n                best_d = dmat[cur][i];\n                nxt = i;\n            }\n        }\n        if (nxt == -1) break;\n        tour.push_back(nxt);\n        used[nxt] = true;\n        cur = nxt;\n    }\n    \n    // 2-opt improvement\n    bool improved = true;\n    int max_iter = 1000;\n    int iter_cnt = 0;\n    while (improved && iter_cnt < max_iter) {\n        improved = false;\n        iter_cnt++;\n        for (int i = 0; i < K; i++) {\n            for (int j = i + 2; j < K; j++) {\n                int a = tour[i];\n                int b = tour[(i+1)%K];\n                int c = tour[j];\n                int d = tour[(j+1)%K];\n                \n                int cur_len = dmat[a][b] + dmat[c][d];\n                int new_len = dmat[a][c] + dmat[b][d];\n                \n                if (new_len < cur_len) {\n                    // Reverse segment [i+1, j]\n                    int l = i + 1, r = j;\n                    while (l < r) {\n                        swap(tour[l], tour[r]);\n                        l++; r--;\n                    }\n                    improved = true;\n                }\n            }\n        }\n    }\n    \n    // Build route string\n    string route;\n    route.reserve(N * N * 4); // rough estimate\n    \n    for (int ii = 0; ii < K; ii++) {\n        int from_idx = points[tour[ii]];\n        int to_idx = points[tour[(ii+1)%K]];\n        if (from_idx == to_idx) continue;\n        \n        // Dijkstra to get path\n        vector<int> dist(R, INF);\n        vector<int> prev(R, -1);\n        vector<int> prev_dir(R, -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[from_idx] = 0;\n        pq.emplace(0, from_idx);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == to_idx) break;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_dir[v] = dir;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        // Reconstruct path\n        vector<int> dirs;\n        int cur_node = to_idx;\n        while (cur_node != from_idx) {\n            dirs.push_back(prev_dir[cur_node]);\n            cur_node = prev[cur_node];\n        }\n        reverse(dirs.begin(), dirs.end());\n        for (int d : dirs) {\n            if (d == 0) route += 'U';\n            else if (d == 1) route += 'D';\n            else if (d == 2) route += 'L';\n            else route += 'R';\n        }\n    }\n    \n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if(!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> sum_d(N, 0);\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<K; j++) {\n            cin >> d[i][j];\n            sum_d[i] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> adj(N);\n    vector<vector<int>> radj(N);\n    vector<int> indeg(N, 0);\n    for(int i=0; i<R; i++) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n        indeg[v]++;\n    }\n    \n    // State\n    vector<vector<double>> est_s(M, vector<double>(K, 35.0)); // Conservative initial guess\n    vector<vector<double>> lb(M, vector<double>(K, 0.0));     // Hard lower bounds\n    vector<int> num_obs(M, 0);\n    \n    vector<int> indeg_cur = indeg;\n    vector<int> task_state(N, 0); // 0:not ready, 1:ready, 2:running, 3:done\n    vector<int> member_task(M, -1);\n    vector<int> task_start_day(N, -1);\n    \n    int day = 0;\n    const int MAX_DAY = 2000;\n    \n    while(day < MAX_DAY) {\n        ++day;\n        \n        // Update available tasks\n        vector<int> available;\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 0 && indeg_cur[i] == 0) {\n                task_state[i] = 1;\n            }\n            if(task_state[i] == 1) available.push_back(i);\n        }\n        \n        // Find free members\n        vector<int> free_members;\n        for(int j=0; j<M; j++) if(member_task[j] == -1) free_members.push_back(j);\n        \n        if(!available.empty() && !free_members.empty()) {\n            // Compute estimated times and critical path info\n            vector<double> min_time(N, 1.0), second_min_time(N, 1e18);\n            vector<vector<double>> est_time(M, vector<double>(N, 1.0));\n            \n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                double best = 1e18, second = 1e18;\n                for(int j=0; j<M; j++) {\n                    double w = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > est_s[j][k]) w += d[i][k] - est_s[j][k];\n                    double t = (w <= 0) ? 1.0 : max(1.0, w);\n                    est_time[j][i] = t;\n                    if(t < best) { second = best; best = t; }\n                    else if(t < second) { second = t; }\n                }\n                min_time[i] = best;\n                second_min_time[i] = (second < 1e17) ? second : best; // if M=1, use best\n            }\n            \n            // DP for critical path (longest path to end)\n            vector<double> dp(N, -1.0);\n            function<double(int)> solve_dp = [&](int u) -> double {\n                if(task_state[u] == 3) return 0.0;\n                if(dp[u] >= 0) return dp[u];\n                double max_next = 0.0;\n                for(int v : adj[u]) if(task_state[v] != 3) {\n                    max_next = max(max_next, solve_dp(v));\n                }\n                dp[u] = min_time[u] + max_next;\n                return dp[u];\n            };\n            \n            for(int i : available) solve_dp(i);\n            \n            // Calculate priority: critical path + bottleneck penalty\n            vector<double> priority(N, 0.0);\n            for(int i : available) {\n                double bottleneck = second_min_time[i] - min_time[i];\n                priority[i] = dp[i] + 0.5 * bottleneck;\n            }\n            \n            sort(available.begin(), available.end(), [&](int a, int b) {\n                return priority[a] > priority[b];\n            });\n            \n            // Greedy assignment with matching\n            vector<bool> used(M, false);\n            vector<pair<int,int>> assignments;\n            \n            for(int task_id : available) {\n                if(assignments.size() >= free_members.size()) break;\n                \n                int best_j = -1;\n                double best_t = 1e18;\n                for(int j : free_members) {\n                    if(used[j]) continue;\n                    double t = est_time[j][task_id];\n                    // Small tie-breaker to favor members with fewer assignments (load balancing)\n                    if(t < best_t - 1e-9 || (abs(t - best_t) < 1e-9 && num_obs[j] < num_obs[best_j])) {\n                        best_t = t;\n                        best_j = j;\n                    }\n                }\n                if(best_j != -1) {\n                    assignments.emplace_back(best_j, task_id);\n                    used[best_j] = true;\n                }\n            }\n            \n            cout << assignments.size();\n            for(auto& [j, i] : assignments) {\n                cout << \" \" << j+1 << \" \" << i+1;\n                member_task[j] = i;\n                task_state[i] = 2;\n                task_start_day[i] = day;\n            }\n            cout << endl;\n        } else {\n            cout << 0 << endl;\n        }\n        cout.flush();\n        \n        // Read completions\n        int n_comp;\n        cin >> n_comp;\n        if(n_comp == -1) break;\n        \n        vector<int> completed(n_comp);\n        for(int i=0; i<n_comp; i++) {\n            cin >> completed[i];\n            completed[i]--;\n        }\n        \n        // Process completions and update skills\n        for(int j : completed) {\n            int task_id = member_task[j];\n            if(task_id == -1) continue;\n            \n            int duration = day - task_start_day[task_id] + 1;\n            double obs_w = max(0, duration - 1);\n            \n            num_obs[j]++;\n            \n            // Update lower bounds: s_k >= d_k - obs_w\n            for(int k=0; k<K; k++) {\n                lb[j][k] = max(lb[j][k], (double)d[task_id][k] - obs_w);\n                if(obs_w == 0) lb[j][k] = max(lb[j][k], (double)d[task_id][k]);\n            }\n            \n            // Predicted deficiency\n            double pred_w = 0;\n            vector<int> active_dims;\n            for(int k=0; k<K; k++) {\n                if(d[task_id][k] > est_s[j][k]) {\n                    pred_w += d[task_id][k] - est_s[j][k];\n                    active_dims.push_back(k);\n                }\n            }\n            \n            // Gradient update\n            if(obs_w == 0) {\n                for(int k=0; k<K; k++) est_s[j][k] = max(est_s[j][k], (double)d[task_id][k]);\n            } else if(active_dims.empty()) {\n                // pred_w = 0 but obs_w > 0: distribute deficiency\n                double sumd = sum_d[task_id];\n                if(sumd > 0) {\n                    for(int k=0; k<K; k++) {\n                        double reduce = obs_w * d[task_id][k] / sumd;\n                        est_s[j][k] = max(lb[j][k], est_s[j][k] - reduce);\n                    }\n                }\n            } else {\n                double diff = obs_w - pred_w; // positive means we overestimated skills\n                double lr = 0.3; // Conservative learning rate\n                for(int k : active_dims) {\n                    double contrib = d[task_id][k] - est_s[j][k];\n                    double delta = diff * (contrib / pred_w) * lr;\n                    est_s[j][k] -= delta; // decrease if diff>0 (observed slower than predicted)\n                }\n                // Clamp to lower bounds\n                for(int k=0; k<K; k++) est_s[j][k] = max(est_s[j][k], lb[j][k]);\n            }\n            \n            // Mark done\n            task_state[task_id] = 3;\n            member_task[j] = -1;\n            for(int v : adj[task_id]) indeg_cur[v]--;\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double now() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 1000;\n    const int OFFICE = 0;\n    const int OFFICE_X = 400, OFFICE_Y = 400;\n    const int MAX_P = 2 * N + 1; // 0..2000\n    \n    vector<int> a(N), b(N), c(N), d(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> a[i] >> b[i] >> c[i] >> d[i];\n    }\n    \n    // Coordinate compression: 0 = office, 1..N = pickup, N+1..2N = delivery\n    vector<int> xs(MAX_P), ys(MAX_P);\n    xs[OFFICE] = OFFICE_X; ys[OFFICE] = OFFICE_Y;\n    for (int i = 0; i < N; ++i) {\n        xs[1 + i] = a[i]; ys[1 + i] = b[i];\n        xs[1 + N + i] = c[i]; ys[1 + N + i] = d[i];\n    }\n    \n    // Flat distance matrix: dist[i * MAX_P + j]\n    vector<int> dist(MAX_P * MAX_P);\n    auto D = [&](int i, int j) -> int& { return dist[i * MAX_P + j]; };\n    for (int i = 0; i < MAX_P; ++i) {\n        for (int j = 0; j < MAX_P; ++j) {\n            D(i, j) = abs(xs[i] - xs[j]) + abs(ys[i] - ys[j]);\n        }\n    }\n    \n    Timer timer;\n    \n    // ---------- Greedy Insertion ----------\n    vector<int> route;\n    route.reserve(105);\n    route.push_back(OFFICE);\n    route.push_back(OFFICE);\n    vector<int> selected; selected.reserve(50);\n    vector<bool> used(N, false);\n    \n    for (int iter = 0; iter < 50; ++iter) {\n        int m = (int)route.size();\n        int best_o = -1, best_i = -1, best_j = -1;\n        int best_delta = 1e9;\n        \n        for (int o = 0; o < N; ++o) if (!used[o]) {\n            int p = 1 + o;\n            int del = 1 + N + o;\n            for (int i = 0; i < m - 1; ++i) {\n                int ri = route[i];\n                int ri1 = route[i+1];\n                int dpi = -D(ri, ri1);\n                for (int j = i; j < m - 1; ++j) {\n                    int rj = route[j];\n                    int rj1 = route[j+1];\n                    int delta;\n                    if (i == j) {\n                        delta = dpi + D(ri, p) + D(p, del) + D(del, rj1);\n                    } else {\n                        int dpj = -D(rj, rj1);\n                        delta = dpi + dpj + D(ri, p) + D(p, ri1) + D(rj, del) + D(del, rj1);\n                    }\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_o = o;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        int p = 1 + best_o;\n        int del = 1 + N + best_o;\n        if (best_i == best_j) {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_i + 2, del);\n        } else {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_j + 2, del);\n        }\n        selected.push_back(best_o);\n        used[best_o] = true;\n    }\n    \n    // Prepare for SA: cur sequence and position array\n    vector<int> cur = route; // size 102\n    const int LEN = 102;\n    const int MIDDLE = 100; // indices 1..100 are movable\n    \n    array<int, MAX_P> pos;\n    for (int i = 0; i < LEN; ++i) pos[cur[i]] = i;\n    \n    auto calc_full = [&](const vector<int>& seq) {\n        int s = 0;\n        for (int i = 0; i + 1 < LEN; ++i) s += D(seq[i], seq[i+1]);\n        return s;\n    };\n    int cur_cost = calc_full(cur);\n    int best_cost = cur_cost;\n    vector<int> best_seq = cur;\n    \n    // Type: 0 = pickup, 1 = delivery\n    auto is_pickup = [&](int idx)->bool{ return idx >= 1 && idx <= N; };\n    auto is_delivery = [&](int idx)->bool{ return idx > N; };\n    \n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(1, 100); // movable range\n    \n    // Precompute exp table for fast annealing\n    const int EXP_TABLE_SIZE = 1000;\n    vector<double> exp_table(EXP_TABLE_SIZE);\n    for (int i = 0; i < EXP_TABLE_SIZE; ++i) {\n        double t = (double)i / 100.0; // delta / T\n        exp_table[i] = exp(-t);\n    }\n    \n    double T_start = 1000.0;\n    double T_end = 0.1;\n    double time_limit = 1.98 - timer.now(); // remaining time for SA\n    if (time_limit < 0.1) time_limit = 0.1;\n    double start_time = timer.now();\n    \n    long long iter = 0;\n    while (timer.now() - start_time < time_limit) {\n        double elapsed = timer.now() - start_time;\n        double progress = elapsed / time_limit;\n        double T = T_start * pow(T_end / T_start, progress);\n        \n        int type = rng() & 1; // 0 = swap, 1 = 2-opt\n        bool accept = false;\n        int delta = 0;\n        \n        if (type == 0) {\n            // Swap\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l == r) continue;\n            if (l > r) swap(l, r);\n            \n            int u = cur[l];\n            int v = cur[r];\n            \n            // Validity check: O(1)\n            bool ok = true;\n            if (is_pickup(u)) {\n                if (pos[u + N] <= r) ok = false; // delivery must be after new pos r\n            } else {\n                if (pos[u - N] >= r) ok = false; // pickup must be before new pos r\n            }\n            if (ok && is_pickup(v)) {\n                if (pos[v + N] <= l) ok = false;\n            } else if (ok) {\n                if (pos[v - N] >= l) ok = false;\n            }\n            if (!ok) continue;\n            \n            // Delta calculation\n            int ul = cur[l-1];\n            int ur = cur[l+1];\n            int vl = cur[r-1];\n            int vr = cur[r+1];\n            \n            if (r == l + 1) {\n                // Adjacent: ... ul, u, v, vr ...\n                delta = -D(ul, u) - D(u, v) - D(v, vr)\n                        + D(ul, v) + D(v, u) + D(u, vr);\n            } else {\n                delta = -D(ul, u) - D(u, ur) - D(vl, v) - D(v, vr)\n                        + D(ul, v) + D(v, ur) + D(vl, u) + D(u, vr);\n            }\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    if (uniform_real_distribution<double>(0,1)(rng) >= 0) continue; // reject with high probability\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                swap(cur[l], cur[r]);\n                pos[u] = r;\n                pos[v] = l;\n            }\n        } else {\n            // 2-opt reverse [l, r]\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l >= r) continue;\n            \n            // Validity: no order has both ends inside [l, r]\n            bool ok = true;\n            for (int o : selected) {\n                int p = 1 + o;\n                int d = 1 + N + o;\n                if (l <= pos[p] && pos[p] <= r && l <= pos[d] && pos[d] <= r) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            \n            int before = cur[l-1];\n            int after = cur[r+1];\n            int left = cur[l];\n            int right = cur[r];\n            delta = -D(before, left) - D(right, after) + D(before, right) + D(left, after);\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    continue;\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n                for (int i = l; i <= r; ++i) pos[cur[i]] = i;\n            }\n        }\n        \n        if (accept) {\n            cur_cost += delta;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_seq = cur;\n            }\n        }\n        ++iter;\n    }\n    \n    // ---------- Output ----------\n    cout << 50;\n    for (int o : selected) cout << ' ' << (o + 1);\n    cout << '\\n';\n    \n    cout << best_seq.size();\n    for (int idx : best_seq) {\n        cout << ' ' << xs[idx] << ' ' << ys[idx];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        r.assign(n, 0);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        return p[x] == x ? x : p[x] = find(p[x]);\n    }\n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n    void unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> xs[i] >> ys[i];\n    }\n    \n    vector<int> u(M), v(M);\n    vector<long long> d(M);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        long long dx = (long long)xs[u[i]] - xs[v[i]];\n        long long dy = (long long)ys[u[i]] - ys[v[i]];\n        long long dist_sq = dx * dx + dy * dy;\n        long long dist = llround(sqrt((double)dist_sq));\n        d[i] = dist;\n    }\n    \n    // Precompute which edges are bridges in the suffix graph G_i = (V, {e_i, e_{i+1}, ..., e_{M-1}})\n    // If an edge is not a bridge in the suffix, there exists an alternative path using future edges\n    vector<char> is_bridge(M, 0);\n    DSU dsu_back(N);\n    for (int i = M - 1; i >= 0; --i) {\n        if (dsu_back.same(u[i], v[i])) {\n            is_bridge[i] = 0;\n        } else {\n            is_bridge[i] = 1;\n            dsu_back.unite(u[i], v[i]);\n        }\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;\n        cin >> l;\n        \n        if (dsu.same(u[i], v[i])) {\n            // Already connected, skip\n            cout << 0 << '\\n';\n        } else {\n            int need = components - 1;      // How many more edges we need\n            int remaining = M - i;          // How many edges remain (including current)\n            bool take = false;\n            \n            // If this edge is a bridge in the suffix, we must take it (no future path exists)\n            if (is_bridge[i]) {\n                take = true;\n            } \n            // If we skip this edge, we have 'remaining-1' edges left to connect 'need' components.\n            // If need > remaining-1, we cannot afford to skip.\n            else if (need >= remaining) {\n                take = true;\n            } \n            else {\n                // Dynamic threshold: stricter when we have many edges left, looser when few left\n                double ratio = (double)need / (double)remaining;\n                double threshold = 1.0 + 2.0 * ratio; // ranges from ~1.4 to 3.0\n                \n                // Accept if the edge is cheaper than the threshold\n                if ((double)l <= threshold * (double)d[i]) {\n                    take = true;\n                } else {\n                    take = false;\n                }\n            }\n            \n            if (take) {\n                cout << 1 << '\\n';\n                dsu.unite(u[i], v[i]);\n                components--;\n            } else {\n                cout << 0 << '\\n';\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool blocked[32][32];\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char wall_cmd[4] = {'u', 'd', 'l', 'r'};\nconst char move_cmd[4] = {'U', 'D', 'L', 'R'};\n\nbool is_passable(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30 && !blocked[x][y];\n}\n\nbool can_place_wall(int x, int y) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) return false;\n    if (blocked[x][y]) return false;\n    \n    for (auto& p : pets) {\n        if (p.x == x && p.y == y) return false;\n    }\n    for (auto& h : humans) {\n        if (h.x == x && h.y == y) return false;\n    }\n    \n    for (auto& p : pets) {\n        for (int d = 0; d < 4; d++) {\n            if (p.x + dx[d] == x && p.y + dy[d] == y) return false;\n        }\n    }\n    return true;\n}\n\nint bfs_area(int sx, int sy) {\n    if (!is_passable(sx, sy)) return 0;\n    bool visited[32][32] = {};\n    queue<pair<int,int>> q;\n    q.push({sx, sy});\n    visited[sx][sy] = true;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (is_passable(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return cnt;\n}\n\nint bfs_next_move(int sx, int sy, int tx, int ty, const vector<pair<int,int>>& obstacles) {\n    if (sx == tx && sy == ty) return -1;\n    \n    queue<pair<int,int>> q;\n    int dist[32][32];\n    memset(dist, -1, sizeof(dist));\n    \n    q.push({sx, sy});\n    dist[sx][sy] = 0;\n    int first_move[32][32];\n    memset(first_move, -1, sizeof(first_move));\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (!is_passable(nx, ny)) continue;\n            if (dist[nx][ny] != -1) continue;\n            \n            bool occupied = false;\n            for (auto& obs : obstacles) {\n                if (obs.first == nx && obs.second == ny) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (occupied) continue;\n            \n            dist[nx][ny] = dist[x][y] + 1;\n            first_move[nx][ny] = (dist[x][y] == 0) ? d : first_move[x][y];\n            \n            if (nx == tx && ny == ty) {\n                return first_move[nx][ny];\n            }\n            q.push({nx, ny});\n        }\n    }\n    return -1;\n}\n\nint nearest_pet_dist(int hx, int hy) {\n    int dist = 1000;\n    for (auto& p : pets) {\n        dist = min(dist, abs(p.x - hx) + abs(p.y - hy));\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    memset(blocked, false, sizeof(blocked));\n    \n    // Calculate initial fortress bounds\n    int min_x = 30, max_x = 1, min_y = 30, max_y = 1;\n    for (auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n    \n    int expand = 2;\n    int f_min_x = max(2, min_x - expand);\n    int f_max_x = min(29, max_x + expand);\n    int f_min_y = max(2, min_y - expand);\n    int f_max_y = min(29, max_y + expand);\n    \n    // Check if pets are initially inside\n    bool individual_mode = false;\n    for (auto& p : pets) {\n        if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n            individual_mode = true;\n            break;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> human_targets(M);\n    \n    if (individual_mode) {\n        // Each human builds their own 3x3 cell\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx + dx[d];\n                int wy = hy + dy[d];\n                if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                    human_targets[i].push_back({wx, wy});\n                }\n            }\n        }\n    } else {\n        // Shared fortress - assign perimeter sections\n        vector<pair<int,int>> all_targets;\n        for (int y = f_min_y; y <= f_max_y; y++) {\n            all_targets.push_back({f_min_x, y});\n            all_targets.push_back({f_max_x, y});\n        }\n        for (int x = f_min_x + 1; x <= f_max_x - 1; x++) {\n            all_targets.push_back({x, f_min_y});\n            all_targets.push_back({x, f_max_y});\n        }\n        \n        // Sort by angle from center to distribute evenly\n        double cx = (min_x + max_x) / 2.0;\n        double cy = (min_y + max_y) / 2.0;\n        sort(all_targets.begin(), all_targets.end(), [&](auto& a, auto& b) {\n            double ang_a = atan2(a.first - cx, a.second - cy);\n            double ang_b = atan2(b.first - cx, b.second - cy);\n            return ang_a < ang_b;\n        });\n        \n        // Round-robin assignment\n        for (int i = 0; i < (int)all_targets.size(); i++) {\n            human_targets[i % M].push_back(all_targets[i]);\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        // Check for invasion (pets inside fortress)\n        if (!individual_mode && turn > 0) {\n            for (auto& p : pets) {\n                if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n                    // Pet invaded! Switch to emergency individual mode\n                    individual_mode = true;\n                    human_targets.assign(M, {});\n                    for (int i = 0; i < M; i++) {\n                        int hx = humans[i].x, hy = humans[i].y;\n                        for (int d = 0; d < 4; d++) {\n                            int wx = hx + dx[d], wy = hy + dy[d];\n                            if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                                human_targets[i].push_back({wx, wy});\n                            }\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n        \n        string actions(M, '.');\n        vector<pair<int,int>> next_pos(M);\n        vector<bool> will_build(M, false);\n        \n        // Process humans in order of threat (most threatened first)\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return nearest_pet_dist(humans[a].x, humans[a].y) < nearest_pet_dist(humans[b].x, humans[b].y);\n        });\n        \n        // Track occupied positions for collision avoidance\n        vector<pair<int,int>> occupied;\n        for (auto& h : humans) occupied.push_back({h.x, h.y});\n        \n        for (int idx : order) {\n            int hx = humans[idx].x, hy = humans[idx].y;\n            bool acted = false;\n            \n            // Remove completed targets\n            human_targets[idx].erase(\n                remove_if(human_targets[idx].begin(), human_targets[idx].end(),\n                    [&](auto& t) { return blocked[t.first][t.second]; }),\n                human_targets[idx].end()\n            );\n            \n            // Try to build adjacent wall\n            for (auto& target : human_targets[idx]) {\n                int tx = target.first, ty = target.second;\n                if (abs(tx - hx) + abs(ty - hy) == 1) {\n                    if (can_place_wall(tx, ty)) {\n                        // Safety check: ensure building this wall doesn't trap us in tiny space\n                        blocked[tx][ty] = true;\n                        int area = bfs_area(hx, hy);\n                        blocked[tx][ty] = false;\n                        \n                        if (area >= 4) { // Ensure at least 4 cells accessible\n                            int d = (tx == hx - 1) ? 0 : (tx == hx + 1) ? 1 : (ty == hy - 1) ? 2 : 3;\n                            actions[idx] = wall_cmd[d];\n                            will_build[idx] = true;\n                            next_pos[idx] = {hx, hy};\n                            acted = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (acted) continue;\n            \n            // Move toward nearest target\n            if (!human_targets[idx].empty()) {\n                // Find nearest reachable target\n                int best_target = -1;\n                int best_dist = 1000;\n                \n                for (int i = 0; i < (int)human_targets[idx].size(); i++) {\n                    int tx = human_targets[idx][i].first;\n                    int ty = human_targets[idx][i].second;\n                    int d = abs(tx - hx) + abs(ty - hy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_target = i;\n                    }\n                }\n                \n                if (best_target != -1) {\n                    int tx = human_targets[idx][best_target].first;\n                    int ty = human_targets[idx][best_target].second;\n                    int d = bfs_next_move(hx, hy, tx, ty, occupied);\n                    \n                    if (d != -1) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        actions[idx] = move_cmd[d];\n                        next_pos[idx] = {nx, ny};\n                        // Update occupied for subsequent humans\n                        for (auto& o : occupied) {\n                            if (o.first == hx && o.second == hy) {\n                                o = {nx, ny};\n                                break;\n                            }\n                        }\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                // Defensive: move away from pets if too close\n                int min_dist = nearest_pet_dist(hx, hy);\n                if (min_dist <= 2) {\n                    int best_d = -1;\n                    int max_new_dist = min_dist;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (!is_passable(nx, ny)) continue;\n                        \n                        bool collides = false;\n                        for (auto& o : occupied) {\n                            if (o.first == nx && o.second == ny && !(o.first == hx && o.second == hy)) {\n                                collides = true;\n                                break;\n                            }\n                        }\n                        if (collides) continue;\n                        \n                        int new_dist = 1000;\n                        for (auto& p : pets) {\n                            new_dist = min(new_dist, abs(p.x - nx) + abs(p.y - ny));\n                        }\n                        if (new_dist > max_new_dist) {\n                            max_new_dist = new_dist;\n                            best_d = d;\n                        }\n                    }\n                    if (best_d != -1) {\n                        actions[idx] = move_cmd[best_d];\n                        next_pos[idx] = {hx + dx[best_d], hy + dy[best_d]};\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                actions[idx] = '.';\n                next_pos[idx] = {hx, hy};\n            }\n        }\n        \n        // Final conflict resolution for moves\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    // Later human stays\n                    actions[j] = '.';\n                    next_pos[j] = {humans[j].x, humans[j].y};\n                }\n            }\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n        \n        // Update state\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u') blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    double score;                 // Accumulated expected score from terminated paths\n    double value;                 // Upper bound = score + heuristic (for ranking/pruning)\n    array<double, 400> prob;      // Distribution over cells for active paths\n    string s;                     // Current string\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    const int N = 20;\n    auto ID = [&](int i, int j) { return i * N + j; };\n    const int target = ID(ti, tj);\n    const int start  = ID(si, sj);\n    const double q = 1.0 - p; // probability of remembering\n    \n    /*------------------------------------------------------------\n        1. Shortest path distances from the target (BFS)\n      ------------------------------------------------------------*/\n    vector<int> dist(400, -1);\n    queue<int> qdist;\n    qdist.push(target);\n    dist[target] = 0;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    while (!qdist.empty()) {\n        int cur = qdist.front(); qdist.pop();\n        int i = cur / N, j = cur % N;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) wall = (i == 0) ? true : (v[i-1][j] == '1');\n            else if (dir == 1) wall = (i == 19) ? true : (v[i][j] == '1');\n            else if (dir == 2) wall = (j == 0) ? true : (h[i][j-1] == '1');\n            else wall = (j == 19) ? true : (h[i][j] == '1');\n            if (wall) continue;\n            int nid = ID(ni, nj);\n            if (dist[nid] == -1) {\n                dist[nid] = dist[cur] + 1;\n                qdist.push(nid);\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        2. Pre\u2011compute moves and (1-p)^d\n      ------------------------------------------------------------*/\n    int nxt[400][4];\n    bool can_move[400][4];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int id = ID(i, j);\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                bool wall = false;\n                if (dir == 0) wall = (i == 0) ? true : (v[i-1][j] == '1');\n                else if (dir == 1) wall = (i == 19) ? true : (v[i][j] == '1');\n                else if (dir == 2) wall = (j == 0) ? true : (h[i][j-1] == '1');\n                else wall = (j == 19) ? true : (h[i][j] == '1');\n                if (wall) {\n                    can_move[id][dir] = false;\n                    nxt[id][dir] = id;\n                } else {\n                    can_move[id][dir] = true;\n                    nxt[id][dir] = ID(ni, nj);\n                }\n            }\n        }\n    }\n    \n    // Precompute (1-p)^d for d = 0..400\n    double pow_q[401];\n    pow_q[0] = 1.0;\n    for (int i = 1; i <= 400; ++i) pow_q[i] = pow_q[i-1] * q;\n    \n    // Helper to evaluate a string exactly\n    auto evaluate = [&](const string& s) -> double {\n        array<double, 400> cur{}, nxt_arr{};\n        cur.fill(0.0);\n        cur[start] = 1.0;\n        double score = 0.0;\n        int L = s.size();\n        for (int step = 0; step < L; ++step) {\n            nxt_arr.fill(0.0);\n            char c = s[step];\n            int dir = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n            for (int i = 0; i < 400; ++i) {\n                double pr = cur[i];\n                if (pr < 1e-15) continue;\n                // Forgot\n                nxt_arr[i] += pr * p;\n                // Try move\n                int to = nxt[i][dir];\n                if (to == target) {\n                    score += pr * q * (401 - (step + 1));\n                } else {\n                    nxt_arr[to] += pr * q;\n                }\n            }\n            cur.swap(nxt_arr);\n        }\n        return score;\n    };\n    \n    // Heuristic function: realistic upper bound\n    auto heuristic = [&](const array<double,400>& pr, int step) -> double {\n        double h = 0.0;\n        for (int i = 0; i < 400; ++i) {\n            double pi = pr[i];\n            if (pi < 1e-15) continue;\n            int d = dist[i];\n            if (d < 0) continue; // Should not happen\n            int arrival = step + d;\n            if (arrival >= 401) continue;\n            // Probability to execute d moves without failure: (1-p)^d\n            h += pi * pow_q[d] * (401 - arrival);\n        }\n        return h;\n    };\n    \n    /*------------------------------------------------------------\n        3. Greedy baseline for pruning\n      ------------------------------------------------------------*/\n    // Construct a simple greedy path (shortest path)\n    string greedy;\n    int ci = si, cj = sj;\n    while (ci != ti || cj != tj) {\n        int cur = ID(ci, cj);\n        for (int dir = 0; dir < 4; ++dir) {\n            if (!can_move[cur][dir]) continue;\n            int nid = nxt[cur][dir];\n            if (dist[nid] < dist[cur]) {\n                greedy += dc[dir];\n                ci += di[dir];\n                cj += dj[dir];\n                break;\n            }\n        }\n    }\n    double best_score_global = evaluate(greedy);\n    string best_string_global = greedy;\n    \n    /*------------------------------------------------------------\n        4. Beam Search\n      ------------------------------------------------------------*/\n    const int BEAM = 200;\n    vector<State> beam;\n    State init;\n    init.score = 0.0;\n    init.prob.fill(0.0);\n    init.prob[start] = 1.0;\n    init.s.clear();\n    init.value = heuristic(init.prob, 0);\n    beam.push_back(init);\n    \n    for (int step = 1; step <= 200; ++step) {\n        vector<State> cand;\n        cand.reserve(beam.size() * 4);\n        for (const State &st : beam) {\n            // Pruning: if even the optimistic bound is worse than current best, skip\n            if (st.value < best_score_global) continue;\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                State ns;\n                ns.score = st.score;\n                ns.prob.fill(0.0);\n                // Transition\n                for (int i = 0; i < 400; ++i) {\n                    double curp = st.prob[i];\n                    if (curp < 1e-15) continue;\n                    // Forgot character\n                    ns.prob[i] += curp * p;\n                    // Execute move\n                    if (can_move[i][dir]) {\n                        int to = nxt[i][dir];\n                        if (to == target) {\n                            ns.score += curp * q * (401 - step);\n                        } else {\n                            ns.prob[to] += curp * q;\n                        }\n                    } else {\n                        // Blocked by wall -> stay\n                        ns.prob[i] += curp * q;\n                    }\n                }\n                ns.s = st.s + dc[dir];\n                double heu = heuristic(ns.prob, step);\n                ns.value = ns.score + heu;\n                \n                // Update global best (ns.s is a valid complete string of length step)\n                if (ns.score > best_score_global) {\n                    best_score_global = ns.score;\n                    best_string_global = ns.s;\n                }\n                \n                cand.push_back(ns);\n            }\n        }\n        \n        if (cand.empty()) break;\n        \n        // Keep top BEAM states by value\n        if ((int)cand.size() > BEAM) {\n            nth_element(cand.begin(), cand.begin() + BEAM, cand.end(),\n                [](const State& a, const State& b) { return a.value > b.value; });\n            cand.resize(BEAM);\n        }\n        // Optional: full sort for stability, but nth_element is enough\n        beam.swap(cand);\n    }\n    \n    /*------------------------------------------------------------\n        5. Hill Climbing Refinement\n      ------------------------------------------------------------*/\n    string current = best_string_global;\n    double cur_score = best_score_global;\n    bool improved = true;\n    // Limit iterations to avoid excessive time in pathological cases\n    int max_iterations = 2000;\n    int iter = 0;\n    \n    while (improved && iter < max_iterations) {\n        improved = false;\n        int L = current.size();\n        for (int pos = 0; pos < L && !improved; ++pos) {\n            char orig = current[pos];\n            for (int dir = 0; dir < 4; ++dir) {\n                char c = dc[dir];\n                if (c == orig) continue;\n                string cand = current;\n                cand[pos] = c;\n                double sc = evaluate(cand);\n                ++iter;\n                if (sc > cur_score) {\n                    cur_score = sc;\n                    current = cand;\n                    improved = true;\n                    break;\n                }\n                if (iter >= max_iterations) break;\n            }\n        }\n    }\n    \n    cout << current << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast random number generator\nstruct XorShift {\n    unsigned long long x;\n    XorShift() { x = chrono::steady_clock::now().time_since_epoch().count(); }\n    unsigned int rand() {\n        x ^= x << 13;\n        x ^= x >> 7;\n        x ^= x << 17;\n        return (unsigned int)(x & 0xFFFFFFFF);\n    }\n    int rand_int(int n) { return rand() % n; }\n    int rand_int(int l, int r) { return l + rand_int(r - l + 1); }\n    double rand_double() { return (double)rand() / UINT32_MAX; }\n} rng;\n\n// Tile connection definitions\n// to[t][d]: exit direction when entering tile type t from direction d\n// d: 0=left, 1=up, 2=right, 3=down\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0: left-up corner\n    {3, -1, -1, 0},  // 1: left-down corner\n    {-1, -1, 3, 2},  // 2: right-down corner\n    {-1, 2, 1, -1},  // 3: up-right corner\n    {1, 0, 3, 2},    // 4: double curve (LU + RD)\n    {3, 2, 1, 0},    // 5: double curve (LD + RU)\n    {2, -1, 0, -1},  // 6: horizontal straight\n    {-1, 3, -1, 1}   // 7: vertical straight\n};\n\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\ninline int rotate_type(int t, int r) {\n    r &= 3;\n    if (t < 4) return (t + r) & 3;\n    else if (t < 6) return (r & 1) ? (t == 4 ? 5 : 4) : t;\n    else return (r & 1) ? (t == 6 ? 7 : 6) : t;\n}\n\n// Fast cycle detection with cycle length tracking\nstruct Evaluator {\n    static const int N = 30;\n    static const int M = 30;\n    static const int V = N * M * 4;\n    \n    short nxt[V];\n    int comp_id[V];\n    int comp_size[V];\n    int dist[V];\n    unsigned short vis[V];\n    unsigned short vis_token;\n    vector<pair<int, int>> cycles; // (size, representative)\n    \n    Evaluator() : vis_token(1) {\n        memset(vis, 0, sizeof(vis));\n    }\n    \n    void clear() {\n        vis_token++;\n        if (vis_token == 0) {\n            memset(vis, 0, sizeof(vis));\n            vis_token = 1;\n        }\n    }\n    \n    // Returns score = L1 * L2, and fills cycle lengths in cycles vector\n    int evaluate(const array<array<int, 30>, 30>& rot, \n                 const array<array<int, 30>, 30>& init,\n                 vector<int>& cycle_lengths) {\n        // Build transition graph\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < M; j++) {\n                int t = rotate_type(init[i][j], rot[i][j]);\n                int base = (i * M + j) * 4;\n                for (int d = 0; d < 4; d++) {\n                    int d2 = to[t][d];\n                    if (d2 == -1) {\n                        nxt[base + d] = -1;\n                    } else {\n                        int ni = i + di[d2];\n                        int nj = j + dj[d2];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= M) {\n                            nxt[base + d] = -1;\n                        } else {\n                            int nd = (d2 + 2) & 3;\n                            nxt[base + d] = (ni * M + nj) * 4 + nd;\n                        }\n                    }\n                }\n            }\n        }\n        \n        cycle_lengths.clear();\n        clear();\n        \n        // Find cycles using Floyd or simple DFS\n        for (int s = 0; s < V; s++) {\n            if (vis[s] == vis_token || nxt[s] == -1) continue;\n            \n            int cur = s;\n            vector<int> path;\n            path.reserve(64);\n            \n            while (cur != -1) {\n                if (vis[cur] == vis_token) {\n                    if (dist[cur] >= 0) {\n                        cycle_lengths.push_back((int)path.size() - dist[cur]);\n                    }\n                    break;\n                }\n                vis[cur] = vis_token;\n                dist[cur] = (int)path.size();\n                path.push_back(cur);\n                cur = nxt[cur];\n            }\n            \n            for (int node : path) dist[node] = -1;\n        }\n        \n        // Get top 2 cycles\n        if (cycle_lengths.size() <= 1) {\n            return 0;\n        }\n        \n        // Partial sort for top 2\n        nth_element(cycle_lengths.begin(), \n                   cycle_lengths.begin() + min(2, (int)cycle_lengths.size()), \n                   cycle_lengths.end(), greater<int>());\n        \n        int L1 = cycle_lengths[0];\n        int L2 = cycle_lengths.size() > 1 ? cycle_lengths[1] : 0;\n        return L1 * L2;\n    }\n};\n\n// Find which cycle a tile belongs to (approximately)\nvoid find_small_cycles(const array<array<int, 30>, 30>& rot,\n                      const array<array<int, 30>, 30>& init,\n                      vector<pair<int, pair<int, int>>>& small_tiles) {\n    // Returns tiles on smallest cycles\n    static short nxt[3600];\n    static int dist[3600];\n    static unsigned short vis[3600];\n    static unsigned short vis_token = 1;\n    static int cycle_id[3600];\n    static int cycle_len[3600];\n    \n    // Build graph\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = rotate_type(init[i][j], rot[i][j]);\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                int d2 = to[t][d];\n                if (d2 == -1) {\n                    nxt[base + d] = -1;\n                } else {\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                        nxt[base + d] = -1;\n                    } else {\n                        int nd = (d2 + 2) & 3;\n                        nxt[base + d] = (ni * 30 + nj) * 4 + nd;\n                    }\n                }\n            }\n        }\n    }\n    \n    memset(cycle_id, -1, sizeof(cycle_id));\n    vector<int> all_cycles;\n    \n    for (int s = 0; s < 3600; s++) {\n        if (vis[s] == vis_token || nxt[s] == -1) continue;\n        \n        int cur = s;\n        vector<int> path;\n        \n        while (cur != -1) {\n            if (vis[cur] == vis_token) {\n                if (dist[cur] >= 0) {\n                    int len = (int)path.size() - dist[cur];\n                    all_cycles.push_back(len);\n                    for (int k = dist[cur]; k < (int)path.size(); k++) {\n                        cycle_id[path[k]] = (int)all_cycles.size() - 1;\n                        cycle_len[path[k]] = len;\n                    }\n                }\n                break;\n            }\n            vis[cur] = vis_token;\n            dist[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        for (int node : path) dist[node] = -1;\n    }\n    \n    vis_token++;\n    if (vis_token == 0) {\n        memset(vis, 0, sizeof(vis));\n        vis_token = 1;\n    }\n    \n    // Collect tiles on small cycles\n    small_tiles.clear();\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                if (cycle_id[base + d] != -1 && cycle_len[base + d] <= 20) {\n                    small_tiles.push_back({cycle_len[base + d], {i, j}});\n                }\n            }\n        }\n    }\n    \n    sort(small_tiles.begin(), small_tiles.end());\n    small_tiles.erase(unique(small_tiles.begin(), small_tiles.end()), small_tiles.end());\n}\n\n// Try to construct a snake pattern covering the grid\nvoid init_snake(array<array<int, 30>, 30>& rot,\n                const array<array<int, 30>, 30>& init,\n                int pattern) {\n    // Pattern 0: Two horizontal snakes\n    // Pattern 1: Two vertical snakes\n    // Pattern 2: Spiral\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = init[i][j];\n            int r = 0;\n            \n            if (pattern == 0) {\n                // Horizontal snake: even rows left->right, odd rows right->left\n                // But we need to connect rows with turns at ends\n                if (i % 4 == 0 || i % 4 == 3) {\n                    // Horizontal segment\n                    if (t == 6) r = 0; // already horizontal\n                    else if (t == 7) r = 1; // rotate to horizontal\n                    else if (t < 4) {\n                        // Need to be horizontal, but corner can't be horizontal straight\n                        // Use as turn at ends\n                        if (j == 0 && i % 4 == 0) r = (t == 0) ? 0 : (t == 1) ? 3 : (t == 2) ? 2 : 1; // up or down?\n                        else if (j == 29 && i % 4 == 0) r = (t == 0) ? 3 : (t == 1) ? 0 : (t == 2) ? 1 : 2;\n                        else if (j == 0 && i % 4 == 3) r = (t == 0) ? 1 : (t == 1) ? 2 : (t == 2) ? 3 : 0;\n                        else if (j == 29 && i % 4 == 3) r = (t == 0) ? 2 : (t == 1) ? 1 : (t == 2) ? 0 : 3;\n                        else r = rng.rand_int(0, 3);\n                    } else {\n                        r = rng.rand_int(0, 1);\n                    }\n                } else {\n                    // Vertical connector at ends\n                    if (i % 4 == 1) {\n                        // Going down at left side, up at right side?\n                        if (j == 0) {\n                            if (t == 7) r = 0;\n                            else if (t == 6) r = 1;\n                            else if (t == 0) r = 3;\n                            else if (t == 1) r = 0;\n                            else if (t == 2) r = 1;\n                            else if (t == 3) r = 2;\n                            else r = rng.rand_int(0, 1);\n                        } else if (j == 29) {\n                            if (t == 7) r = 0;\n                            else if (t == 6) r = 1;\n                            else if (t == 0) r = 1;\n                            else if (t == 1) r = 2;\n                            else if (t == 2) r = 3;\n                            else if (t == 3) r = 0;\n                            else r = rng.rand_int(0, 1);\n                        } else {\n                            r = rng.rand_int(0, 3);\n                        }\n                    } else {\n                        // i % 4 == 2\n                        if (j == 0) {\n                            if (t == 7) r = 0;\n                            else if (t == 6) r = 1;\n                            else if (t == 0) r = 1;\n                            else if (t == 1) r = 0;\n                            else if (t == 2) r = 3;\n                            else if (t == 3) r = 2;\n                            else r = rng.rand_int(0, 1);\n                        } else if (j == 29) {\n                            if (t == 7) r = 0;\n                            else if (t == 6) r = 1;\n                            else if (t == 0) r = 3;\n                            else if (t == 1) r = 2;\n                            else if (t == 2) r = 1;\n                            else if (t == 3) r = 0;\n                            else r = rng.rand_int(0, 1);\n                        } else {\n                            r = rng.rand_int(0, 3);\n                        }\n                    }\n                }\n            } else if (pattern == 1) {\n                // Vertical snake\n                if (j % 4 == 0 || j % 4 == 3) {\n                    if (t == 7) r = 0;\n                    else if (t == 6) r = 1;\n                    else if (t < 4) {\n                        if (i == 0 && j % 4 == 0) r = (t == 0) ? 0 : (t == 1) ? 3 : (t == 2) ? 2 : 1;\n                        else if (i == 29 && j % 4 == 0) r = (t == 0) ? 2 : (t == 1) ? 1 : (t == 2) ? 0 : 3;\n                        else if (i == 0 && j % 4 == 3) r = (t == 0) ? 3 : (t == 1) ? 2 : (t == 2) ? 1 : 0;\n                        else if (i == 29 && j % 4 == 3) r = (t == 0) ? 1 : (t == 1) ? 0 : (t == 2) ? 3 : 2;\n                        else r = rng.rand_int(0, 3);\n                    } else {\n                        r = rng.rand_int(0, 1);\n                    }\n                } else {\n                    if (j % 4 == 1) {\n                        if (i == 0) {\n                            if (t == 6) r = 0;\n                            else if (t == 7) r = 1;\n                            else if (t == 0) r = 3;\n                            else if (t == 1) r = 2;\n                            else if (t == 2) r = 1;\n                            else if (t == 3) r = 0;\n                            else r = rng.rand_int(0, 1);\n                        } else if (i == 29) {\n                            if (t == 6) r = 0;\n                            else if (t == 7) r = 1;\n                            else if (t == 0) r = 1;\n                            else if (t == 1) r = 0;\n                            else if (t == 2) r = 3;\n                            else if (t == 3) r = 2;\n                            else r = rng.rand_int(0, 1);\n                        } else {\n                            r = rng.rand_int(0, 3);\n                        }\n                    } else {\n                        if (i == 0) {\n                            if (t == 6) r = 0;\n                            else if (t == 7) r = 1;\n                            else if (t == 0) r = 1;\n                            else if (t == 1) r = 0;\n                            else if (t == 2) r = 3;\n                            else if (t == 3) r = 2;\n                            else r = rng.rand_int(0, 1);\n                        } else if (i == 29) {\n                            if (t == 6) r = 0;\n                            else if (t == 7) r = 1;\n                            else if (t == 0) r = 3;\n                            else if (t == 1) r = 2;\n                            else if (t == 2) r = 1;\n                            else if (t == 3) r = 0;\n                            else r = rng.rand_int(0, 1);\n                        } else {\n                            r = rng.rand_int(0, 3);\n                        }\n                    }\n                }\n            } else {\n                r = rng.rand_int(0, 3);\n            }\n            \n            rot[i][j] = r;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    array<array<int, 30>, 30> init{};\n    for (int i = 0; i < 30; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < 30; j++) {\n            init[i][j] = s[j] - '0';\n        }\n    }\n    \n    Evaluator eval;\n    vector<int> cycles;\n    vector<pair<int, pair<int, int>>> small_tiles;\n    cycles.reserve(1000);\n    \n    array<array<int, 30>, 30> best_rot{};\n    int best_score = -1;\n    \n    const double TIME_LIMIT = 1.95;\n    clock_t start_time = clock();\n    \n    // Try different initialization strategies\n    for (int strategy = 0; strategy < 4; strategy++) {\n        array<array<int, 30>, 30> cur_rot{};\n        \n        if (strategy < 3) {\n            init_snake(cur_rot, init, strategy);\n        } else {\n            // Random init\n            for (int i = 0; i < 30; i++)\n                for (int j = 0; j < 30; j++)\n                    cur_rot[i][j] = rng.rand_int(0, 3);\n        }\n        \n        int cur_score = eval.evaluate(cur_rot, init, cycles);\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            best_rot = cur_rot;\n        }\n        \n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Simulated annealing for this start\n        double temp = 50.0;\n        const double cooling = 0.99998;\n        \n        int last_improve = 0;\n        for (int iter = 0; ; iter++) {\n            elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n            if (elapsed > TIME_LIMIT || elapsed > (strategy + 1) * TIME_LIMIT / 4) break;\n            \n            // Pick tile to modify\n            int i, j;\n            \n            if (iter % 10 == 0 && iter > 100) {\n                // Occasionally try to break small cycles\n                find_small_cycles(cur_rot, init, small_tiles);\n                if (!small_tiles.empty() && rng.rand_double() < 0.7) {\n                    int idx = rng.rand_int(0, min((int)small_tiles.size() - 1, 10));\n                    i = small_tiles[idx].second.first;\n                    j = small_tiles[idx].second.second;\n                } else {\n                    i = rng.rand_int(0, 29);\n                    j = rng.rand_int(0, 29);\n                }\n            } else {\n                i = rng.rand_int(0, 29);\n                j = rng.rand_int(0, 29);\n            }\n            \n            int old_r = cur_rot[i][j];\n            int best_local_r = old_r;\n            int best_local_score = cur_score;\n            \n            // Try all 3 other rotations\n            for (int delta = 1; delta <= 3; delta++) {\n                int new_r = (old_r + delta) & 3;\n                cur_rot[i][j] = new_r;\n                int new_score = eval.evaluate(cur_rot, init, cycles);\n                \n                if (new_score > best_local_score) {\n                    best_local_score = new_score;\n                    best_local_r = new_r;\n                }\n            }\n            \n            // Accept or reject\n            if (best_local_score > cur_score) {\n                cur_rot[i][j] = best_local_r;\n                cur_score = best_local_score;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rot = cur_rot;\n                    last_improve = iter;\n                }\n            } else {\n                // Accept with probability based on temperature\n                cur_rot[i][j] = old_r;\n                if (rng.rand_double() < exp((best_local_score - cur_score) / temp)) {\n                    cur_rot[i][j] = best_local_r;\n                    cur_score = best_local_score;\n                }\n            }\n            \n            temp *= cooling;\n            \n            // Random restart within this strategy if stuck\n            if (iter - last_improve > 5000) {\n                // Perturb\n                for (int k = 0; k < 50; k++) {\n                    int pi = rng.rand_int(0, 29);\n                    int pj = rng.rand_int(0, 29);\n                    cur_rot[pi][pj] = rng.rand_int(0, 3);\n                }\n                cur_score = eval.evaluate(cur_rot, init, cycles);\n                last_improve = iter;\n            }\n        }\n    }\n    \n    // Final intensive search from best solution\n    array<array<int, 30>, 30> cur_rot = best_rot;\n    int cur_score = best_score;\n    double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n    \n    while (elapsed < TIME_LIMIT) {\n        // Greedy hill climbing\n        bool improved = false;\n        \n        // Shuffle order\n        vector<pair<int, int>> order;\n        for (int i = 0; i < 30; i++)\n            for (int j = 0; j < 30; j++)\n                order.push_back({i, j});\n        shuffle(order.begin(), order.end(), mt19937(rng.rand()));\n        \n        for (auto [i, j] : order) {\n            elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n            if (elapsed > TIME_LIMIT) break;\n            \n            int old_r = cur_rot[i][j];\n            int orig_score = cur_score;\n            \n            for (int r = 0; r < 4; r++) {\n                if (r == old_r) continue;\n                cur_rot[i][j] = r;\n                int new_score = eval.evaluate(cur_rot, init, cycles);\n                if (new_score > cur_score) {\n                    cur_score = new_score;\n                    improved = true;\n                    if (cur_score > best_score) {\n                        best_score = cur_score;\n                        best_rot = cur_rot;\n                    }\n                } else {\n                    cur_rot[i][j] = old_r;\n                }\n            }\n        }\n        \n        if (!improved) break;\n        elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n    }\n    \n    // Output result\n    string ans;\n    ans.reserve(900);\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            ans += char('0' + best_rot[i][j]);\n        }\n    }\n    cout << ans << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> initial_board;\n\nstruct State {\n    array<array<int, 10>, 10> bd;\n    int er, ec;\n    string moves;\n    \n    State() {}\n    State(const vector<string>& b, int _er, int _ec) : er(_er), ec(_ec), moves(\"\") {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = b[i][j];\n                bd[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            }\n        }\n    }\n    \n    bool in_bounds(int r, int c) const {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    char reverse(char c) const {\n        if (c == 'U') return 'D';\n        if (c == 'D') return 'U';\n        if (c == 'L') return 'R';\n        return 'L';\n    }\n    \n    bool can_move(char c) const {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else if (c == 'R') nc++;\n        return in_bounds(nr, nc);\n    }\n    \n    void move(char c) {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else if (c == 'R') nc++;\n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n        moves.push_back(c);\n    }\n    \n    int calc_score() const {\n        int V = N * N;\n        vector<int> parent(V);\n        iota(parent.begin(), parent.end(), 0);\n        \n        function<int(int)> find = [&](int x) -> int {\n            return parent[x] == x ? x : parent[x] = find(parent[x]);\n        };\n        \n        auto unite = [&](int x, int y) {\n            x = find(x);\n            y = find(y);\n            if (x != y) parent[x] = y;\n        };\n        \n        // Horizontal edges: right (4) connects to left (1)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    unite(i * N + j, i * N + (j + 1));\n                }\n            }\n        }\n        // Vertical edges: down (8) connects to up (2)\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    unite(i * N + j, (i + 1) * N + j);\n                }\n            }\n        }\n        \n        vector<int> verts(V, 0), edges(V, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] != 0) {\n                    verts[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        int best = 0;\n        for (int i = 0; i < V; i++) {\n            if (verts[i] > 0 && edges[i] == verts[i] - 1) {\n                best = max(best, verts[i]);\n            }\n        }\n        return best;\n    }\n};\n\nstring solve() {\n    // Find initial empty cell\n    int er = -1, ec = -1;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (initial_board[i][j] == '0') {\n                er = i;\n                ec = j;\n                break;\n            }\n        }\n        if (er != -1) break;\n    }\n    \n    if (er == -1) return \"\"; // Should not happen\n    \n    State cur(initial_board, er, ec);\n    int cur_score = cur.calc_score();\n    \n    string best_moves = \"\";\n    int best_score = cur_score;\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start = chrono::steady_clock::now();\n    const double TL = 2.8;\n    \n    double temp = 50.0;\n    const double cooling = 0.99995;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TL) break;\n        \n        // Reset if path too long\n        if ((int)cur.moves.size() >= T - 5) {\n            cur = State(initial_board, er, ec);\n            cur_score = cur.calc_score();\n            temp = 50.0;\n            continue;\n        }\n        \n        vector<pair<char, int>> candidates; // move, score\n        char prev_rev = cur.moves.empty() ? 'X' : cur.reverse(cur.moves.back());\n        \n        for (char c : {'U', 'D', 'L', 'R'}) {\n            if (c == prev_rev) continue; // Avoid immediate reversal\n            if (!cur.can_move(c)) continue;\n            \n            State nxt = cur;\n            nxt.move(c);\n            int sc = nxt.calc_score();\n            candidates.push_back({c, sc});\n        }\n        \n        if (candidates.empty()) continue;\n        \n        sort(candidates.begin(), candidates.end(), \n             [](const auto& a, const auto& b) { return a.second > b.second; });\n        \n        char chosen;\n        int new_score;\n        bool accept = false;\n        \n        if (candidates[0].second >= cur_score) {\n            chosen = candidates[0].first;\n            new_score = candidates[0].second;\n            accept = true;\n        } else {\n            uniform_int_distribution<int> dist(0, candidates.size() - 1);\n            int idx = dist(rng);\n            chosen = candidates[idx].first;\n            new_score = candidates[idx].second;\n            \n            double delta = new_score - cur_score;\n            if (exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            cur.move(chosen);\n            cur_score = new_score;\n            \n            if (cur_score > best_score || (cur_score == best_score && cur.moves.size() < best_moves.size())) {\n                best_score = cur_score;\n                best_moves = cur.moves;\n            }\n        }\n        \n        temp *= cooling;\n        \n        // Periodic restart\n        static int iter = 0;\n        if (++iter % 50000 == 0 && best_score < N*N-1) {\n            if (uniform_int_distribution<int>(0, 100)(rng) < 20) {\n                cur = State(initial_board, er, ec);\n                cur_score = cur.calc_score();\n                temp = 50.0;\n            }\n        }\n    }\n    \n    // Validate the best solution\n    State validator(initial_board, er, ec);\n    bool valid = true;\n    for (char c : best_moves) {\n        if (!validator.can_move(c)) {\n            valid = false;\n            break;\n        }\n        validator.move(c);\n    }\n    \n    if (!valid || best_moves.size() > T) {\n        return \"\";\n    }\n    \n    return best_moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    initial_board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> initial_board[i];\n    }\n    \n    string ans = solve();\n    cout << ans << \"\\n\";\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long x1, y1, x2, y2;\n};\n\nint N, K;\nint target[11];\nvector<Point> pts;\nvector<Line> cuts;\n\n// Current partition: piece_id[i] = index of piece for strawberry i\nvector<int> piece_id;\n// List of pieces (each is list of indices)\nvector<vector<int>> pieces;\nint cur_cnt[12]; // cur_cnt[d] for d=1..10, cur_cnt[0] for >10 or empty\n\nint calc_score() {\n    int res = 0;\n    for (int d = 1; d <= 10; d++) {\n        res += min(cur_cnt[d], target[d]);\n    }\n    return res;\n}\n\n// side: -1 for left, 1 for right, 0 for on line\nint side(const Point& p, const Line& ln) {\n    long long v1x = ln.x2 - ln.x1;\n    long long v1y = ln.y2 - ln.y1;\n    long long v2x = p.x - ln.x1;\n    long long v2y = p.y - ln.y1;\n    long long cr = v1x * v2y - v1y * v2x;\n    if (cr < 0) return -1;\n    if (cr > 0) return 1;\n    return 0;\n}\n\n// Apply cut and update state\nvoid apply_cut(const Line& ln) {\n    vector<vector<int>> new_pieces;\n    vector<int> new_id(N);\n    new_pieces.reserve(pieces.size() * 2);\n    \n    int pid = 0;\n    for (auto& pc : pieces) {\n        vector<int> left, right;\n        left.reserve(pc.size());\n        right.reserve(pc.size());\n        for (int idx : pc) {\n            int s = side(pts[idx], ln);\n            if (s == 0) {\n                // Should not happen if we generate lines correctly\n                // Put to left arbitrarily\n                left.push_back(idx);\n            } else if (s < 0) {\n                left.push_back(idx);\n            } else {\n                right.push_back(idx);\n            }\n        }\n        if (!left.empty()) {\n            for (int idx : left) new_id[idx] = pid;\n            new_pieces.push_back(move(left));\n            pid++;\n        }\n        if (!right.empty()) {\n            for (int idx : right) new_id[idx] = pid;\n            new_pieces.push_back(move(right));\n            pid++;\n        }\n    }\n    \n    pieces = move(new_pieces);\n    piece_id = move(new_id);\n    \n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    for (auto& pc : pieces) {\n        int s = pc.size();\n        if (1 <= s && s <= 10) cur_cnt[s]++;\n        else if (s > 10) cur_cnt[0]++;\n    }\n}\n\n// Generate a random line attempting to split a specific piece\n// Returns line and the expected sizes (approximate)\nLine generate_cut_for_piece(const vector<int>& pc, int& out_left, int& out_right) {\n    int n = pc.size();\n    out_left = n/2;\n    out_right = n - n/2;\n    \n    if (n < 2) return {0,0,0,0};\n    \n    // Random projection direction\n    double theta = (double)rand() / RAND_MAX * 2.0 * M_PI;\n    long long dx = (long long)(cos(theta) * 1000000);\n    long long dy = (long long)(sin(theta) * 1000000);\n    \n    // Project\n    vector<pair<long long, int>> proj;\n    proj.reserve(n);\n    for (int idx : pc) {\n        long long dot = pts[idx].x * dx + pts[idx].y * dy;\n        proj.emplace_back(dot, idx);\n    }\n    sort(proj.begin(), proj.end());\n    \n    // Try to cut at various positions\n    vector<int> try_pos;\n    // Try to isolate small groups that are needed\n    for (int d = 1; d <= min(10, n-1); d++) {\n        if (target[d] > cur_cnt[d]) {\n            try_pos.push_back(d);\n        }\n    }\n    // Also try middle\n    try_pos.push_back(n/2);\n    \n    for (int d : try_pos) {\n        if (d <= 0 || d >= n) continue;\n        // Cut between d-1 and d\n        // Find perpendicular direction\n        // Original direction: (dx, dy), perpendicular: (-dy, dx)\n        long long px = -dy;\n        long long py = dx;\n        \n        // Midpoint between proj[d-1] and proj[d]\n        long long midx = (pts[proj[d-1].second].x + pts[proj[d].second].x) / 2;\n        long long midy = (pts[proj[d-1].second].y + pts[proj[d].second].y) / 2;\n        \n        // Line: passes through (midx, midy), direction (px, py)\n        // Use points far away to ensure integer coordinates and range\n        Line ln;\n        ln.x1 = midx - px;\n        ln.y1 = midy - py;\n        ln.x2 = midx + px;\n        ln.y2 = midy + py;\n        \n        // Check range\n        if (abs(ln.x1) > 1e9 || abs(ln.y1) > 1e9 || abs(ln.x2) > 1e9 || abs(ln.y2) > 1e9) {\n            // Scale down or skip\n            continue;\n        }\n        \n        // Verify no point on line\n        bool ok = true;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) == 0) {\n                ok = false;\n                break;\n            }\n        }\n        if (!ok) continue;\n        \n        // Count actual split\n        int lc = 0, rc = 0;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) < 0) lc++;\n            else rc++;\n        }\n        if (lc == 0 || rc == 0) continue;\n        \n        out_left = lc;\n        out_right = rc;\n        return ln;\n    }\n    \n    return {0,0,0,0};\n}\n\n// Generate completely random line\nLine generate_random_cut() {\n    Line ln;\n    ln.x1 = (rand() % 2000000000) - 1000000000;\n    ln.y1 = (rand() % 2000000000) - 1000000000;\n    ln.x2 = (rand() % 2000000000) - 1000000000;\n    ln.y2 = (rand() % 2000000000) - 1000000000;\n    if (ln.x1 == ln.x2 && ln.y1 == ln.y2) {\n        ln.x2++;\n    }\n    \n    // Ensure no point on line\n    bool bad = true;\n    int attempts = 0;\n    while (bad && attempts < 10) {\n        bad = false;\n        for (int i = 0; i < N; i++) {\n            if (side(pts[i], ln) == 0) {\n                bad = true;\n                ln.x2 += (rand() % 10) - 5;\n                ln.y2 += (rand() % 10) - 5;\n                attempts++;\n                break;\n            }\n        }\n    }\n    return ln;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(42); // Fixed seed for reproducibility, can use time(0) in contest\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> target[i];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n    \n    // Initial state: one piece containing all\n    pieces.resize(1);\n    pieces[0].resize(N);\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n    piece_id.assign(N, 0);\n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    if (N <= 10) cur_cnt[N] = 1;\n    else cur_cnt[0] = 1;\n    \n    int current_score = calc_score();\n    \n    for (int iter = 0; iter < K; iter++) {\n        Line best_ln = {0,0,0,0};\n        int best_new_score = current_score;\n        bool found = false;\n        \n        // Identify candidate pieces to split\n        vector<int> cand_pieces;\n        for (int i = 0; i < pieces.size(); i++) {\n            int s = pieces[i].size();\n            if (s > 1) {\n                // Split if too large or we have excess of this size\n                if (s > 10 || (s <= 10 && cur_cnt[s] > target[s])) {\n                    cand_pieces.push_back(i);\n                }\n            }\n        }\n        \n        if (cand_pieces.empty()) {\n            // Try to improve by splitting any piece that might allow better distribution\n            for (int i = 0; i < pieces.size(); i++) {\n                if (pieces[i].size() > 1) cand_pieces.push_back(i);\n            }\n        }\n        \n        if (cand_pieces.empty()) break;\n        \n        // Try candidates from specific pieces\n        for (int pid : cand_pieces) {\n            for (int t = 0; t < 30; t++) {\n                int lc, rc;\n                Line ln = generate_cut_for_piece(pieces[pid], lc, rc);\n                if (ln.x1 == 0 && ln.y1 == 0) continue;\n                \n                // Quick evaluation: compute delta score\n                int delta = 0;\n                int s = pieces[pid].size();\n                \n                // Remove s\n                if (s <= 10) {\n                    delta -= min(cur_cnt[s], target[s]) - min(cur_cnt[s]-1, target[s]);\n                }\n                // Add lc, rc\n                if (lc <= 10 && lc >= 1) {\n                    delta += min(cur_cnt[lc]+1, target[lc]) - min(cur_cnt[lc], target[lc]);\n                }\n                if (rc <= 10 && rc >= 1 && rc != lc) {\n                    delta += min(cur_cnt[rc]+1, target[rc]) - min(cur_cnt[rc], target[rc]);\n                } else if (rc == lc && rc <= 10 && rc >= 1) {\n                    // If both sides same size, we added 2, but above counted 1\n                    delta += min(cur_cnt[rc]+2, target[rc]) - min(cur_cnt[rc]+1, target[rc]);\n                }\n                \n                // But this delta calculation ignores other pieces being split!\n                // The generate_cut_for_piece only checks the target piece.\n                // We need full simulation.\n                \n                // Full simulation\n                auto old_pieces = pieces;\n                auto old_pid = piece_id;\n                auto old_cnt = cur_cnt;\n                int old_score = current_score;\n                \n                apply_cut(ln);\n                int new_score = calc_score();\n                \n                if (new_score > best_new_score) {\n                    best_new_score = new_score;\n                    best_ln = ln;\n                    found = true;\n                }\n                \n                // Restore\n                pieces = old_pieces;\n                piece_id = old_pid;\n                memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n                current_score = old_score;\n            }\n        }\n        \n        // Also try some random cuts\n        for (int t = 0; t < 20; t++) {\n            Line ln = generate_random_cut();\n            \n            auto old_pieces = pieces;\n            auto old_pid = piece_id;\n            auto old_cnt = cur_cnt;\n            \n            apply_cut(ln);\n            int new_score = calc_score();\n            \n            if (new_score > best_new_score) {\n                best_new_score = new_score;\n                best_ln = ln;\n                found = true;\n            }\n            \n            pieces = old_pieces;\n            piece_id = old_pid;\n            memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n        }\n        \n        if (!found) break;\n        \n        apply_cut(best_ln);\n        cuts.push_back(best_ln);\n        current_score = best_new_score;\n    }\n    \n    cout << cuts.size() << \"\\n\";\n    for (auto& ln : cuts) {\n        cout << ln.x1 << \" \" << ln.y1 << \" \" << ln.x2 << \" \" << ln.y2 << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint C;                          // centre (N-1)/2\nvector<vector<bool>> has_dot;   // true if a dot exists\n// edge arrays: canonical forms\nvector<vector<bool>> edge_h;    // horizontal (x,y)-(x+1,y)   stored at (x,y)   [0,N-2] x [0,N-1]\nvector<vector<bool>> edge_v;    // vertical   (x,y)-(x,y+1)   stored at (x,y)   [0,N-1] x [0,N-2]\nvector<vector<bool>> edge_d1;   // diagonal / (x,y)-(x+1,y+1) stored at (x,y)   [0,N-2] x [0,N-2]\nvector<vector<bool>> edge_d2;   // diagonal \\ (x,y)-(x+1,y-1) stored at (x,y)   [0,N-2] x [1,N-1]\n\nstruct Operation {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\nvector<Operation> ops;\n\n/*---------------------------------------------------------------*/\n/*  Axis aligned rectangles                                       */\n/*---------------------------------------------------------------*/\nbool check_axis(int x1, int y1, int x2, int y2) {\n    if (x1 == x2 || y1 == y2) return false;\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n\n    // condition 2: no other dots on the perimeter (excluding the four corners)\n    for (int x = xl + 1; x < xr; ++x) if (has_dot[x][yl]) return false;\n    for (int x = xl + 1; x < xr; ++x) if (has_dot[x][yr]) return false;\n    for (int y = yl + 1; y < yr; ++y) if (has_dot[xl][y]) return false;\n    for (int y = yl + 1; y < yr; ++y) if (has_dot[xr][y]) return false;\n\n    // condition 3: edges must be unused\n    for (int x = xl; x < xr; ++x) if (edge_h[x][yl]) return false; // bottom\n    for (int x = xl; x < xr; ++x) if (edge_h[x][yr]) return false; // top\n    for (int y = yl; y < yr; ++y) if (edge_v[xl][y]) return false; // left\n    for (int y = yl; y < yr; ++y) if (edge_v[xr][y]) return false; // right\n\n    return true;\n}\n\nvoid add_axis(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    for (int x = xl; x < xr; ++x) edge_h[x][yl] = true;\n    for (int x = xl; x < xr; ++x) edge_h[x][yr] = true;\n    for (int y = yl; y < yr; ++y) edge_v[xl][y] = true;\n    for (int y = yl; y < yr; ++y) edge_v[xr][y] = true;\n}\n\n/*---------------------------------------------------------------*/\n/*  45 degree rectangles                                          */\n/*---------------------------------------------------------------*/\n// walk from (xs,ys) to (xt,yt) (|dx|=|dy|) and check dots (interior) and edges\nbool walk_check(int xs, int ys, int xt, int yt) {\n    int dx = (xt > xs) ? 1 : -1;\n    int dy = (yt > ys) ? 1 : -1;\n    int len = abs(xt - xs); // = abs(yt-ys)\n\n    // interior dots (exclude both ends)\n    for (int i = 1; i < len; ++i) {\n        int x = xs + i * dx;\n        int y = ys + i * dy;\n        if (has_dot[x][y]) return false;\n    }\n\n    // edges\n    for (int i = 0; i < len; ++i) {\n        int x = xs + i * dx;\n        int y = ys + i * dy;\n        if (dx == dy) { // slope +1  -> edge_d1\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == 1) ? y : y - 1;\n            if (edge_d1[ex][ey]) return false;\n        } else {        // slope -1  -> edge_d2\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == -1) ? y : y + 1;\n            if (edge_d2[ex][ey]) return false;\n        }\n    }\n    return true;\n}\n\n// mark edges of a 45-degree side\nvoid walk_mark(int xs, int ys, int xt, int yt) {\n    int dx = (xt > xs) ? 1 : -1;\n    int dy = (yt > ys) ? 1 : -1;\n    int len = abs(xt - xs);\n    for (int i = 0; i < len; ++i) {\n        int x = xs + i * dx;\n        int y = ys + i * dy;\n        if (dx == dy) {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == 1) ? y : y - 1;\n            edge_d1[ex][ey] = true;\n        } else {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == -1) ? y : y + 1;\n            edge_d2[ex][ey] = true;\n        }\n    }\n}\n\n// p1=(x1,y1) is empty, we look for a 45\u00b0 rectangle using diagonal (x3,y3)\nbool check_45(int x1, int y1, int x3, int y3,\n              int &x2, int &y2, int &x4, int &y4) {\n    int dx = x3 - x1;\n    int dy = y3 - y1;\n    if ( ((dx + dy) & 1) || ((dx - dy) & 1) ) return false; // parity check\n\n    int a = (dx + dy) >> 1;\n    int b = (dx - dy) >> 1;\n    if (a == 0 || b == 0) return false;\n\n    x2 = x1 + a; y2 = y1 + a;\n    x4 = x1 + b; y4 = y1 - b;\n    // bounds check\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) return false;\n    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) return false;\n\n    if (!has_dot[x2][y2] || !has_dot[x4][y4] || !has_dot[x3][y3]) return false;\n\n    // check the four sides\n    if (!walk_check(x1, y1, x2, y2)) return false;\n    if (!walk_check(x2, y2, x3, y3)) return false;\n    if (!walk_check(x3, y3, x4, y4)) return false;\n    if (!walk_check(x4, y4, x1, y1)) return false;\n    return true;\n}\n\nvoid add_45(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    walk_mark(x1, y1, x2, y2);\n    walk_mark(x2, y2, x3, y3);\n    walk_mark(x3, y3, x4, y4);\n    walk_mark(x4, y4, x1, y1);\n}\n\n/*---------------------------------------------------------------*/\n/*  Main                                                          */\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    C = (N - 1) / 2;\n\n    has_dot.assign(N, vector<bool>(N, false));\n    vector<pair<int,int>> dots;\n    dots.reserve(N * N);\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        has_dot[x][y] = true;\n        dots.emplace_back(x, y);\n    }\n\n    edge_h.assign(N, vector<bool>(N, false));\n    edge_v.assign(N, vector<bool>(N, false));\n    edge_d1.assign(N, vector<bool>(N, false));\n    edge_d2.assign(N, vector<bool>(N, false));\n\n    // candidates: empty cells sorted by weight descending\n    vector<tuple<int,int,int>> cand; // (weight, x, y)\n    cand.reserve(N * N);\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            if (!has_dot[x][y]) {\n                int w = (x - C) * (x - C) + (y - C) * (y - C) + 1;\n                cand.emplace_back(w, x, y);\n            }\n    sort(cand.rbegin(), cand.rend());\n\n    // try to fill cells\n    for (auto &[w, x1, y1] : cand) {\n        if (has_dot[x1][y1]) continue; // already filled\n\n        bool placed = false;\n        int bx2, by2, bx3, by3, bx4, by4;\n        bool is_axis = false;\n\n        // shuffle dots to get variety (helps when many choices exist)\n        // Note: we use a fixed seed for reproducibility; the judge accepts any valid solution.\n        static std::mt19937 rng(12345);\n        vector<pair<int,int>> shuffled = dots;\n        shuffle(shuffled.begin(), shuffled.end(), rng);\n\n        // 1) try axis-aligned first (usually more \u201crigid\u201d, leaves diagonals free)\n        for (auto [x3, y3] : shuffled) {\n            if (x3 == x1 || y3 == y1) continue;\n            int x2 = x3, y2 = y1;\n            int x4 = x1, y4 = y3;\n            if (!has_dot[x2][y2] || !has_dot[x4][y4]) continue;\n            if (check_axis(x1, y1, x3, y3)) {\n                placed = true;\n                bx2 = x2; by2 = y2;\n                bx3 = x3; by3 = y3;\n                bx4 = x4; by4 = y4;\n                is_axis = true;\n                break;\n            }\n        }\n\n        // 2) try 45-degree\n        if (!placed) {\n            for (auto [x3, y3] : shuffled) {\n                int tx2, ty2, tx4, ty4;\n                if (check_45(x1, y1, x3, y3, tx2, ty2, tx4, ty4)) {\n                    placed = true;\n                    bx2 = tx2; by2 = ty2;\n                    bx3 = x3;  by3 = y3;\n                    bx4 = tx4; by4 = ty4;\n                    is_axis = false;\n                    break;\n                }\n            }\n        }\n\n        if (placed) {\n            ops.push_back({x1, y1, bx2, by2, bx3, by3, bx4, by4});\n            has_dot[x1][y1] = true;\n            dots.emplace_back(x1, y1);\n            if (is_axis)\n                add_axis(x1, y1, bx3, by3);\n            else\n                add_45(x1, y1, bx2, by2, bx3, by3, bx4, by4);\n        }\n    }\n\n    cout << ops.size() << '\\n';\n    for (auto &op : ops) {\n        cout << op.x1 << ' ' << op.y1 << ' '\n             << op.x2 << ' ' << op.y2 << ' '\n             << op.x3 << ' ' << op.y3 << ' '\n             << op.x4 << ' ' << op.y4 << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed = chrono::steady_clock::now().time_since_epoch().count()) {\n        s = seed;\n    }\n    uint64_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return s;\n    }\n    int randint(int n) {\n        return next() % n;\n    }\n} rng;\n\nstruct Grid {\n    uint8_t a[10][10];\n    \n    Grid() {\n        memset(a, 0, sizeof(a));\n    }\n    \n    void place(int p, int f) {\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void placeRandom(int f, int numEmpty) {\n        int p = rng.randint(numEmpty) + 1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') {\n            for (int j = 0; j < 10; j++) {\n                int write = 0;\n                for (int i = 0; i < 10; i++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write++][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'B') {\n            for (int j = 0; j < 10; j++) {\n                int write = 9;\n                for (int i = 9; i >= 0; i--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write--][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'L') {\n            for (int i = 0; i < 10; i++) {\n                int write = 0;\n                for (int j = 0; j < 10; j++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write++] = val;\n                    }\n                }\n            }\n        } else if (dir == 'R') {\n            for (int i = 0; i < 10; i++) {\n                int write = 9;\n                for (int j = 9; j >= 0; j--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write--] = val;\n                    }\n                }\n            }\n        }\n    }\n    \n    int countEmpty() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++)\n            for (int j = 0; j < 10; j++)\n                if (a[i][j] == 0) cnt++;\n        return cnt;\n    }\n    \n    long long calcScore() const {\n        bool vis[10][10] = {};\n        long long res = 0;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] != 0 && !vis[i][j]) {\n                    uint8_t f = a[i][j];\n                    int sz = 0;\n                    int q[100];\n                    int qe = 0;\n                    q[qe++] = i * 10 + j;\n                    vis[i][j] = true;\n                    \n                    while (qe > 0) {\n                        int cur = q[--qe];\n                        int x = cur / 10, y = cur % 10;\n                        sz++;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !vis[nx][ny] && a[nx][ny] == f) {\n                                vis[nx][ny] = true;\n                                q[qe++] = nx * 10 + ny;\n                            }\n                        }\n                    }\n                    res += 1LL * sz * sz;\n                }\n            }\n        }\n        return res;\n    }\n    \n    // Fast heuristic: count same-flavor adjacent pairs\n    int countEdges() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) continue;\n                if (i < 9 && a[i][j] == a[i+1][j]) cnt++;\n                if (j < 9 && a[i][j] == a[i][j+1]) cnt++;\n            }\n        }\n        return cnt;\n    }\n    \n    // Greedy tilt: choose direction maximizing edges\n    char greedyTilt() {\n        char bestDir = 'F';\n        int bestEdges = -1;\n        char dirs[4] = {'F', 'B', 'L', 'R'};\n        \n        for (int d = 0; d < 4; d++) {\n            Grid tmp = *this;\n            tmp.tilt(dirs[d]);\n            int e = tmp.countEdges();\n            if (e > bestEdges) {\n                bestEdges = e;\n                bestDir = dirs[d];\n            }\n        }\n        return bestDir;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> f[i];\n    }\n    \n    Grid grid;\n    const char dirs[4] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        grid.place(p, f[t]);\n        \n        if (t == 99) {\n            cout << \"F\\n\" << flush;\n            break;\n        }\n        \n        int remaining = 99 - t;\n        // Adaptive samples: more samples early when structure matters\n        int samples = max(15, min(50, 2000 / (remaining + 5)));\n        \n        long long bestTotal = -1;\n        char bestDir = 'F';\n        \n        // Try each direction for the current tilt\n        for (int d = 0; d < 4; d++) {\n            long long totalScore = 0;\n            \n            for (int s = 0; s < samples; s++) {\n                Grid sim = grid;\n                sim.tilt(dirs[d]);\n                int numEmpty = 100 - (t + 1);\n                \n                // Rollout with greedy policy\n                for (int tt = t + 1; tt < 100; tt++) {\n                    sim.placeRandom(f[tt], numEmpty--);\n                    char gdir = sim.greedyTilt();\n                    sim.tilt(gdir);\n                }\n                \n                totalScore += sim.calcScore();\n            }\n            \n            if (totalScore > bestTotal) {\n                bestTotal = totalScore;\n                bestDir = dirs[d];\n            }\n        }\n        \n        cout << bestDir << \"\\n\" << flush;\n        grid.tilt(bestDir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\n\nusing namespace std;\n\nint N, M;\ndouble eps;\n\nstruct Graph {\n    vector<bitset<4950>> adj; // adjacency matrix as bitset per row (max N=100, max edges=4950)\n    vector<int> degree;\n    vector<int> order; // canonical order: permutation to apply to get canonical form\n    string canonical_str; // edge string in canonical order\n};\n\nvector<Graph> graphs;\n\n// Convert (i, j) to index in edge string, assuming i < j\ninline int edge_idx(int i, int j, int n) {\n    return i * n - i * (i + 1) / 2 + (j - i - 1);\n}\n\n// Build canonical string from adjacency matrix (symmetric) and vertex order\nstring build_canonical_string(const vector<bitset<4950>>& adj, const vector<int>& order, int n) {\n    string s;\n    s.reserve(n * (n - 1) / 2);\n    int m = order.size();\n    for (int ii = 0; ii < m; ++ii) {\n        for (int jj = ii + 1; jj < m; ++jj) {\n            int i = order[ii];\n            int j = order[jj];\n            s.push_back(adj[i].test(j) ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Compute degree sequence from adjacency matrix\nvector<int> compute_degrees(const vector<bitset<4950>>& adj, int n) {\n    vector<int> deg(n, 0);\n    for (int i = 0; i < n; ++i) {\n        deg[i] = adj[i].count();\n    }\n    return deg;\n}\n\n// Get canonical order by (degree, sum of neighbor degrees) descending\nvector<int> get_canonical_order(const vector<bitset<4950>>& adj, const vector<int>& deg, int n) {\n    vector<long long> neighbor_sum(n, 0);\n    for (int i = 0; i < n; ++i) {\n        long long sum = 0;\n        for (int j = 0; j < n; ++j) {\n            if (adj[i].test(j)) sum += deg[j];\n        }\n        neighbor_sum[i] = sum;\n    }\n    \n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (deg[a] != deg[b]) return deg[a] > deg[b];\n        if (neighbor_sum[a] != neighbor_sum[b]) return neighbor_sum[a] > neighbor_sum[b];\n        return a < b; // tie-breaker\n    });\n    return order;\n}\n\n// Parse edge string to adjacency matrix\nvector<bitset<4950>> parse_graph(const string& s, int n) {\n    vector<bitset<4950>> adj(n);\n    int pos = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[pos++] == '1') {\n                adj[i].set(j);\n                adj[j].set(i);\n            }\n        }\n    }\n    return adj;\n}\n\n// Hamming distance between two edge strings\nint hamming_dist(const string& a, const string& b) {\n    int dist = 0;\n    // Process 64 bits at a time using uint64_t for speedup if needed, but simple loop is fine for 5000*100*100=50M\n    for (size_t i = 0; i < a.size(); ++i) {\n        dist += (a[i] != b[i]);\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> M >> eps;\n    \n    // Choose N based on epsilon: larger epsilon needs larger N for robustness\n    // Heuristic: N = 30 + 150 * eps, capped at 100, min 20\n    int N_calc = (int)(25 + 160 * eps);\n    N = max(20, min(100, N_calc));\n    if (N < 4) N = 4;\n    \n    // Generate M graphs\n    graphs.resize(M);\n    mt19937 rng(42);\n    \n    for (int idx = 0; idx < M; ++idx) {\n        // Generate random graph G(N, 0.5) with seed = idx\n        mt19937 gen(idx);\n        bernoulli_distribution d(0.5);\n        \n        vector<bitset<4950>> adj(N);\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (d(gen)) {\n                    adj[i].set(j);\n                    adj[j].set(i);\n                }\n            }\n        }\n        \n        graphs[idx].adj = adj;\n        graphs[idx].degree = compute_degrees(adj, N);\n        graphs[idx].order = get_canonical_order(adj, graphs[idx].degree, N);\n        graphs[idx].canonical_str = build_canonical_string(adj, graphs[idx].order, N);\n    }\n    \n    // Output\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << graphs[i].canonical_str << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        // Parse H\n        auto h_adj = parse_graph(h_str, N);\n        auto h_deg = compute_degrees(h_adj, N);\n        auto h_order = get_canonical_order(h_adj, h_deg, N);\n        string h_canonical = build_canonical_string(h_adj, h_order, N);\n        \n        // Find best match by Hamming distance\n        int best_idx = 0;\n        int min_dist = N * N; // large\n        \n        for (int i = 0; i < M; ++i) {\n            int dist = hamming_dist(h_canonical, graphs[i].canonical_str);\n            if (dist < min_dist) {\n                min_dist = dist;\n                best_idx = i;\n            }\n        }\n        \n        cout << best_idx << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    // Read coordinates (not used but need to consume input)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    const long long INF = (long long)1e12;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Compute all-pairs shortest paths\n    vector<vector<long long>> dist(N, vector<long long>(N, INF));\n    for (int s = 0; s < N; s++) {\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        dist[s][s] = 0;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[s][u]) continue;\n            for (auto [v, eid] : adj[u]) {\n                int w = edges[eid].w;\n                if (dist[s][v] > d + w) {\n                    dist[s][v] = d + w;\n                    pq.push({dist[s][v], v});\n                }\n            }\n        }\n    }\n    \n    // Compute edge criticality using sampling (approximate betweenness)\n    vector<double> crit(M, 0.0);\n    const int NUM_SAMPLES = 150;\n    vector<int> samples;\n    for (int i = 0; i < NUM_SAMPLES; i++) samples.push_back(rng() % N);\n    \n    for (int s : samples) {\n        for (int i = 0; i < M; i++) {\n            int u = edges[i].u, v = edges[i].v, w = edges[i].w;\n            // Check if edge i is on any shortest path from s\n            if ((dist[s][u] + w == dist[s][v]) || (dist[s][v] + w == dist[s][u])) {\n                crit[i] += 1.0;\n            }\n        }\n    }\n    \n    // Normalize criticality\n    double max_crit = *max_element(crit.begin(), crit.end());\n    if (max_crit > 0) {\n        for (int i = 0; i < M; i++) crit[i] /= max_crit;\n    }\n    \n    // Build adjacency between edges (share a vertex)\n    vector<vector<int>> edge_adj(M);\n    vector<vector<int>> vertex_edges(N);\n    for (int i = 0; i < M; i++) {\n        vertex_edges[edges[i].u].push_back(i);\n        vertex_edges[edges[i].v].push_back(i);\n    }\n    for (int i = 0; i < M; i++) {\n        unordered_set<int> neigh;\n        for (int v : {edges[i].u, edges[i].v}) {\n            for (int e : vertex_edges[v]) {\n                if (e != i) neigh.insert(e);\n            }\n        }\n        edge_adj[i] = vector<int>(neigh.begin(), neigh.end());\n    }\n    \n    // Initial solution: greedy assignment balancing criticality\n    vector<int> assign(M, -1);\n    vector<vector<int>> day_edges(D);\n    vector<double> day_crit(D, 0.0);\n    vector<int> day_adj_count(D, 0); // count of adjacent pairs within the day\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return crit[a] > crit[b];\n    });\n    \n    for (int eid : order) {\n        int best_day = -1;\n        double best_cost = 1e300;\n        for (int d = 0; d < D; d++) {\n            if ((int)day_edges[d].size() >= K) continue;\n            // Cost if we add eid to day d\n            double new_crit = day_crit[d] + crit[eid];\n            // Count adjacent edges already in day d\n            int adj_cnt = 0;\n            for (int other : edge_adj[eid]) {\n                if (assign[other] == d) adj_cnt++;\n            }\n            // Penalize high criticality and adjacency\n            double cost = new_crit * new_crit + 10.0 * adj_cnt;\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_day = d;\n            }\n        }\n        if (best_day == -1) {\n            // Fallback: find any day with space\n            for (int d = 0; d < D; d++) {\n                if ((int)day_edges[d].size() < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n        }\n        assign[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_crit[best_day] += crit[eid];\n        for (int other : edge_adj[eid]) {\n            if (assign[other] == best_day) day_adj_count[best_day]++;\n        }\n    }\n    \n    // Simulated Annealing\n    auto compute_day_cost = [&](int d) -> double {\n        return day_crit[d] * day_crit[d] + 5.0 * day_adj_count[d];\n    };\n    \n    auto current_cost = [&]() -> double {\n        double total = 0;\n        for (int d = 0; d < D; d++) total += compute_day_cost(d);\n        return total;\n    };\n    \n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 5.5;\n    \n    double T = 100.0;\n    const double T_min = 0.01;\n    const double cooling = 0.9999;\n    \n    double curr_cost = current_cost();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Pick two random edges from different days\n        int e1 = rng() % M;\n        int d1 = assign[e1];\n        int e2;\n        int d2;\n        int attempts = 0;\n        do {\n            e2 = rng() % M;\n            d2 = assign[e2];\n            attempts++;\n        } while (d1 == d2 && attempts < 10);\n        if (d1 == d2) continue;\n        \n        // Compute delta if we swap e1 and e2\n        double old_cost = compute_day_cost(d1) + compute_day_cost(d2);\n        \n        // Remove e1 from d1, add e2 to d1\n        // Remove e2 from d2, add e1 to d2\n        double crit1 = day_crit[d1] - crit[e1] + crit[e2];\n        double crit2 = day_crit[d2] - crit[e2] + crit[e1];\n        \n        // Count adjacency changes\n        int adj1 = day_adj_count[d1];\n        int adj2 = day_adj_count[d2];\n        \n        // Remove contributions of e1 from d1's adj count\n        for (int other : edge_adj[e1]) {\n            if (other != e2 && assign[other] == d1) adj1--;\n        }\n        // Remove contributions of e2 from d2's adj count  \n        for (int other : edge_adj[e2]) {\n            if (other != e1 && assign[other] == d2) adj2--;\n        }\n        \n        // Add e2 to d1\n        for (int other : edge_adj[e2]) {\n            if (other != e1 && assign[other] == d1) adj1++;\n        }\n        // Add e1 to d2\n        for (int other : edge_adj[e1]) {\n            if (other != e2 && assign[other] == d2) adj2++;\n        }\n        \n        double new_cost = crit1 * crit1 + 5.0 * adj1 + crit2 * crit2 + 5.0 * adj2;\n        double delta = new_cost - old_cost;\n        \n        if (delta < 0 || (T > 0 && (double)rng() / UINT_MAX < exp(-delta / T))) {\n            // Accept swap\n            // Update day_edges lists (inefficient but okay for small K)\n            auto& v1 = day_edges[d1];\n            auto& v2 = day_edges[d2];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            auto it2 = find(v2.begin(), v2.end(), e2);\n            if (it1 != v1.end() && it2 != v2.end()) {\n                *it1 = e2;\n                *it2 = e1;\n                assign[e1] = d2;\n                assign[e2] = d1;\n                day_crit[d1] = crit1;\n                day_crit[d2] = crit2;\n                day_adj_count[d1] = adj1;\n                day_adj_count[d2] = adj2;\n                curr_cost += delta;\n            }\n        }\n        \n        T *= cooling;\n        if (T < T_min) T = T_min;\n    }\n    \n    // Final local search: try to move single edges to reduce max load\n    for (int iter = 0; iter < 10000; iter++) {\n        int heavy_day = max_element(day_crit.begin(), day_crit.end()) - day_crit.begin();\n        if (day_edges[heavy_day].empty()) continue;\n        \n        int e = day_edges[heavy_day][rng() % day_edges[heavy_day].size()];\n        int best_target = -1;\n        double best_improvement = 0;\n        \n        for (int d = 0; d < D; d++) {\n            if (d == heavy_day) continue;\n            if ((int)day_edges[d].size() >= K) continue;\n            \n            double new_crit_heavy = day_crit[heavy_day] - crit[e];\n            double new_crit_target = day_crit[d] + crit[e];\n            double improvement = (day_crit[heavy_day] * day_crit[heavy_day] + day_crit[d] * day_crit[d]) \n                               - (new_crit_heavy * new_crit_heavy + new_crit_target * new_crit_target);\n            \n            // Small penalty for adjacency in target\n            int extra_adj = 0;\n            for (int other : edge_adj[e]) {\n                if (assign[other] == d) extra_adj++;\n            }\n            improvement -= 5.0 * extra_adj;\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_target = d;\n            }\n        }\n        \n        if (best_target != -1 && best_improvement > 0) {\n            // Move e from heavy_day to best_target\n            auto& vh = day_edges[heavy_day];\n            vh.erase(remove(vh.begin(), vh.end(), e), vh.end());\n            day_edges[best_target].push_back(e);\n            \n            // Update adj counts\n            for (int other : edge_adj[e]) {\n                if (assign[other] == heavy_day) day_adj_count[heavy_day]--;\n                if (assign[other] == best_target) day_adj_count[best_target]++;\n            }\n            \n            day_crit[heavy_day] -= crit[e];\n            day_crit[best_target] += crit[e];\n            assign[e] = best_target;\n        }\n    }\n    \n    // Verify constraints\n    for (int d = 0; d < D; d++) {\n        if ((int)day_edges[d].size() > K) {\n            // This shouldn't happen, but fix if it does\n            while ((int)day_edges[d].size() > K) {\n                int e = day_edges[d].back();\n                for (int d2 = 0; d2 < D; d2++) {\n                    if ((int)day_edges[d2].size() < K) {\n                        day_edges[d].pop_back();\n                        day_edges[d2].push_back(e);\n                        assign[e] = d2;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << assign[i] + 1;\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<array<array<int,3>,3>> rotations;\n\nvoid init_rotations() {\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int parity[6] = {1, -1, -1, 1, 1, -1};\n    for (int p=0; p<6; p++) {\n        for (int sx : {1, -1}) {\n            for (int sy : {1, -1}) {\n                for (int sz : {1, -1}) {\n                    if (sx * sy * sz * parity[p] == 1) {\n                        array<array<int,3>,3> mat = {};\n                        mat[0][perms[p][0]] = sx;\n                        mat[1][perms[p][1]] = sy;\n                        mat[2][perms[p][2]] = sz;\n                        rotations.push_back(mat);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvector<array<int,3>> normalize_shape(vector<array<int,3>> cells) {\n    if (cells.empty()) return cells;\n    int minx = 1e9, miny = 1e9, minz = 1e9;\n    for (auto& c : cells) {\n        minx = min(minx, c[0]);\n        miny = min(miny, c[1]);\n        minz = min(minz, c[2]);\n    }\n    for (auto& c : cells) {\n        c[0] -= minx;\n        c[1] -= miny;\n        c[2] -= minz;\n    }\n    vector<vector<array<int,3>>> candidates;\n    for (auto& rot : rotations) {\n        vector<array<int,3>> cur;\n        for (auto& c : cells) {\n            int x = c[0], y = c[1], z = c[2];\n            int nx = rot[0][0]*x + rot[0][1]*y + rot[0][2]*z;\n            int ny = rot[1][0]*x + rot[1][1]*y + rot[1][2]*z;\n            int nz = rot[2][0]*x + rot[2][1]*y + rot[2][2]*z;\n            cur.push_back({nx, ny, nz});\n        }\n        int mix = 1e9, miy = 1e9, miz = 1e9;\n        for (auto& c : cur) {\n            mix = min(mix, c[0]);\n            miy = min(miy, c[1]);\n            miz = min(miz, c[2]);\n        }\n        for (auto& c : cur) {\n            c[0] -= mix;\n            c[1] -= miy;\n            c[2] -= miz;\n        }\n        sort(cur.begin(), cur.end());\n        candidates.push_back(cur);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\nstruct Component {\n    vector<array<int,3>> cells;\n    vector<array<int,3>> shape;\n    int id;\n};\n\nvector<Component> extract_components(const vector<vector<vector<bool>>>& valid) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<Component> comps;\n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid[x][y][z] && !vis[x][y][z]) {\n                    Component comp;\n                    queue<array<int,3>> q;\n                    q.push({x,y,z});\n                    vis[x][y][z] = true;\n                    while (!q.empty()) {\n                        auto cur = q.front(); q.pop();\n                        comp.cells.push_back(cur);\n                        int cx=cur[0], cy=cur[1], cz=cur[2];\n                        for (int dir=0; dir<6; dir++) {\n                            int nx=cx+dx[dir], ny=cy+dy[dir], nz=cz+dz[dir];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && valid[nx][ny][nz] && !vis[nx][ny][nz]) {\n                                vis[nx][ny][nz] = true;\n                                q.push({nx,ny,nz});\n                            }\n                        }\n                    }\n                    comp.shape = normalize_shape(comp.cells);\n                    comps.push_back(comp);\n                }\n            }\n        }\n    }\n    return comps;\n}\n\nvoid reduce_set(vector<vector<vector<bool>>>& cells, \n                const vector<vector<vector<bool>>>& base,\n                const vector<string>& f, const vector<string>& r) {\n    // cells: R1 or R2 (modifiable)\n    // base: C (fixed, provides coverage)\n    vector<vector<int>> front(D, vector<int>(D, 0));\n    vector<vector<int>> right(D, vector<int>(D, 0));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (base[x][y][z] || cells[x][y][z]) {\n                    front[z][x]++;\n                    right[z][y]++;\n                }\n            }\n        }\n    }\n    \n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int x=0; x<D; x++) {\n            for (int y=0; y<D; y++) {\n                for (int z=0; z<D; z++) {\n                    if (!cells[x][y][z]) continue;\n                    if (front[z][x] > 1 && right[z][y] > 1) {\n                        cells[x][y][z] = false;\n                        front[z][x]--;\n                        right[z][y]--;\n                        changed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotations();\n    \n    cin >> D;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i=0; i<2; i++) {\n        for (int j=0; j<D; j++) cin >> f[i][j];\n        for (int j=0; j<D; j++) cin >> r[i][j];\n    }\n    \n    vector<vector<vector<bool>>> P1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> P2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1') P1[x][y][z] = true;\n                if (f[1][z][x] == '1' && r[1][z][y] == '1') P2[x][y][z] = true;\n            }\n        }\n    }\n    \n    // Compute intersection C and differences R1, R2\n    vector<vector<vector<bool>>> C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (P1[x][y][z] && P2[x][y][z]) C[x][y][z] = true;\n                else if (P1[x][y][z]) R1[x][y][z] = true;\n                else if (P2[x][y][z]) R2[x][y][z] = true;\n            }\n        }\n    }\n    \n    // Reduce R1 and R2\n    reduce_set(R1, C, f[0], r[0]);\n    reduce_set(R2, C, f[1], r[1]);\n    \n    // Extract components\n    auto compsC = extract_components(C);\n    auto compsR1 = extract_components(R1);\n    auto compsR2 = extract_components(R2);\n    \n    int n = 0;\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto idx = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n    \n    // Assign shared blocks from C\n    for (auto& comp : compsC) {\n        n++;\n        for (auto& c : comp.cells) {\n            b1[idx(c[0], c[1], c[2])] = n;\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    // Match R1 and R2 components\n    map<vector<array<int,3>>, vector<Component*>> shape_map;\n    for (auto& comp : compsR1) {\n        shape_map[comp.shape].push_back(&comp);\n    }\n    \n    vector<Component*> unmatched_R2;\n    for (auto& comp : compsR2) {\n        auto& vec = shape_map[comp.shape];\n        if (!vec.empty()) {\n            Component* c1 = vec.back();\n            vec.pop_back();\n            n++;\n            for (auto& c : c1->cells) b1[idx(c[0], c[1], c[2])] = n;\n            for (auto& c : comp.cells) b2[idx(c[0], c[1], c[2])] = n;\n        } else {\n            unmatched_R2.push_back(&comp);\n        }\n    }\n    \n    // Output remaining R1\n    for (auto& [shape, vec] : shape_map) {\n        for (auto* comp : vec) {\n            n++;\n            for (auto& c : comp->cells) b1[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    // Output remaining R2\n    for (auto* comp : unmatched_R2) {\n        n++;\n        for (auto& c : comp->cells) b2[idx(c[0], c[1], c[2])] = n;\n    }\n    \n    cout << n << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b2[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {int x, y;};\nstruct Edge{int u, v; int w;};\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    void unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a!=b) p[a]=b;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<Point> V(N);\n    for(int i=0;i<N;i++) cin>>V[i].x>>V[i].y;\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++) {\n        int u,v,w;\n        cin>>u>>v>>w;\n        u--; v--;\n        edges[i] = {u,v,w};\n        adj[u].push_back({v,i});\n        adj[v].push_back({u,i});\n    }\n    vector<Point> R(K);\n    for(int i=0;i<K;i++) cin>>R[i].x>>R[i].y;\n    \n    const int COVER_DIST2 = 5000*5000;\n    const long long INF = (1LL<<60);\n    \n    // Precompute shortest paths between vertices (Dijkstra from each)\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    vector<vector<int>> parent_edge(N, vector<int>(N, -1)); // edge id to parent in Dijkstra tree from s\n    \n    for(int s=0; s<N; s++) {\n        distV[s][s] = 0;\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u] = pq.top(); pq.pop();\n            if(d!=distV[s][u]) continue;\n            for(auto [v,eid]: adj[u]){\n                long long nd = d + edges[eid].w;\n                if(nd < distV[s][v]){\n                    distV[s][v] = nd;\n                    parent_edge[s][v] = eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // Precompute resident-vertex distances and required P\n    vector<vector<int>> resVdist2(K, vector<int>(N));\n    vector<vector<int>> needP(K, vector<int>(N));\n    for(int i=0;i<K;i++){\n        for(int j=0;j<N;j++){\n            long long dx = (long long)R[i].x - V[j].x;\n            long long dy = (long long)R[i].y - V[j].y;\n            int d2 = (int)(dx*dx + dy*dy);\n            resVdist2[i][j] = d2;\n            needP[i][j] = (int)ceil(sqrt((double)d2) - 1e-9);\n        }\n    }\n    \n    // Evaluation function: returns {cost, feasible}\n    auto evaluate = [&](const vector<int>& S)->pair<long long,bool>{\n        int sz = (int)S.size();\n        if(sz==0) return {INF,false};\n        vector<int> maxP(N,0);\n        // Assign each resident to closest vertex in S\n        for(int r=0;r<K;r++){\n            int bestv = -1;\n            int bestd2 = COVER_DIST2+1;\n            for(int v: S){\n                if(resVdist2[r][v] < bestd2){\n                    bestd2 = resVdist2[r][v];\n                    bestv = v;\n                }\n            }\n            if(bestv==-1 || bestd2 > COVER_DIST2) return {INF,false};\n            int p = needP[r][bestv];\n            if(p>5000) return {INF,false};\n            maxP[bestv] = max(maxP[bestv], p);\n        }\n        long long fac_cost = 0;\n        for(int v: S) fac_cost += 1LL*maxP[v]*maxP[v];\n        \n        // Tree cost: MST on S using metric distV\n        long long tree_cost = 0;\n        if(sz>1){\n            vector<bool> used(sz,false);\n            used[0] = true;\n            for(int iter=1; iter<sz; iter++){\n                long long best = INF;\n                int bestj = -1;\n                for(int i=0;i<sz;i++) if(used[i]){\n                    for(int j=0;j<sz;j++) if(!used[j]){\n                        long long d = distV[S[i]][S[j]];\n                        if(d < best){\n                            best = d;\n                            bestj = j;\n                        }\n                    }\n                }\n                if(bestj==-1) return {INF,false};\n                tree_cost += best;\n                used[bestj] = true;\n            }\n        }\n        return {tree_cost + fac_cost, true};\n    };\n    \n    // Precompute which residents each vertex can cover\n    vector<vector<int>> covResidents(N);\n    for(int v=0;v<N;v++){\n        for(int r=0;r<K;r++){\n            if(resVdist2[r][v] <= COVER_DIST2) covResidents[v].push_back(r);\n        }\n    }\n    \n    // Initial greedy solution (set cover with connection heuristic)\n    vector<int> S;\n    vector<bool> inS(N,false);\n    S.push_back(0);\n    inS[0] = true;\n    vector<bool> covered(K,false);\n    \n    while(true){\n        bool all = true;\n        for(bool c: covered) if(!c){all=false; break;}\n        if(all) break;\n        \n        int bestv = -1;\n        double best_score = -1.0;\n        long long best_conn = INF;\n        \n        for(int v=0; v<N; v++) if(!inS[v]){\n            // Newly covered residents\n            int newly = 0;\n            int max_need = 0;\n            for(int r: covResidents[v]){\n                if(!covered[r]){\n                    newly++;\n                    max_need = max(max_need, needP[r][v]);\n                }\n            }\n            if(newly==0) continue;\n            // Connection cost to current S\n            long long conn = INF;\n            for(int u: S) conn = min(conn, distV[u][v]);\n            long long total_cost = conn + 1LL*max_need*max_need;\n            double score = (double)newly / (double)total_cost;\n            if(score > best_score){\n                best_score = score;\n                bestv = v;\n                best_conn = conn;\n            }\n        }\n        \n        if(bestv==-1) break; // Should not happen due to problem guarantee\n        \n        inS[bestv] = true;\n        S.push_back(bestv);\n        for(int r: covResidents[bestv]){\n            covered[r] = true;\n        }\n    }\n    \n    // Ensure all covered (safety)\n    for(int r=0;r<K;r++){\n        bool ok=false;\n        for(int v: S) if(resVdist2[r][v]<=COVER_DIST2){ok=true; break;}\n        if(!ok){\n            // Add best vertex for this resident\n            int bestv=-1, bestd2=COVER_DIST2+1;\n            for(int v=0;v<N;v++) if(!inS[v] && resVdist2[r][v]<bestd2){\n                bestd2=resVdist2[r][v]; bestv=v;\n            }\n            if(bestv!=-1){\n                inS[bestv]=true;\n                S.push_back(bestv);\n            }\n        }\n    }\n    \n    // Local search (hill climbing)\n    bool improved = true;\n    auto [cur_cost, _] = evaluate(S);\n    \n    for(int iter=0; iter<200 && improved; iter++){\n        improved = false;\n        // Try remove\n        for(size_t i=0;i<S.size();i++){\n            if(S[i]==0) continue; // cannot remove root\n            vector<int> S2 = S;\n            S2.erase(S2.begin()+i);\n            auto [c2,f2] = evaluate(S2);\n            if(f2 && c2 < cur_cost){\n                inS[S[i]] = false;\n                S = S2;\n                cur_cost = c2;\n                improved = true;\n                break;\n            }\n        }\n        if(improved) continue;\n        // Try add\n        for(int v=0;v<N;v++) if(!inS[v]){\n            vector<int> S2 = S;\n            S2.push_back(v);\n            auto [c2,f2] = evaluate(S2);\n            if(f2 && c2 < cur_cost){\n                inS[v] = true;\n                S = S2;\n                cur_cost = c2;\n                improved = true;\n                break;\n            }\n        }\n    }\n    \n    // Build final output\n    int sz = S.size();\n    vector<int> P(N,0);\n    // Assign residents to compute P\n    for(int r=0;r<K;r++){\n        int bestv=-1, bestd2=COVER_DIST2+1;\n        for(int v: S){\n            if(resVdist2[r][v] < bestd2){\n                bestd2 = resVdist2[r][v];\n                bestv = v;\n            }\n        }\n        if(bestv!=-1){\n            P[bestv] = max(P[bestv], needP[r][bestv]);\n        }\n    }\n    \n    // Build tree edges via MST on metric closure\n    vector<int> B(M,0);\n    if(sz>1){\n        // Prim on S to get metric MST edges\n        vector<long long> min_edge(sz, INF);\n        vector<bool> used(sz,false);\n        vector<int> parent_metric(sz,-1);\n        min_edge[0]=0;\n        for(int iter=0; iter<sz; iter++){\n            int v=-1;\n            for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_edge[i]<min_edge[v])) v=i;\n            used[v]=true;\n            for(int i=0;i<sz;i++) if(!used[i]){\n                long long d = distV[S[v]][S[i]];\n                if(d < min_edge[i]){\n                    min_edge[i]=d;\n                    parent_metric[i]=v;\n                }\n            }\n        }\n        \n        // Collect edges from paths\n        vector<bool> edge_active(M,false);\n        for(int i=1;i<sz;i++){\n            int u = S[parent_metric[i]];\n            int v = S[i];\n            // Trace back from v to u in Dijkstra tree of u\n            int cur = v;\n            while(cur != u){\n                int e = parent_edge[u][cur];\n                if(e==-1) break; // should not happen\n                edge_active[e] = true;\n                int pu = edges[e].u == cur ? edges[e].v : edges[e].u;\n                cur = pu;\n            }\n        }\n        \n        // MST on the active edges to get tree\n        vector<int> active_list;\n        for(int i=0;i<M;i++) if(edge_active[i]) active_list.push_back(i);\n        sort(active_list.begin(), active_list.end(), [&](int a, int b){return edges[a].w < edges[b].w;});\n        \n        DSU dsu(N);\n        for(int e: active_list){\n            int u=edges[e].u, v=edges[e].v;\n            if(dsu.find(u)!=dsu.find(v)){\n                dsu.unite(u,v);\n                B[e]=1;\n            }\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int i=0;i<M;i++){\n        if(i) cout << ' ';\n        cout << B[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    const int BALLS = N * (N + 1) / 2; // 465\n    \n    // grid[x][y] = current value at (x,y)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // pos[v] = current coordinates of value v\n    vector<pair<int,int>> pos(BALLS);\n    \n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v; \n            if(!(cin >> v)) return 0;\n            grid[x][y] = v;\n            pos[v] = {x, y};\n        }\n    }\n    \n    vector<array<int,4>> ops;\n    vector<vector<bool>> fixed(N, vector<bool>(N, false));\n    \n    // Process from bottom-right to top-left\n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = x; y >= 0; --y) {\n            int target_val = x * (x + 1) / 2 + y;\n            auto [cx, cy] = pos[target_val];\n            \n            // Route the ball to (x,y) through the unfixed region\n            while (cx != x || cy != y) {\n                int nx, ny;\n                if (cx < x) {\n                    if (cy > y) {\n                        // Need to decrease y first (move left)\n                        nx = cx;\n                        ny = cy - 1;\n                    } else if (cy < y) {\n                        // Can go down-right\n                        nx = cx + 1;\n                        ny = cy + 1;\n                    } else { // cy == y\n                        // Go down-left\n                        nx = cx + 1;\n                        ny = cy;\n                    }\n                } else if (cx > x) {\n                    // This case should not appear with the processing order,\n                    // but we keep it for safety.\n                    if (cy > y) {\n                        nx = cx - 1;\n                        ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx - 1;\n                        ny = cy;\n                    } else {\n                        nx = cx - 1;\n                        ny = cy;\n                    }\n                } else { // cx == x\n                    if (cy < y) {\n                        // Move right along the row\n                        nx = cx;\n                        ny = cy + 1;\n                    } else {\n                        // cy > y, should not happen\n                        nx = cx;\n                        ny = cy - 1;\n                    }\n                }\n                \n                // Perform the swap\n                int v1 = grid[cx][cy];\n                int v2 = grid[nx][ny];\n                \n                swap(grid[cx][cy], grid[nx][ny]);\n                pos[v1] = {nx, ny};\n                pos[v2] = {cx, cy};\n                \n                ops.push_back({cx, cy, nx, ny});\n                \n                cx = nx;\n                cy = ny;\n            }\n            \n            fixed[x][y] = true;\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op[0] << ' ' << op[1] << ' ' << op[2] << ' ' << op[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D;\n    int N;\n    if (!(cin >> D >> N)) return 0;\n    \n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    \n    const int si = 0;\n    const int sj = (D - 1) / 2;\n    const int M = D * D - 1 - N;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // BFS to compute distances from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (dist[ni][nj] != -1) continue;\n            dist[ni][nj] = dist[i][j] + 1;\n            q.push({ni, nj});\n        }\n    }\n    \n    // Collect valid cells (non-entrance, non-obstacle)\n    vector<pair<int, int>> cells;\n    cells.reserve(M);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == si && j == sj) continue;\n            if (obstacle[i][j]) continue;\n            cells.push_back({i, j});\n        }\n    }\n    \n    // Sort by distance descending (farther cells first)\n    sort(cells.begin(), cells.end(), [&](const pair<int, int> &a, const pair<int, int> &b) {\n        return dist[a.first][a.second] > dist[b.first][b.second];\n    });\n    \n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    vector<vector<int>> value_at(D, vector<int>(D, -1));\n    \n    // Helper to check if a cell is on the frontier (adjacent to entrance or occupied)\n    auto is_frontier = [&](int i, int j) -> bool {\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni == si && nj == sj) return true;\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && occupied[ni][nj]) return true;\n        }\n        return false;\n    };\n    \n    // Helper to compute reachability from entrance through empty cells\n    auto compute_reachable = [&]() -> vector<vector<bool>> {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        vis[si][sj] = true;\n        qq.push({si, sj});\n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (vis[ni][nj]) continue;\n                vis[ni][nj] = true;\n                qq.push({ni, nj});\n            }\n        }\n        return vis;\n    };\n    \n    // Online placement phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        \n        // Target index in the sorted cells array\n        // Small t should be placed near the end (close to entrance)\n        // Large t should be placed near the beginning (far from entrance)\n        int target_idx = M - 1 - t;\n        \n        auto reachable = compute_reachable();\n        pair<int, int> chosen = {-1, -1};\n        int best_delta = M + 1;\n        \n        // Find reachable frontier cell with index closest to target_idx\n        for (int idx = 0; idx < M; idx++) {\n            auto [i, j] = cells[idx];\n            if (occupied[i][j]) continue;\n            if (!reachable[i][j]) continue;\n            if (!is_frontier(i, j)) continue;\n            \n            int delta = abs(idx - target_idx);\n            if (delta < best_delta) {\n                best_delta = delta;\n                chosen = {i, j};\n            }\n        }\n        \n        // Fallback: should not happen if logic is correct, but take any reachable\n        if (chosen.first == -1) {\n            for (int idx = 0; idx < M; idx++) {\n                auto [i, j] = cells[idx];\n                if (occupied[i][j]) continue;\n                if (!reachable[i][j]) continue;\n                chosen = {i, j};\n                break;\n            }\n        }\n        \n        occupied[chosen.first][chosen.second] = true;\n        value_at[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << \"\\n\";\n    }\n    \n    // Retrieval phase: greedy using priority queue (always take smallest available value)\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[si][sj] = true;\n    \n    using State = pair<int, pair<int, int>>; // (value, position)\n    priority_queue<State, vector<State>, greater<State>> pq;\n    \n    // Initialize with cells adjacent to entrance\n    for (int k = 0; k < 4; k++) {\n        int ni = si + di[k], nj = sj + dj[k];\n        if (ni >= 0 && ni < D && nj >= 0 && nj < D && value_at[ni][nj] != -1) {\n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    }\n    \n    vector<pair<int, int>> retrieval_order;\n    retrieval_order.reserve(M);\n    vector<vector<bool>> retrieved(D, vector<bool>(D, false));\n    \n    while (!pq.empty()) {\n        auto [val, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        \n        if (retrieved[i][j]) continue; // Skip if already processed\n        \n        retrieved[i][j] = true;\n        is_empty[i][j] = true;\n        retrieval_order.push_back(pos);\n        \n        // Add neighbors that now become accessible\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (is_empty[ni][nj]) continue;      // Already empty\n            if (retrieved[ni][nj]) continue;     // Already retrieved\n            if (value_at[ni][nj] == -1) continue; // No container there\n            \n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    }\n    \n    // Output retrieval order\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc024":"","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    vector<double> score(N, 1.0);  // Estimated weight for each item\n    vector<int> belong(N, 0);      // Current group assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    auto do_query = [&](const vector<int>& L, const vector<int>& R) -> char {\n        cout << L.size() << \" \" << R.size();\n        for (int x : L) cout << \" \" << x;\n        for (int x : R) cout << \" \" << x;\n        cout << endl;\n        char res;\n        cin >> res;\n        return res;\n    };\n    \n    // Determine query budget for each phase\n    // Phase 1: Estimate weights via pairwise comparisons\n    // Phase 3: Refine partition by comparing groups and swapping\n    int refine_budget = 0;\n    if (Q > 150) {\n        refine_budget = min(Q / 3, 600);  // Reserve up to 1/3 or 600 for refinement\n    }\n    int phase1_budget = Q - refine_budget;\n    \n    // Phase 1: Pairwise comparisons to estimate relative weights\n    // First, ensure every item is compared at least once (connectivity)\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; i++) {\n        pairs.emplace_back(i, (i + 1) % N);\n    }\n    // Add random pairs for remaining budget\n    while ((int)pairs.size() < phase1_budget) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a != b) {\n            if (a > b) swap(a, b);\n            pairs.emplace_back(a, b);\n        }\n    }\n    shuffle(pairs.begin(), pairs.end(), rng);\n    \n    for (int q = 0; q < phase1_budget && q < (int)pairs.size(); q++) {\n        auto [a, b] = pairs[q];\n        char res = do_query({a}, {b});\n        const double delta = 1.0;\n        if (res == '>') {\n            score[a] += delta;\n            score[b] -= delta;\n        } else if (res == '<') {\n            score[a] -= delta;\n            score[b] += delta;\n        }\n    }\n    \n    // Normalize scores to positive values\n    double min_score = *min_element(score.begin(), score.end());\n    for (double& s : score) {\n        s = s - min_score + 1.0;\n    }\n    \n    // Phase 2: Initial partition using LPT (Longest Processing Time) rule\n    // Sort items by estimated weight descending\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    vector<double> group_sum(D, 0.0);\n    for (int idx : items) {\n        // Assign to the currently lightest group\n        int best_g = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_g]) best_g = g;\n        }\n        belong[idx] = best_g;\n        group_sum[best_g] += score[idx];\n    }\n    \n    // Phase 3: Refinement using remaining queries\n    // Compare heavy vs light groups and swap items to balance\n    for (int q = phase1_budget; q < Q; q++) {\n        // Find currently heaviest and lightest groups by estimate\n        int heavy_g = max_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        int light_g = min_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        \n        if (heavy_g == light_g) break;  // Already balanced\n        \n        // Collect items in these groups\n        vector<int> heavy_items, light_items;\n        for (int i = 0; i < N; i++) {\n            if (belong[i] == heavy_g) heavy_items.push_back(i);\n            else if (belong[i] == light_g) light_items.push_back(i);\n        }\n        \n        if (heavy_items.empty() || light_items.empty()) continue;\n        \n        // Pick candidate items: heaviest in heavy group, lightest in light group\n        int h_item = *max_element(heavy_items.begin(), heavy_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        int l_item = *min_element(light_items.begin(), light_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        \n        // Compare the two groups to check actual imbalance direction\n        char res = do_query(heavy_items, light_items);\n        \n        // Also update individual scores based on group comparison (small adjustment)\n        const double eps = 0.1;\n        if (res == '>') {\n            // Heavy group is indeed heavier\n            for (int x : heavy_items) score[x] += eps;\n            for (int x : light_items) score[x] -= eps;\n            \n            // Swap heaviest from heavy with lightest from light\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else if (res == '<') {\n            // Opposite of estimate: light group is actually heavier\n            for (int x : heavy_items) score[x] -= eps;\n            for (int x : light_items) score[x] += eps;\n            \n            // Swap in opposite direction (move \"light\" from heavy to light, \"heavy\" from light to heavy)\n            // Actually, swap the candidates we picked (which might be wrong, but let's swap anyway to fix)\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else {\n            // Equal, do a random beneficial swap or nothing\n            // Swap to explore\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        }\n    }\n    \n    // Output final partition\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << belong[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> st(m);\n    vector<int> pos(n + 1); // pos[v] = which stack (0-indexed) contains v\n    \n    for (int i = 0; i < m; ++i) {\n        int h = n / m;\n        for (int j = 0; j < h; ++j) {\n            int x; \n            cin >> x;\n            st[i].push_back(x);\n            pos[x] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops; // (v, i). i=0 for removal, else 1-indexed destination stack\n    \n    for (int target = 1; target <= n; ++target) {\n        int s = pos[target];\n        \n        // Find position of target in its stack\n        int idx = -1;\n        for (int i = 0; i < (int)st[s].size(); ++i) {\n            if (st[s][i] == target) {\n                idx = i;\n                break;\n            }\n        }\n        \n        // Move boxes above target until it becomes the top\n        while (idx < (int)st[s].size() - 1) {\n            int w = st[s].back(); // current top, will become top of moved segment\n            \n            int best_d = -1;\n            int min_valid_top = INT_MAX;\n            int max_top = -1;\n            \n            for (int d = 0; d < m; ++d) {\n                if (d == s) continue;\n                if (st[d].empty()) {\n                    best_d = d;          // empty is ideal\n                    break;\n                }\n                int top_d = st[d].back();\n                if (top_d > w) {         // valid: won't block existing top\n                    if (top_d < min_valid_top) {\n                        min_valid_top = top_d;\n                        best_d = d;\n                    }\n                }\n                if (top_d > max_top) {\n                    max_top = top_d;\n                }\n            }\n            \n            if (best_d == -1) {          // no empty and no valid top>w\n                for (int d = 0; d < m; ++d) {\n                    if (d == s) continue;\n                    if (st[d].back() == max_top) {\n                        best_d = d;\n                        break;\n                    }\n                }\n            }\n            \n            // The box immediately above target\n            int u = st[s][idx + 1];\n            \n            // Perform move: take suffix starting at idx+1\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            st[s].resize(idx + 1);\n            \n            for (int x : seg) pos[x] = best_d;\n            st[best_d].insert(st[best_d].end(), seg.begin(), seg.end());\n            \n            ops.emplace_back(u, best_d + 1); // convert to 1-indexed for output\n            // After this, target is at top of stack s (loop will exit)\n        }\n        \n        // Remove target (Operation 2)\n        st[s].pop_back();\n        ops.emplace_back(target, 0);\n    }\n    \n    for (auto [v, i] : ops) {\n        cout << v << ' ' << i << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n    \n    auto id = [&](int i, int j){ return i*N + j; };\n    int V = N*N;\n    vector<vector<pair<int,char>>> adj(V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n    const int rev[4] = {1,0,3,2};\n    \n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                bool ok = false;\n                if (dir == 0) { // up\n                    ok = h[ni][j] == '0';\n                } else if (dir == 1) { // down\n                    ok = h[i][j] == '0';\n                } else if (dir == 2) { // left\n                    ok = v[i][nj] == '0';\n                } else { // right\n                    ok = v[i][j] == '0';\n                }\n                if (ok) {\n                    adj[id(i,j)].push_back({id(ni,nj), dc[dir]});\n                }\n            }\n        }\n    }\n    \n    int root = 0;\n    vector<int> parent(V, -1);\n    vector<vector<int>> children(V);\n    vector<char> move_to_parent(V, 0);\n    {\n        queue<int> q;\n        q.push(root);\n        parent[root] = -2;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, c] : adj[u]) {\n                if (parent[v] == -1) {\n                    parent[v] = u;\n                    move_to_parent[v] = dc[rev[strchr(dc, c) - dc]];\n                    children[u].push_back(v);\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    // BFS order for top\u2011down, reverse for bottom\u2011up\n    vector<int> bfs_order;\n    bfs_order.reserve(V);\n    {\n        queue<int> q;\n        q.push(root);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            bfs_order.push_back(u);\n            for (int w : children[u]) q.push(w);\n        }\n    }\n    vector<int> rev_order = bfs_order;\n    reverse(rev_order.begin(), rev_order.end());\n    \n    vector<double> dval(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            dval[id(i,j)] = sqrt((double)d[i][j]);\n    \n    const long long LIM = 100000LL;\n    const int B = 3; // max excursions per slot\n    \n    vector<long long> k(V, 1);\n    \n    auto feasible = [&](double c)->bool {\n        for (int u : rev_order) {\n            if (u == root) continue;\n            long long sum_child = 0;\n            for (int w : children[u]) sum_child += k[w];\n            long long need = (sum_child + B - 1) / B; // ceil(sum/B)\n            long long kv = (long long)(c * dval[u]);\n            if (kv < 1) kv = 1;\n            if (kv < need) kv = need;\n            k[u] = kv;\n        }\n        long long total = 0;\n        for (int u = 0; u < V; ++u) {\n            if (u == root) continue;\n            total += 2 * k[u];\n            if (total > LIM) return false;\n        }\n        return total <= LIM;\n    };\n    \n    double lo = 0, hi = 1e6;\n    for (int it = 0; it < 60; ++it) {\n        double mid = (lo + hi) * 0.5;\n        if (feasible(mid)) lo = mid;\n        else hi = mid;\n    }\n    feasible(lo); // fill k with the final feasible value\n    \n    long long k_root = 0;\n    for (int w : children[root]) k_root += k[w];\n    k[root] = k_root; // root's own dirtiness is handled by its k\n    \n    // Build schedules: for each node, list of children for each slot\n    vector<vector<vector<int>>> sched(V);\n    for (int u : bfs_order) {\n        if (children[u].empty()) {\n            sched[u].assign((size_t)k[u], {});\n            continue;\n        }\n        vector<int> exc; // excursions (child ids repeated k[child] times)\n        exc.reserve(10000);\n        for (int w : children[u]) {\n            for (long long i = 0; i < k[w]; ++i) exc.push_back(w);\n        }\n        sched[u].assign((size_t)k[u], {});\n        for (size_t i = 0; i < exc.size(); ++i) {\n            int slot = (int)(i % k[u]);\n            sched[u][slot].push_back(exc[i]);\n        }\n    }\n    \n    string ans;\n    ans.reserve((size_t)LIM);\n    vector<size_t> cur_slot(V, 0);\n    \n    auto get_char = [&](int u, int v)->char {\n        for (auto [to, c] : adj[u]) if (to == v) return c;\n        return '?';\n    };\n    \n    function<void(int)> visit = [&](int u) {\n        size_t slot = cur_slot[u]++;\n        for (int w : sched[u][slot]) {\n            ans.push_back(get_char(u, w));\n            visit(w);\n            ans.push_back(get_char(w, u));\n        }\n    };\n    \n    // Process root slots\n    for (size_t slot = 0; slot < (size_t)k[root]; ++slot) {\n        for (int w : sched[root][slot]) {\n            ans.push_back(get_char(root, w));\n            visit(w);\n            ans.push_back(get_char(w, root));\n        }\n    }\n    \n    if ((long long)ans.size() > LIM) {\n        ans.resize((size_t)LIM);\n    }\n    cout << ans << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint calc_overlap(const string& a, const string& b) {\n    // If b is already a substring of a, we don't need to add anything\n    if (a.find(b) != string::npos) return (int)b.length();\n    // Find maximum k such that suffix of a matches prefix of b\n    int max_k = min((int)a.length(), (int)b.length());\n    for (int k = max_k; k > 0; --k) {\n        if (a.compare(a.length() - k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    int si, sj;\n    cin >> N >> M >> si >> sj;\n    \n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n    }\n    \n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n    \n    // Build superstring using greedy SCS (Shortest Common Superstring)\n    vector<string> pool = targets;\n    while (pool.size() > 1) {\n        int n = pool.size();\n        int best_ov = -1;\n        int best_i = -1, best_j = -1;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(pool[i], pool[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        \n        // Merge pool[best_i] and pool[best_j]\n        string merged = pool[best_i] + pool[best_j].substr(best_ov);\n        \n        // Remove best_j and best_i (remove higher index first to keep indices valid)\n        if (best_i > best_j) swap(best_i, best_j);\n        pool.erase(pool.begin() + best_j);\n        pool.erase(pool.begin() + best_i);\n        pool.push_back(merged);\n    }\n    \n    const string& U = pool[0];\n    const int L = U.size();\n    \n    // Precompute positions for each character\n    vector<vector<int>> pos(26); // store cell indices (i*N + j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int c = grid[i][j] - 'A';\n            pos[c].push_back(i * N + j);\n        }\n    }\n    \n    // Precompute Manhattan distances between all cells\n    const int V = N * N;\n    vector<vector<int>> dist(V, vector<int>(V));\n    for (int i = 0; i < V; ++i) {\n        int i1 = i / N, j1 = i % N;\n        for (int j = 0; j < V; ++j) {\n            int i2 = j / N, j2 = j % N;\n            dist[i][j] = abs(i1 - i2) + abs(j1 - j2);\n        }\n    }\n    \n    const int INF = 1e9;\n    // dp_curr[v] = min cost to reach cell v at current step\n    vector<int> dp_prev(V, INF), dp_curr(V, INF);\n    // parent[step][v] = previous cell index that achieved dp_curr[v]\n    vector<vector<int>> parent(L, vector<int>(V, -1));\n    \n    // Initialize for first character\n    int first_c = U[0] - 'A';\n    for (int v : pos[first_c]) {\n        int vi = v / N, vj = v % N;\n        dp_curr[v] = dist[si * N + sj][v] + 1;\n    }\n    \n    // DP for subsequent characters\n    for (int step = 1; step < L; ++step) {\n        dp_prev = dp_curr;\n        fill(dp_curr.begin(), dp_curr.end(), INF);\n        \n        int curr_c = U[step] - 'A';\n        int prev_c = U[step - 1] - 'A';\n        \n        for (int v : pos[curr_c]) {\n            int best = INF;\n            int best_u = -1;\n            for (int u : pos[prev_c]) {\n                if (dp_prev[u] == INF) continue;\n                int cost = dp_prev[u] + dist[u][v] + 1;\n                if (cost < best) {\n                    best = cost;\n                    best_u = u;\n                }\n            }\n            if (best < INF) {\n                dp_curr[v] = best;\n                parent[step][v] = best_u;\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_v = -1;\n    int best_cost = INF;\n    for (int v = 0; v < V; ++v) {\n        if (dp_curr[v] < best_cost) {\n            best_cost = dp_curr[v];\n            best_v = v;\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int, int>> path;\n    int cur = best_v;\n    for (int step = L - 1; step >= 0; --step) {\n        int i = cur / N;\n        int j = cur % N;\n        path.push_back({i, j});\n        if (step > 0) {\n            cur = parent[step][cur];\n        }\n    }\n    reverse(path.begin(), path.end());\n    \n    // Output\n    for (auto [i, j] : path) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ------------------------------------------------------------\n// Problem parameters\nint N, M;\ndouble eps;\nconst int MAX_N2 = 400; // 20*20\n\nstruct Placement {\n    bitset<MAX_N2> cells;\n    int area; // popcount\n};\n\nvector<vector<Placement>> placements; // [field][placement_idx]\nvector<int> num_placements; // [field]\n\n// ------------------------------------------------------------\n// Particle\nstruct Particle {\n    vector<int> pos; // size M, index of placement for each field\n    double weight;\n    Particle(int M_) : pos(M_), weight(1.0) {}\n};\n\nvector<Particle> particles;\nconst int NUM_PARTICLES = 2000;\n\n// ------------------------------------------------------------\n// Utilities\nint flat(int i, int j) { return i * N + j; }\n\n// ------------------------------------------------------------\n// Random generator\nmt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\ndouble rand_double() {\n    return uniform_real_distribution<double>(0.0, 1.0)(rng);\n}\n\n// ------------------------------------------------------------\n// Enumerate all valid placements for each field\nvoid enumerate_placements(const vector<vector<pair<int,int>>>& shapes) {\n    placements.resize(M);\n    num_placements.resize(M);\n    for (int k = 0; k < M; ++k) {\n        const auto& shape = shapes[k];\n        int h = 0, w = 0;\n        for (auto [i, j] : shape) {\n            h = max(h, i);\n            w = max(w, j);\n        }\n        // translations\n        for (int di = 0; di + h < N; ++di) {\n            for (int dj = 0; dj + w < N; ++dj) {\n                Placement p;\n                p.area = (int)shape.size();\n                for (auto [i, j] : shape) {\n                    int ni = di + i;\n                    int nj = dj + j;\n                    p.cells.set(flat(ni, nj));\n                }\n                placements[k].push_back(p);\n            }\n        }\n        num_placements[k] = (int)placements[k].size();\n        if (num_placements[k] == 0) {\n            // should not happen with valid input\n        }\n    }\n}\n\n// ------------------------------------------------------------\n// Initialize particles uniformly at random\nvoid init_particles(const vector<int>& forced_val = {}) {\n    particles.clear();\n    particles.reserve(NUM_PARTICLES);\n    for (int i = 0; i < NUM_PARTICLES; ++i) {\n        Particle p(M);\n        for (int k = 0; k < M; ++k) {\n            p.pos[k] = rand_int(0, num_placements[k] - 1);\n        }\n        p.weight = 1.0;\n        particles.push_back(p);\n    }\n}\n\n// ------------------------------------------------------------\n// Compute cell probabilities from particles\n// Returns vector<double> prob (size N*N), and also fills drilled constraints\nvector<double> compute_cell_probs(const vector<int>& drilled_val) {\n    vector<double> prob(N*N, 0.0);\n    for (const auto& p : particles) {\n        // coverage bitset of this particle\n        bitset<MAX_N2> cov;\n        for (int k = 0; k < M; ++k) {\n            cov |= placements[k][p.pos[k]].cells;\n        }\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (cov[idx]) prob[idx] += 1.0;\n        }\n    }\n    double invP = 1.0 / particles.size();\n    for (int i = 0; i < N*N; ++i) prob[i] *= invP;\n    return prob;\n}\n\n// ------------------------------------------------------------\n// Resample particles according to weights\nvoid resample() {\n    double sumw = 0.0;\n    for (auto& p : particles) sumw += p.weight;\n    if (sumw == 0) {\n        // all weights zero, reinitialize\n        init_particles();\n        return;\n    }\n    for (auto& p : particles) p.weight /= sumw;\n    \n    vector<Particle> new_parts;\n    new_parts.reserve(particles.size());\n    double step = 1.0 / particles.size();\n    double r = rand_double() * step;\n    double csum = 0.0;\n    size_t idx = 0;\n    for (size_t i = 0; i < particles.size(); ++i) {\n        double target = r + i * step;\n        while (idx < particles.size() && csum + particles[idx].weight < target) {\n            csum += particles[idx].weight;\n            ++idx;\n        }\n        if (idx >= particles.size()) idx = particles.size() - 1;\n        new_parts.push_back(particles[idx]);\n        new_parts.back().weight = 1.0;\n    }\n    particles.swap(new_parts);\n}\n\n// ------------------------------------------------------------\n// Filter particles by a drilled cell (exact value v)\nvoid filter_by_drill(int cell, int v) {\n    vector<Particle> filtered;\n    filtered.reserve(particles.size());\n    for (const auto& p : particles) {\n        int cnt = 0;\n        for (int k = 0; k < M; ++k) {\n            if (placements[k][p.pos[k]].cells[cell]) ++cnt;\n        }\n        if (cnt == v) filtered.push_back(p);\n    }\n    if ((int)filtered.size() < 10) {\n        // keep some random ones to avoid collapse, or reinitialize with constraint\n        // For simplicity, if too few, we keep original but this is rare\n        if (filtered.empty()) {\n            // total collapse, reinitialize and hope for the best\n            init_particles();\n            return;\n        }\n    }\n    particles.swap(filtered);\n    // reset weights\n    for (auto& p : particles) p.weight = 1.0;\n}\n\n// ------------------------------------------------------------\n// Main\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---- Input ------------------------------------------------\n    if (!(cin >> N >> M >> eps)) return 0;\n    vector<vector<pair<int,int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n    \n    enumerate_placements(shapes);\n    init_particles();\n    \n    vector<char> is_drilled(N*N, 0);\n    vector<int> drilled_val(N*N, -1);\n    \n    const int MAX_Q = 2 * N * N;\n    \n    for (int qcnt = 0; qcnt < MAX_Q - 5; ++qcnt) {\n        // Compute current beliefs\n        vector<double> prob = compute_cell_probs(drilled_val);\n        \n        // Identify uncertain cells\n        vector<int> uncertain;\n        uncertain.reserve(N*N);\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (is_drilled[idx]) continue;\n            if (prob[idx] > 0.1 && prob[idx] < 0.9) {\n                uncertain.push_back(idx);\n            }\n        }\n        \n        // Decide action\n        bool do_answer = false;\n        bool do_drill = false;\n        int drill_cell = -1;\n        vector<int> query_cells; // for divine\n        \n        // If almost all cells are certain, try to answer\n        if ((int)uncertain.size() <= 3 || qcnt > MAX_Q - 10) {\n            do_answer = true;\n        } else if (qcnt < 30) {\n            // Exploration: random large divine query\n            bitset<MAX_N2> mask;\n            for (int i = 0; i < N*N; ++i) {\n                if (rand_int(0,1)) query_cells.push_back(i);\n            }\n            if ((int)query_cells.size() < 2) {\n                query_cells.push_back(0);\n                query_cells.push_back(1);\n            }\n        } else {\n            // Exploitation: divine a batch of uncertain cells\n            // Take up to 25 cells to keep noise moderate (sigma ~ 0.5 for eps=0.01)\n            int take = min((int)uncertain.size(), 25);\n            // Sort by closest to 0.5\n            sort(uncertain.begin(), uncertain.end(), [&](int a, int b){\n                double da = abs(prob[a] - 0.5);\n                double db = abs(prob[b] - 0.5);\n                return da < db;\n            });\n            query_cells.assign(uncertain.begin(), uncertain.begin() + take);\n        }\n        \n        if (do_answer) {\n            vector<int> ans_cells;\n            for (int idx = 0; idx < N*N; ++idx) {\n                if (is_drilled[idx]) {\n                    if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n                } else {\n                    if (prob[idx] > 0.5) ans_cells.push_back(idx);\n                }\n            }\n            // Output answer\n            cout << \"a \" << ans_cells.size();\n            for (int idx : ans_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            int resp; cin >> resp;\n            if (resp == 1) {\n                return 0; // success\n            } else {\n                // Wrong answer, penalized 1 cost, continue\n                continue;\n            }\n        }\n        \n        if (!query_cells.empty() && !do_drill) {\n            // Divine query\n            int k = (int)query_cells.size();\n            cout << \"q \" << k;\n            for (int idx : query_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            \n            int obs; cin >> obs;\n            \n            // Prepare query mask\n            bitset<MAX_N2> qmask;\n            for (int idx : query_cells) qmask.set(idx);\n            \n            // Update weights\n            double kdbl = k;\n            double mu0 = kdbl * eps;\n            double sigma2 = kdbl * eps * (1.0 - eps);\n            double sigma = sqrt(sigma2);\n            if (sigma < 1e-9) sigma = 1e-9;\n            \n            for (auto& p : particles) {\n                int v = 0;\n                for (int m = 0; m < M; ++m) {\n                    v += (placements[m][p.pos[m]].cells & qmask).count();\n                }\n                double mu = mu0 + v * (1.0 - 2.0 * eps);\n                // Gaussian likelihood (ignoring round/max)\n                double z = (obs - mu) / sigma;\n                double w = exp(-0.5 * z * z);\n                p.weight = w;\n            }\n            resample();\n        } else if (do_drill && drill_cell >= 0) {\n            // Single drill\n            cout << \"q 1 \" << drill_cell / N << \" \" << drill_cell % N << endl;\n            int val; cin >> val;\n            is_drilled[drill_cell] = 1;\n            drilled_val[drill_cell] = val;\n            filter_by_drill(drill_cell, val);\n        }\n    }\n    \n    // Fallback: if we exit loop without answering, just answer with current belief\n    vector<int> ans_cells;\n    vector<double> prob = compute_cell_probs(drilled_val);\n    for (int idx = 0; idx < N*N; ++idx) {\n        if (is_drilled[idx]) {\n            if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n        } else {\n            if (prob[idx] > 0.5) ans_cells.push_back(idx);\n        }\n    }\n    cout << \"a \" << ans_cells.size();\n    for (int idx : ans_cells) {\n        cout << \" \" << idx / N << \" \" << idx % N;\n    }\n    cout << endl;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> day_dist(0, D-1);\n    uniform_int_distribution<int> strip_dist(0, N-1);\n    \n    // Heights h[d][k] for each day and strip\n    vector<vector<int>> h(D, vector<int>(N, 1));\n    \n    // Initialize: greedy allocation to minimize area deficit\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> needs;\n        for (int k = 0; k < N; k++) {\n            int need = (a[d][k] + W - 1) / W;\n            needs.push_back({need, k});\n        }\n        sort(needs.rbegin(), needs.rend());\n        \n        int remaining = W - N;\n        for (auto &[need, k] : needs) {\n            int give = min(remaining, max(0, need - 1));\n            h[d][k] = 1 + give;\n            remaining -= give;\n        }\n        int idx = 0;\n        while (remaining > 0) {\n            h[d][idx % N]++;\n            remaining--;\n            idx++;\n        }\n    }\n    \n    // Cumulative positions y[d][k] = sum_{i<k} h[d][i], with y[d][0]=0, y[d][N]=W\n    vector<vector<int>> y(D, vector<int>(N+1));\n    for (int d = 0; d < D; d++) {\n        y[d][0] = 0;\n        for (int k = 0; k < N; k++) y[d][k+1] = y[d][k] + h[d][k];\n    }\n    \n    auto calc_cost = [&]() -> long long {\n        long long cost = 0;\n        for (int d = 0; d < D; d++) {\n            for (int k = 0; k < N; k++) {\n                long long area = 1LL * h[d][k] * W;\n                if (area < a[d][k]) cost += 100LL * (a[d][k] - area);\n            }\n        }\n        for (int d = 1; d < D; d++) {\n            for (int k = 1; k < N; k++) {\n                if (y[d][k] != y[d-1][k]) cost += 2LL * W;\n            }\n        }\n        return cost;\n    };\n    \n    long long current_cost = calc_cost();\n    long long best_cost = current_cost;\n    auto best_h = h;\n    \n    const double TIME_LIMIT = 2.8;\n    clock_t start_time = clock();\n    \n    int iterations = 0;\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > TIME_LIMIT) break;\n        \n        double T = 1e8 * (1.0 - elapsed / TIME_LIMIT) + 1.0;\n        \n        int d = day_dist(rng);\n        int i = strip_dist(rng);\n        int j = strip_dist(rng);\n        if (i == j) continue;\n        if (h[d][i] <= 1) continue;\n        \n        // Determine affected range: [l, r] inclusive\n        int l = min(i, j) + 1;\n        int r = max(i, j);\n        int delta = (i < j) ? -1 : +1;\n        \n        long long delta_cost = 0;\n        \n        // Area cost change\n        long long old_area_i = 1LL * h[d][i] * W;\n        long long new_area_i = 1LL * (h[d][i] - 1) * W;\n        if (old_area_i < a[d][i]) delta_cost -= 100LL * (a[d][i] - old_area_i);\n        if (new_area_i < a[d][i]) delta_cost += 100LL * (a[d][i] - new_area_i);\n        \n        long long old_area_j = 1LL * h[d][j] * W;\n        long long new_area_j = 1LL * (h[d][j] + 1) * W;\n        if (old_area_j < a[d][j]) delta_cost -= 100LL * (a[d][j] - old_area_j);\n        if (new_area_j < a[d][j]) delta_cost += 100LL * (a[d][j] - new_area_j);\n        \n        // Partition cost change for boundaries in [l, r]\n        for (int k = l; k <= r; k++) {\n            int old_y = y[d][k];\n            int new_y = old_y + delta;\n            \n            if (d > 0) {\n                bool old_eq = (old_y == y[d-1][k]);\n                bool new_eq = (new_y == y[d-1][k]);\n                if (old_eq && !new_eq) delta_cost += 2LL * W;\n                else if (!old_eq && new_eq) delta_cost -= 2LL * W;\n            }\n            if (d < D - 1) {\n                bool old_eq = (old_y == y[d+1][k]);\n                bool new_eq = (new_y == y[d+1][k]);\n                if (old_eq && !new_eq) delta_cost += 2LL * W;\n                else if (!old_eq && new_eq) delta_cost -= 2LL * W;\n            }\n        }\n        \n        bool accept = false;\n        if (delta_cost < 0) {\n            accept = true;\n        } else {\n            double prob = exp(-(double)delta_cost / T);\n            if (uniform_real_distribution<double>(0, 1)(rng) < prob) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            h[d][i]--;\n            h[d][j]++;\n            for (int k = l; k <= r; k++) {\n                y[d][k] += delta;\n            }\n            current_cost += delta_cost;\n            \n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_h = h;\n            }\n        }\n        \n        iterations++;\n    }\n    \n    // Recompute y from best_h to ensure correctness\n    for (int d = 0; d < D; d++) {\n        int cur = 0;\n        for (int k = 0; k < N; k++) {\n            int i1 = cur;\n            cur += best_h[d][k];\n            int i2 = cur;\n            cout << i1 << \" 0 \" << i2 << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Stamp {\n    int s[3][3];\n};\n\nstruct Solver {\n    int N, M, K;\n    vector<vector<long long>> grid;\n    vector<Stamp> stamps;\n    vector<tuple<int, int, int>> ops; // (stamp_id, p, q)\n    long long current_score = 0;\n    mt19937 rng;\n\n    Solver(int n, int m, int k, const vector<vector<long long>>& init_grid, const vector<Stamp>& st)\n        : N(n), M(m), K(k), grid(init_grid), stamps(st), rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        // Calculate initial score\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                current_score += grid[i][j] % MOD;\n            }\n        }\n    }\n\n    // Compute delta if we add stamp m at position (p, q)\n    long long compute_delta_add(int m, int p, int q) const {\n        long long d = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                long long old_val = grid[r][c];\n                long long new_val = old_val + stamps[m].s[i][j];\n                d += (new_val % MOD) - (old_val % MOD);\n            }\n        }\n        return d;\n    }\n\n    // Compute delta if we remove stamp m at position (p, q)\n    // Note: assumes this stamp was previously added and grid reflects its contribution\n    long long compute_delta_remove(int m, int p, int q) const {\n        long long d = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                long long old_val = grid[r][c];\n                long long new_val = old_val - stamps[m].s[i][j];\n                // Since we only add non-negative values and start non-negative, new_val >= 0\n                d += (new_val % MOD) - (old_val % MOD);\n            }\n        }\n        return d;\n    }\n\n    void apply_add(int m, int p, int q) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                grid[r][c] += stamps[m].s[i][j];\n            }\n        }\n        ops.push_back({m, p, q});\n    }\n\n    void apply_remove(int idx) {\n        auto [m, p, q] = ops[idx];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                grid[r][c] -= stamps[m].s[i][j];\n            }\n        }\n        ops[idx] = ops.back();\n        ops.pop_back();\n    }\n\n    void solve() {\n        // --- Greedy Phase ---\n        for (int iter = 0; iter < K; ++iter) {\n            long long best_delta = 0;\n            int best_m = -1, best_p = -1, best_q = -1;\n\n            for (int m = 0; m < M; ++m) {\n                for (int p = 0; p <= N - 3; ++p) {\n                    for (int q = 0; q <= N - 3; ++q) {\n                        long long d = compute_delta_add(m, p, q);\n                        if (d > best_delta) {\n                            best_delta = d;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n\n            if (best_delta <= 0) break;\n            apply_add(best_m, best_p, best_q);\n            current_score += best_delta;\n        }\n\n        // --- Simulated Annealing Phase ---\n        const int MAX_ITER = 20000;\n        double temp = 1000.0; // Initial temperature\n        uniform_real_distribution<double> dist(0.0, 1.0);\n\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            int move_type = rng() % 3; // 0: add, 1: remove, 2: replace\n\n            if (move_type == 0 && (int)ops.size() < K) {\n                int m = rng() % M;\n                int p = rng() % (N - 2);\n                int q = rng() % (N - 2);\n                long long d = compute_delta_add(m, p, q);\n\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    apply_add(m, p, q);\n                    current_score += d;\n                }\n            } \n            else if (move_type == 1 && !ops.empty()) {\n                int idx = rng() % ops.size();\n                auto [m, p, q] = ops[idx];\n                long long d = compute_delta_remove(m, p, q);\n\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    apply_remove(idx);\n                    current_score += d;\n                }\n            } \n            else if (move_type == 2 && !ops.empty()) {\n                // Replace operation\n                int idx = rng() % ops.size();\n                auto [m_old, p_old, q_old] = ops[idx];\n                \n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n\n                // Remove old\n                long long d_remove = compute_delta_remove(m_old, p_old, q_old);\n                apply_remove(idx);\n                \n                // Compute add delta on modified grid\n                long long d_add = compute_delta_add(m_new, p_new, q_new);\n                \n                long long total_d = d_remove + d_add;\n                \n                if (total_d > 0 || exp(total_d / temp) > dist(rng)) {\n                    apply_add(m_new, p_new, q_new);\n                    current_score += total_d;\n                } else {\n                    // Revert: add old back\n                    apply_add(m_old, p_old, q_old);\n                }\n            }\n\n            // Cool down\n            temp = 1000.0 * (1.0 - (double)(iter + 1) / MAX_ITER);\n            if (temp < 0.1) temp = 0.1;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Process exactly 150 test cases as per problem statement\n    for (int tc = 0; tc < 150; ++tc) {\n        int N, M, K;\n        if (!(cin >> N >> M >> K)) return 0;\n\n        vector<vector<long long>> grid(N, vector<long long>(N));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cin >> grid[i][j];\n            }\n        }\n\n        vector<Stamp> stamps(M);\n        for (int m = 0; m < M; ++m) {\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    cin >> stamps[m].s[i][j];\n                }\n            }\n        }\n\n        Solver solver(N, M, K, grid, stamps);\n        solver.solve();\n\n        cout << solver.ops.size() << '\\n';\n        for (const auto& [m, p, q] : solver.ops) {\n            cout << m << ' ' << p << ' ' << q << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    int turn = 0;\n    // Crane 0 (large) position\n    int cr = 0, cc = 0;\n    bool holding = false;\n    int held = -1;\n    \n    // Grid: -1 empty, else container id\n    vector<vector<int>> grid;\n    // ptr[g] = next index to receive from gate g\n    vector<int> ptr;\n    // A[g][j]\n    vector<vector<int>> A;\n    \n    vector<string> ops; // operations per crane\n    \n    State(int n, const vector<vector<int>>& A_) : A(A_) {\n        grid.assign(n, vector<int>(n, -1));\n        ptr.assign(n, 0);\n        // Initial grid: receiving gates have first container\n        for (int i=0;i<n;i++) {\n            grid[i][0] = A[i][0];\n        }\n        ops.resize(n);\n    }\n    \n    void add_op(int crane, char c) {\n        if ((int)ops[crane].size() <= turn) {\n            ops[crane].push_back(c);\n        } else {\n            ops[crane][turn] = c;\n        }\n    }\n    \n    void simulate_turn(const vector<char>& actions) {\n        // Step 1: Receiving\n        for (int i=0;i<(int)grid.size();i++) {\n            if (ptr[i]+1 < (int)A[i].size() && grid[i][0] == -1) {\n                // Check no crane holding at (i,0) - only crane 0 exists\n                grid[i][0] = A[i][ptr[i]+1];\n                ptr[i]++;\n            } else if (ptr[i] < (int)A[i].size() && grid[i][0] == -1 && ptr[i] == 0) {\n                 // Initial state already handled, but for completeness\n            }\n        }\n        // Actually, receiving happens if square empty AND no crane holding there\n        // We handle by ptr logic: grid[i][0] contains A[i][ptr[i]] if ptr[i] < 5, else -1\n        \n        // Step 2: Actions (we generate them, so we trust validity)\n        // Step 3: Dispatch\n        for (int i=0;i<(int)grid.size();i++) {\n            if (grid[i][4] != -1) {\n                grid[i][4] = -1; // dispatched\n            }\n        }\n        turn++;\n    }\n    \n    // Find parking column in row r (0..4), prefer 2,3,1,0\n    // Returns -1 if full (shouldn't happen)\n    int find_parking_col(int r) {\n        vector<int> order = {2, 3, 1, 0};\n        for (int c : order) {\n            if (grid[r][c] == -1) return c;\n        }\n        return -1; \n    }\n    \n    // Move crane to (tr, tc), appending moves\n    void move_to(int tr, int tc, int crane_idx) {\n        while (cr != tr) {\n            if (cr < tr) { add_op(crane_idx, 'D'); cr++; }\n            else { add_op(crane_idx, 'U'); cr--; }\n        }\n        while (cc != tc) {\n            if (cc < tc) { add_op(crane_idx, 'R'); cc++; }\n            else { add_op(crane_idx, 'L'); cc--; }\n        }\n    }\n    \n    void pickup(int crane_idx) {\n        add_op(crane_idx, 'P');\n        int val = grid[cr][cc];\n        grid[cr][cc] = -1;\n        holding = true;\n        held = val;\n    }\n    \n    void drop(int crane_idx) {\n        add_op(crane_idx, 'Q');\n        grid[cr][cc] = held;\n        holding = false;\n        held = -1;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if(!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) cin >> A[i][j];\n    \n    State st(N, A);\n    int n = N;\n    \n    // Precompute location of each container\n    vector<pair<int,int>> loc(n*n); // (gate, pos)\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        loc[A[i][j]] = {i, j};\n    }\n    \n    // Bomb small cranes 1..n-1 in first turn\n    for (int i=1;i<n;i++) st.add_op(i, 'B');\n    st.add_op(0, '.'); // wait\n    st.simulate_turn({'.', 'B', 'B', 'B', 'B'}); // simulate first turn\n    \n    vector<int> dispatched(n, 0); // how many dispatched from each row\n    vector<int> gate_ptr(n, 0); // next to pick from gate (0..5)\n    \n    // Initialize grid with first containers\n    for (int i=0;i<n;i++) {\n        st.grid[i][0] = A[i][0];\n    }\n    \n    for (int target_row = 0; target_row < n; target_row++) {\n        // Helper to dispatch if next needed\n        auto try_dispatch = [&](int c) -> bool {\n            int need = target_row * n + dispatched[target_row];\n            if (c == need) {\n                // move to dispatch\n                st.move_to(target_row, n-1, 0);\n                st.drop(0);\n                dispatched[target_row]++;\n                return true;\n            }\n            return false;\n        };\n        \n        // First, clear own gate to free column 0\n        while (gate_ptr[target_row] < n) {\n            int c = A[target_row][gate_ptr[target_row]];\n            st.move_to(target_row, 0, 0);\n            st.pickup(0);\n            gate_ptr[target_row]++;\n            if (!try_dispatch(c)) {\n                int col = st.find_parking_col(target_row);\n                if (col == -1) col = 0; // force, though gate not clear yet? Shouldn't happen early\n                st.move_to(target_row, col, 0);\n                st.drop(0);\n            }\n        }\n        \n        // Process other gates for containers belonging to target_row\n        for (int g=0; g<n; g++) {\n            if (g == target_row) continue;\n            // Check if any container at gate g belongs to target_row\n            while (gate_ptr[g] < n) {\n                int c = A[g][gate_ptr[g]];\n                if (c / n != target_row) break;\n                \n                // Need to clear blockers before c at gate g\n                auto [src_g, src_pos] = loc[c];\n                // src_g should be g, src_pos is gate_ptr[g] ideally\n                // But blockers are A[g][0..gate_ptr[g]-1] already cleared\n                // Actually we need to clear up to c's position\n                // loc[c].second is the original position, but ptr has moved\n                // We need to find current position in the sequence\n                int need_pos = -1;\n                for (int j=gate_ptr[g]; j<n; j++) if (A[g][j] == c) { need_pos = j; break; }\n                \n                // Clear blockers\n                while (gate_ptr[g] < need_pos) {\n                    int c2 = A[g][gate_ptr[g]];\n                    st.move_to(g, 0, 0);\n                    st.pickup(0);\n                    gate_ptr[g]++;\n                    int t2 = c2 / n;\n                    int col = st.find_parking_col(t2);\n                    // If no room, use col 0 of t2 if gate cleared, else we have problem\n                    if (col == -1) {\n                        if (gate_ptr[t2] == n) col = 0;\n                        else {\n                            // Find any empty spot\n                            for (int rr=0; rr<n; rr++) {\n                                for (int cc=0; cc<n; cc++) {\n                                    if (st.grid[rr][cc] == -1 && !(rr==st.cr && cc==st.cc)) {\n                                        col = cc; t2 = rr; break;\n                                    }\n                                }\n                                if (col != -1) break;\n                            }\n                        }\n                    }\n                    st.move_to(t2, col, 0);\n                    st.drop(0);\n                }\n                \n                // Now pick up c\n                st.move_to(g, 0, 0);\n                st.pickup(0);\n                gate_ptr[g]++;\n                if (!try_dispatch(c)) {\n                    int col = st.find_parking_col(target_row);\n                    if (col == -1) col = 0; // gate target_row is cleared now\n                    st.move_to(target_row, col, 0);\n                    st.drop(0);\n                }\n            }\n        }\n        \n        // Dispatch remaining in this row\n        while (dispatched[target_row] < n) {\n            int need = target_row * n + dispatched[target_row];\n            // Find need in row target_row\n            int fc = -1;\n            for (int c=0; c<n; c++) {\n                if (st.grid[target_row][c] == need) {\n                    fc = c; break;\n                }\n            }\n            // Should be there\n            if (fc != -1) {\n                st.move_to(target_row, fc, 0);\n                st.pickup(0);\n                st.move_to(target_row, n-1, 0);\n                st.drop(0);\n                dispatched[target_row]++;\n            } else {\n                // Should not happen\n                break;\n            }\n        }\n    }\n    \n    // Pad output to same length\n    size_t max_len = 0;\n    for (auto& s : st.ops) max_len = max(max_len, s.size());\n    for (auto& s : st.ops) {\n        while (s.size() < max_len) s.push_back('.');\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int r = 0, c = 0;\n    long long load = 0;\n    \n    auto move_to = [&](int nr, int nc) {\n        while (r < nr) {\n            ops.emplace_back(\"D\");\n            ++r;\n        }\n        while (r > nr) {\n            ops.emplace_back(\"U\");\n            --r;\n        }\n        while (c < nc) {\n            ops.emplace_back(\"R\");\n            ++c;\n        }\n        while (c > nc) {\n            ops.emplace_back(\"L\");\n            --c;\n        }\n    };\n    \n    auto find_nearest = [&](bool need_positive) -> pair<int, int> {\n        int best_dist = 1e9;\n        pair<int, int> best = {-1, -1};\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                bool ok = need_positive ? (h[i][j] > 0) : (h[i][j] < 0);\n                if (ok) {\n                    int d = abs(i - r) + abs(j - c);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best = {i, j};\n                    }\n                }\n            }\n        }\n        return best;\n    };\n    \n    while (true) {\n        auto target = find_nearest(load == 0);\n        if (target.first == -1) break; // No more work\n        \n        move_to(target.first, target.second);\n        \n        if (h[r][c] > 0) {\n            // Load all soil from this cell\n            int d = h[r][c];\n            ops.emplace_back(\"+\" + to_string(d));\n            load += d;\n            h[r][c] = 0;\n        } else {\n            // Unload as much as needed/possible\n            int need = -h[r][c];\n            int d = (int)min<long long>(need, load);\n            ops.emplace_back(\"-\" + to_string(d));\n            load -= d;\n            h[r][c] += d; // h[r][c] was negative, now closer to 0\n        }\n    }\n    \n    for (const auto& s : ops) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Solver {\n    int N, M, T;\n    int SEED_COUNT;\n    struct Seed {\n        vector<int> x;\n        int sum;\n        int mx;\n    };\n    vector<Seed> seeds;\n    mt19937 rng;\n    chrono::steady_clock::time_point start_time;\n\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        start_time = chrono::steady_clock::now();\n    }\n\n    void solveOneTurn(int turn, int total_turns) {\n        // Select top N*N seeds using a score that values both sum and max dimension\n        vector<pair<ll, int>> candidates;\n        for (int i = 0; i < SEED_COUNT; i++) {\n            // Score = sum + 5 * max_dimension (weight 5 tuned for balance)\n            ll score = seeds[i].sum + 5LL * seeds[i].mx;\n            candidates.push_back({score, i});\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        vector<int> selected;\n        for (int i = 0; i < N * N; i++) {\n            selected.push_back(candidates[i].second);\n        }\n\n        // Precompute edge scores for selected seeds\n        int S = N * N;\n        vector<vector<ll>> edgeScore(S, vector<ll>(S));\n        for (int i = 0; i < S; i++) {\n            for (int j = i; j < S; j++) {\n                int a = selected[i];\n                int b = selected[j];\n                ll s = 0;\n                for (int l = 0; l < M; l++) {\n                    s += max(seeds[a].x[l], seeds[b].x[l]);\n                }\n                edgeScore[i][j] = edgeScore[j][i] = s;\n            }\n        }\n\n        // Grid positions sorted by degree (center first)\n        vector<pair<int, pair<int,int>>> positions; // (degree, (i,j))\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int deg = 0;\n                if (i > 0) deg++;\n                if (i < N-1) deg++;\n                if (j > 0) deg++;\n                if (j < N-1) deg++;\n                positions.push_back({deg, {i, j}});\n            }\n        }\n        sort(positions.rbegin(), positions.rend());\n\n        // Map from linear index to (i,j)\n        vector<int> pos2idx(S);\n        vector<pair<int,int>> idx2pos(S);\n        for (int i = 0; i < S; i++) {\n            idx2pos[i] = positions[i].second;\n            pos2idx[positions[i].second.first * N + positions[i].second.second] = i;\n        }\n\n        // Initial placement: best seeds in highest degree positions\n        vector<int> placement(S); // position idx -> seed idx (0..S-1 in selected)\n        iota(placement.begin(), placement.end(), 0);\n\n        // Precompute neighbor list for each position idx\n        vector<vector<int>> neighbors(S);\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    neighbors[idx].push_back(pos2idx[ni * N + nj]);\n                }\n            }\n        }\n\n        auto calcCell = [&](int idx) {\n            ll s = 0;\n            int seed = placement[idx];\n            for (int nb : neighbors[idx]) {\n                s += edgeScore[seed][placement[nb]];\n            }\n            return s;\n        };\n\n        auto totalScore = [&]() {\n            ll s = 0;\n            for (int i = 0; i < S; i++) {\n                s += calcCell(i);\n            }\n            return s / 2; // Each edge counted twice\n        };\n\n        // Simulated Annealing\n        double temp = 1000.0;\n        const double cooling = 0.9998;\n        \n        // Time management\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        double time_limit = 1.9; // Keep some margin\n        double time_per_turn = (time_limit - elapsed) / (total_turns - turn);\n        \n        ll currentScore = 0;\n        for (int i = 0; i < S; i++) currentScore += calcCell(i);\n        currentScore /= 2;\n\n        int iterations = 0;\n        while (true) {\n            now = chrono::steady_clock::now();\n            double time_used = chrono::duration<double>(now - start_time).count();\n            if (time_used > time_limit * (turn + 1) / total_turns) break;\n\n            int idx1 = rng() % S;\n            int idx2 = rng() % S;\n            if (idx1 == idx2) continue;\n\n            // Calculate delta\n            ll oldContrib = calcCell(idx1) + calcCell(idx2);\n            \n            // If adjacent, the edge between them is counted in both calcCell\n            // Since edgeScore is symmetric, swapping doesn't change the shared edge contribution\n            // So we don't need to subtract anything special\n            \n            swap(placement[idx1], placement[idx2]);\n            \n            ll newContrib = calcCell(idx1) + calcCell(idx2);\n            ll delta = newContrib - oldContrib;\n\n            if (delta > 0 || exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore += delta;\n            } else {\n                swap(placement[idx1], placement[idx2]); // Revert\n            }\n\n            temp *= cooling;\n            iterations++;\n            if (iterations > 200000) break; // Safety\n        }\n\n        // Local search refinement (hill climbing)\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int idx1 = 0; idx1 < S && !improved; idx1++) {\n                for (int idx2 = idx1 + 1; idx2 < S && !improved; idx2++) {\n                    ll oldContrib = calcCell(idx1) + calcCell(idx2);\n                    swap(placement[idx1], placement[idx2]);\n                    ll newContrib = calcCell(idx1) + calcCell(idx2);\n                    if (newContrib > oldContrib) {\n                        currentScore += newContrib - oldContrib;\n                        improved = true;\n                    } else {\n                        swap(placement[idx1], placement[idx2]);\n                    }\n                }\n            }\n        }\n\n        // Generate output grid\n        vector<vector<int>> output(N, vector<int>(N));\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            output[i][j] = selected[placement[idx]];\n        }\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j > 0) cout << ' ';\n                cout << output[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n    }\n\n    void solve() {\n        cin >> N >> M >> T;\n        SEED_COUNT = 2 * N * (N - 1);\n        seeds.resize(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].x.resize(M);\n            seeds[i].sum = 0;\n            seeds[i].mx = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].x[j];\n                seeds[i].sum += seeds[i].x[j];\n                seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n            }\n        }\n\n        for (int turn = 0; turn < T; turn++) {\n            solveOneTurn(turn, T);\n\n            // Read next generation\n            for (int i = 0; i < SEED_COUNT; i++) {\n                seeds[i].sum = 0;\n                seeds[i].mx = 0;\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i].x[j];\n                    seeds[i].sum += seeds[i].x[j];\n                    seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V_limit;\nvector<pair<int,int>> sources, targets;\n\n// Hungarian algorithm for minimum cost perfect matching\nvector<int> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i=1; i<=n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INT_MAX);\n        vector<char> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INT_MAX, j1 = 0;\n            for (int j=1; j<=m; j++) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j=0; j<=m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> match(n);\n    for (int j=1; j<=m; j++) {\n        if (p[j] != 0) match[p[j]-1] = j-1;\n    }\n    return match;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> V_limit;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i=0; i<N; i++) cin >> s_grid[i];\n    for (int i=0; i<N; i++) cin >> t_grid[i];\n\n    // Collect positions (x=row, y=col)\n    for (int i=0; i<N; i++) {\n        for (int j=0; j<N; j++) {\n            if (s_grid[i][j] == '1') sources.push_back({i, j});\n            if (t_grid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    // Build cost matrix (Manhattan distance)\n    vector<vector<int>> cost(M, vector<int>(M));\n    for (int i=0; i<M; i++) {\n        for (int j=0; j<M; j++) {\n            cost[i][j] = abs(sources[i].first - targets[j].first) \n                       + abs(sources[i].second - targets[j].second);\n        }\n    }\n    \n    vector<int> match = hungarian(cost);\n    \n    // Create pairs (source, target)\n    vector<pair<pair<int,int>, pair<int,int>>> pairs;\n    for (int i=0; i<M; i++) {\n        pairs.push_back({sources[i], targets[match[i]]});\n    }\n\n    // Build dependency graph: if target of i is source of j, then j must come before i\n    // (we must pick up from j's source before dropping at i's target)\n    map<pair<int,int>, int> src_to_idx;\n    for (int i=0; i<M; i++) {\n        src_to_idx[pairs[i].first] = i;\n    }\n    \n    vector<vector<int>> adj(M);\n    vector<int> indeg(M, 0);\n    for (int i=0; i<M; i++) {\n        auto it = src_to_idx.find(pairs[i].second);\n        if (it != src_to_idx.end()) {\n            int j = it->second; // pairs[j].first == pairs[i].second\n            if (i != j) { // self-loop not needed (pickup then drop at same spot is fine)\n                adj[j].push_back(i); // j must come before i\n                indeg[i]++;\n            }\n        }\n    }\n\n    // Topological greedy ordering\n    vector<pair<pair<int,int>, pair<int,int>>> ordered;\n    vector<bool> processed(M, false);\n    int cur_x = 0, cur_y = 0; // current arm root position for greedy selection\n    \n    for (int iter=0; iter<M; iter++) {\n        int best_i = -1;\n        int best_dist = INT_MAX;\n        \n        // Find available pair (indeg == 0) with minimum distance\n        for (int i=0; i<M; i++) {\n            if (processed[i] || indeg[i] > 0) continue;\n            int d = abs(cur_x - pairs[i].first.first) \n                  + abs(cur_y - pairs[i].first.second);\n            if (d < best_dist) {\n                best_dist = d;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) {\n            // Should not happen with valid input, but break to avoid infinite loop\n            break;\n        }\n        \n        processed[best_i] = true;\n        ordered.push_back(pairs[best_i]);\n        cur_x = pairs[best_i].second.first;\n        cur_y = pairs[best_i].second.second;\n        \n        for (int nb : adj[best_i]) {\n            indeg[nb]--;\n        }\n    }\n\n    // Output tree: 2 vertices (root + fingertip), edge length 1\n    cout << 2 << \"\\n\";\n    cout << \"0 1\\n\";\n    cout << \"0 0\\n\";\n\n    // Simulation\n    const int L = 1;\n    int rx = 0, ry = 0;\n    int dir = 0; // 0=right, 1=down, 2=left, 3=up\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    auto move_to = [&](int tx, int ty) {\n        // Find best direction to approach target\n        int best_d = 0;\n        int best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = tx - dx[d] * L;\n            int ny = ty - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manhattan = abs(rx - nx) + abs(ry - ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manhattan, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        \n        int nx = tx - dx[best_d] * L;\n        int ny = ty - dy[best_d] * L;\n        \n        // Move and rotate until positioned\n        while (rx != nx || ry != ny || dir != best_d) {\n            string cmd(4, '.');\n            \n            // Move root toward target\n            if (rx < nx) { cmd[0] = 'D'; rx++; }\n            else if (rx > nx) { cmd[0] = 'U'; rx--; }\n            else if (ry < ny) { cmd[0] = 'R'; ry++; }\n            else if (ry > ny) { cmd[0] = 'L'; ry--; }\n            \n            // Rotate if needed\n            if (dir != best_d) {\n                int diff = (best_d - dir + 4) % 4;\n                if (diff == 1) {\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                } else if (diff == 3) {\n                    cmd[1] = 'L';\n                    dir = (dir + 3) % 4;\n                } else { // diff == 2, rotate 90 and continue\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                }\n            }\n            cout << cmd << \"\\n\";\n        }\n    };\n    \n    auto perform_pickup = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P'; // fingertip is vertex 1 (index 3 in string: 0=move, 1=rot1, 2=root_action, 3=leaf_action)\n        cout << cmd << \"\\n\";\n    };\n    \n    auto perform_drop = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P';\n        cout << cmd << \"\\n\";\n    };\n\n    // Execute\n    for (auto& [src, dst] : ordered) {\n        // Move to source and pickup\n        move_to(src.first, src.second);\n        perform_pickup();\n        \n        // Move to destination and drop\n        move_to(dst.first, dst.second);\n        perform_drop();\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Node {\n    int sum = 0;\n    int best = 0;        // max subarray sum\n    int left_best = 0;   // max prefix sum\n    int right_best = 0;  // max suffix sum\n    int best_l = 0, best_r = 0; // indices of best subarray\n    int left_pos = 0;    // rightmost index of max prefix (end point)\n    int right_pos = 0;   // leftmost index of max suffix (start point)\n};\n\nclass SegTree {\n    int n;\n    int Y; // actual size\n    vector<Node> tree;\npublic:\n    SegTree(int size) {\n        Y = size;\n        n = 1;\n        while (n < Y) n <<= 1;\n        tree.resize(2 * n);\n        init(1, 0, n - 1);\n    }\n\n    void init(int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].left_pos = l;\n            tree[idx].right_pos = r;\n            tree[idx].best_l = l;\n            tree[idx].best_r = r;\n            // If beyond valid range, set to -INF so never chosen\n            if (l >= Y) {\n                tree[idx].best = -INF;\n                tree[idx].left_best = -INF;\n                tree[idx].right_best = -INF;\n                tree[idx].sum = 0;\n            }\n            return;\n        }\n        int mid = (l + r) >> 1;\n        init(idx << 1, l, mid);\n        init(idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    void pull(int idx, int left, int right) {\n        Node &res = tree[idx];\n        Node &L = tree[left];\n        Node &R = tree[right];\n\n        res.sum = L.sum + R.sum;\n\n        // Left prefix (max sum starting from left boundary)\n        if (L.left_best >= L.sum + R.left_best) {\n            res.left_best = L.left_best;\n            res.left_pos = L.left_pos;\n        } else {\n            res.left_best = L.sum + R.left_best;\n            res.left_pos = R.left_pos; // FIXED: takes end index from right child\n        }\n\n        // Right suffix (max sum ending at right boundary)\n        if (R.right_best >= R.sum + L.right_best) {\n            res.right_best = R.right_best;\n            res.right_pos = R.right_pos;\n        } else {\n            res.right_best = R.sum + L.right_best;\n            res.right_pos = L.right_pos; // FIXED: takes start index from left child\n        }\n\n        // Best subarray\n        res.best = L.best;\n        res.best_l = L.best_l;\n        res.best_r = L.best_r;\n\n        if (R.best > res.best) {\n            res.best = R.best;\n            res.best_l = R.best_l;\n            res.best_r = R.best_r;\n        }\n\n        int cross = L.right_best + R.left_best;\n        if (cross > res.best) {\n            res.best = cross;\n            res.best_l = L.right_pos; // Start of left suffix\n            res.best_r = R.left_pos;  // End of right prefix\n        }\n    }\n\n    void update(int pos, int val) { update(pos, val, 1, 0, n - 1); }\n\n    void update(int pos, int val, int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].sum += val;\n            tree[idx].best += val;\n            tree[idx].left_best += val;\n            tree[idx].right_best += val;\n            return;\n        }\n        int mid = (l + r) >> 1;\n        if (pos <= mid) update(pos, val, idx << 1, l, mid);\n        else update(pos, val, idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    const Node& query() const { return tree[1]; }\n};\n\nstruct Point {\n    int x, y;\n    int type; // +1 for mackerel, -1 for sardine\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    \n    vector<Point> points;\n    points.reserve(2 * N);\n    vector<int> all_x, all_y;\n    all_x.reserve(2 * N);\n    all_y.reserve(2 * N);\n\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Coordinate compression for y\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n    int Y = all_y.size();\n\n    // Group points by x-coordinate\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    \n    map<int, vector<pair<int, int>>> x_to_points; // x -> list of (y_idx, type)\n    for (const auto &p : points) {\n        int y_idx = lower_bound(all_y.begin(), all_y.end(), p.y) - all_y.begin();\n        x_to_points[p.x].push_back({y_idx, p.type});\n    }\n\n    // Select candidate x-coordinates (up to 1000 with highest density)\n    vector<int> x_cands = all_x;\n    if (x_cands.size() > 1000) {\n        vector<pair<int, int>> cnts;\n        for (int x : x_cands) {\n            cnts.push_back({-(int)x_to_points[x].size(), x}); // negative for min-heap simulation\n        }\n        sort(cnts.begin(), cnts.end()); // sort by count descending\n        x_cands.clear();\n        for (int i = 0; i < 1000; ++i) x_cands.push_back(cnts[i].second);\n        sort(x_cands.begin(), x_cands.end());\n    }\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 1, best_y1 = 0, best_y2 = 1;\n\n    // Sweep line\n    for (size_t i = 0; i < x_cands.size(); ++i) {\n        SegTree seg(Y);\n        for (size_t j = i; j < x_cands.size(); ++j) {\n            int x = x_cands[j];\n            auto it = x_to_points.find(x);\n            if (it != x_to_points.end()) {\n                for (const auto &[y_idx, typ] : it->second) {\n                    seg.update(y_idx, typ);\n                }\n            }\n            \n            const Node &res = seg.query();\n            if (res.best > best_score) {\n                // Validate indices are within bounds\n                if (res.best_l >= 0 && res.best_l < Y && res.best_r >= 0 && res.best_r < Y) {\n                    best_score = res.best;\n                    best_x1 = x_cands[i];\n                    best_x2 = x;\n                    best_y1 = all_y[res.best_l];\n                    best_y2 = all_y[res.best_r];\n                    if (best_y1 > best_y2) swap(best_y1, best_y2);\n                }\n            }\n        }\n    }\n\n    // Ensure valid rectangle (distinct vertices, positive area)\n    if (best_x1 == best_x2) {\n        if (best_x2 < 100000) best_x2++;\n        else best_x1--;\n    }\n    if (best_y1 == best_y2) {\n        if (best_y2 < 100000) best_y2++;\n        else best_y1--;\n    }\n\n    // Output rectangle\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        double w, h;\n        cin >> w >> h;\n        w_est[i] = w;\n        h_est[i] = h;\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        vector<double> x(N, 0), y(N, 0);\n        vector<int> rot(N, 0);\n        vector<Placement> ops;\n        ops.reserve(N);\n        \n        double cur_W = 0, cur_H = 0;\n        \n        for (int i = 0; i < N; i++) {\n            double best_score = 1e300;\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            double best_x = 0, best_y = 0;\n            \n            for (int r = 0; r < 2; r++) {\n                double wi = r ? h_est[i] : w_est[i];\n                double hi = r ? w_est[i] : h_est[i];\n                \n                // Try both directions\n                for (char d : {'U', 'L'}) {\n                    // Try all possible bases\n                    for (int b = -1; b < i; b++) {\n                        double xi, yi;\n                        \n                        if (d == 'U') {\n                            // Fix x based on b\n                            if (b == -1) {\n                                xi = 0;\n                            } else {\n                                double wb = rot[b] ? h_est[b] : w_est[b];\n                                xi = x[b] + wb;\n                            }\n                            \n                            // Find y by checking overlaps (skyline)\n                            yi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check x-overlap: [xi, xi+wi) vs [xj, xj+wj)\n                                if (max(xi, xj) < min(xi + wi, xj + wj)) {\n                                    yi = max(yi, yj + hj);\n                                }\n                            }\n                        } else { // 'L'\n                            // Fix y based on b\n                            if (b == -1) {\n                                yi = 0;\n                            } else {\n                                double hb = rot[b] ? w_est[b] : h_est[b];\n                                yi = y[b] + hb;\n                            }\n                            \n                            // Find x by checking overlaps\n                            xi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check y-overlap: [yi, yi+hi) vs [yj, yj+hj)\n                                if (max(yi, yj) < min(yi + hi, yj + hj)) {\n                                    xi = max(xi, xj + wj);\n                                }\n                            }\n                        }\n                        \n                        double new_W = max(cur_W, xi + wi);\n                        double new_H = max(cur_H, yi + hi);\n                        double score = new_W + new_H;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            best_x = xi;\n                            best_y = yi;\n                        }\n                    }\n                }\n            }\n            \n            rot[i] = best_r;\n            x[i] = best_x;\n            y[i] = best_y;\n            ops.push_back({i, best_r, best_b, best_d});\n            \n            double wi = best_r ? h_est[i] : w_est[i];\n            double hi = best_r ? w_est[i] : h_est[i];\n            cur_W = max(cur_W, best_x + wi);\n            cur_H = max(cur_H, best_y + hi);\n        }\n        \n        // Output\n        cout << N << \"\\n\";\n        for (const auto& op : ops) {\n            cout << op.p << \" \" << op.r << \" \" << op.d << \" \" << op.b << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read feedback\n        double Wp, Hp;\n        cin >> Wp >> Hp;\n        \n        // Update estimates based on feedback\n        // Compute current max based on estimates\n        double max_right = 0;\n        double max_bottom = 0;\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            max_right = max(max_right, x[i] + wi);\n            max_bottom = max(max_bottom, y[i] + hi);\n        }\n        \n        // Update width estimates for critical rectangles\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            \n            // Check if this rectangle determines the width boundary\n            if (abs(x[i] + wi - max_right) < 1e-6) {\n                double target = Wp - x[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                } else {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                }\n            }\n            \n            // Check if this rectangle determines the height boundary\n            if (abs(y[i] + hi - max_bottom) < 1e-6) {\n                double target = Hp - y[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                } else {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> parent;\n    vector<int> depth;\n    vector<long long> sub_sum;\n    vector<int> height;\n    vector<vector<int>> children;\n    \n    void input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; i++) cin >> A[i];\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v; cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // Skip coordinates\n        for (int i = 0; i < N; i++) {\n            int x, y; cin >> x >> y;\n        }\n    }\n    \n    // Compute sub_sum and height for tree rooted at root\n    void dfs_info(int v) {\n        sub_sum[v] = A[v];\n        height[v] = 0;\n        for (int c : children[v]) {\n            dfs_info(c);\n            sub_sum[v] += sub_sum[c];\n            height[v] = max(height[v], height[c] + 1);\n        }\n    }\n    \n    void compute_all_info() {\n        children.assign(N, {});\n        for (int i = 0; i < N; i++) {\n            if (parent[i] != -1) {\n                children[parent[i]].push_back(i);\n            }\n        }\n        sub_sum.assign(N, 0);\n        height.assign(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) {\n                dfs_info(i);\n            }\n        }\n    }\n    \n    long long calc_score() {\n        long long res = 0;\n        for (int i = 0; i < N; i++) {\n            res += (long long)(depth[i] + 1) * A[i];\n        }\n        return res;\n    }\n    \n    bool is_ancestor(int u, int v) {\n        // check if u is ancestor of v\n        int cur = v;\n        while (cur != -1) {\n            if (cur == u) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n    \n    void update_depths(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) {\n            update_depths(c, delta);\n        }\n    }\n    \n    void greedy_construct() {\n        parent.assign(N, -1);\n        depth.assign(N, -1);\n        vector<long long> path_sum(N, 0);\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return A[i] > A[j];\n        });\n        \n        for (int v : order) {\n            int best_parent = -1;\n            int best_depth = -1;\n            long long best_path_sum = -1;\n            \n            for (int u : adj[v]) {\n                if (depth[u] != -1 && depth[u] < H) {\n                    if (depth[u] > best_depth || (depth[u] == best_depth && path_sum[u] > best_path_sum)) {\n                        best_depth = depth[u];\n                        best_parent = u;\n                        best_path_sum = path_sum[u];\n                    }\n                }\n            }\n            \n            if (best_parent == -1) {\n                parent[v] = -1;\n                depth[v] = 0;\n                path_sum[v] = A[v];\n            } else {\n                parent[v] = best_parent;\n                depth[v] = depth[best_parent] + 1;\n                path_sum[v] = path_sum[best_parent] + A[v];\n            }\n        }\n    }\n    \n    void local_search() {\n        // Steepest ascent local search\n        bool improved = true;\n        int max_iter = 50;\n        int iter = 0;\n        \n        while (improved && iter < max_iter) {\n            improved = false;\n            iter++;\n            \n            // Try all possible moves and pick the best\n            long long best_gain = 0;\n            int best_v = -1, best_new_parent = -1;\n            \n            // Randomize order to avoid bias\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            random_shuffle(order.begin(), order.end());\n            \n            for (int v : order) {\n                int cur_depth = depth[v];\n                long long cur_sub = sub_sum[v];\n                int cur_height = height[v];\n                \n                // Try all neighbors as new parent\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (depth[u] == -1) continue; // should not happen after greedy\n                    if (depth[u] >= H) continue; // cannot be parent\n                    \n                    int new_depth = depth[u] + 1;\n                    if (new_depth <= cur_depth) continue; // no improvement in depth\n                    \n                    // Check if u is in subtree of v (would create cycle)\n                    if (is_ancestor(v, u)) continue;\n                    \n                    // Check height constraint: new_depth + height[v] <= H\n                    if (new_depth + cur_height > H) continue;\n                    \n                    long long gain = (long long)(new_depth - cur_depth) * cur_sub;\n                    \n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_v = v;\n                        best_new_parent = u;\n                    }\n                }\n            }\n            \n            if (best_gain > 0) {\n                // Apply the move\n                int v = best_v;\n                int u = best_new_parent;\n                int old_parent = parent[v];\n                \n                // Remove from old parent\n                if (old_parent != -1) {\n                    auto& vec = children[old_parent];\n                    vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n                }\n                \n                // Add to new parent\n                parent[v] = u;\n                children[u].push_back(v);\n                \n                // Update depths for subtree v\n                int delta = depth[u] + 1 - depth[v];\n                update_depths(v, delta);\n                \n                // Recompute all info (sub_sum, height) from roots\n                // This is necessary because sub_sum and height of ancestors changed\n                compute_all_info();\n                \n                improved = true;\n            }\n        }\n    }\n    \n    void solve() {\n        input();\n        greedy_construct();\n        compute_all_info();\n        local_search();\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            if (i) cout << \" \";\n            cout << parent[i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // For local search randomization\n    srand(time(0));\n    \n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<string> C(N);\n    for (int i = 0; i < N; i++) cin >> C[i];\n    \n    vector<vector<bool>> is_oni(N, vector<bool>(N, false));\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (C[i][j] == 'x') {\n                is_oni[i][j] = true;\n            } else if (C[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    // Precompute safe ranges for each column\n    vector<int> max_up(N, -1);    // max row where Up is safe (no fuku in [0, row])\n    vector<int> min_down(N, N);   // min row where Down is safe (no fuku in [row, N-1])\n    \n    for (int j = 0; j < N; j++) {\n        int first_fuku = N;\n        for (int i = 0; i < N; i++) {\n            if (is_fuku[i][j]) {\n                first_fuku = i;\n                break;\n            }\n        }\n        max_up[j] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int i = N-1; i >= 0; i--) {\n            if (is_fuku[i][j]) {\n                last_fuku = i;\n                break;\n            }\n        }\n        min_down[j] = last_fuku + 1;\n    }\n    \n    // Precompute safe ranges for each row\n    vector<int> max_left(N, -1);  // max col where Left is safe\n    vector<int> min_right(N, N);  // min col where Right is safe\n    \n    for (int i = 0; i < N; i++) {\n        int first_fuku = N;\n        for (int j = 0; j < N; j++) {\n            if (is_fuku[i][j]) {\n                first_fuku = j;\n                break;\n            }\n        }\n        max_left[i] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int j = N-1; j >= 0; j--) {\n            if (is_fuku[i][j]) {\n                last_fuku = j;\n                break;\n            }\n        }\n        min_right[i] = last_fuku + 1;\n    }\n    \n    vector<pair<char, int>> ops;\n    \n    while (true) {\n        double best_eff = -1.0;\n        int best_gain = 0;\n        int best_cost = 0;\n        char best_dir = 0;\n        int best_idx = 0;\n        int best_limit = 0; // row for U/D, col for L/R\n        \n        // Check columns for Up\n        for (int j = 0; j < N; j++) {\n            if (max_up[j] < 0) continue;\n            int highest = -1;\n            int count = 0;\n            for (int i = 0; i <= max_up[j]; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    highest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (highest + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost) || best_gain == 0) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'U';\n                best_idx = j;\n                best_limit = highest;\n            }\n        }\n        \n        // Check columns for Down\n        for (int j = 0; j < N; j++) {\n            if (min_down[j] >= N) continue;\n            int lowest = N;\n            int count = 0;\n            for (int i = min_down[j]; i < N; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    lowest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - lowest);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'D';\n                best_idx = j;\n                best_limit = lowest;\n            }\n        }\n        \n        // Check rows for Left\n        for (int i = 0; i < N; i++) {\n            if (max_left[i] < 0) continue;\n            int rightmost = -1;\n            int count = 0;\n            for (int j = 0; j <= max_left[i]; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    rightmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (rightmost + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'L';\n                best_idx = i;\n                best_limit = rightmost;\n            }\n        }\n        \n        // Check rows for Right\n        for (int i = 0; i < N; i++) {\n            if (min_right[i] >= N) continue;\n            int leftmost = N;\n            int count = 0;\n            for (int j = min_right[i]; j < N; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    leftmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - leftmost);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'R';\n                best_idx = i;\n                best_limit = leftmost;\n            }\n        }\n        \n        if (best_gain == 0) break; // No more Oni\n        \n        // Apply the best operation\n        if (best_dir == 'U') {\n            int j = best_idx;\n            int h = best_limit;\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('U', j);\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('D', j);\n            for (int i = 0; i <= h; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'D') {\n            int j = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('D', j);\n            for (int k = 0; k < times; k++) ops.emplace_back('U', j);\n            for (int i = l; i < N; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'L') {\n            int i = best_idx;\n            int r = best_limit;\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('L', i);\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('R', i);\n            for (int j = 0; j <= r; j++) is_oni[i][j] = false;\n        } else if (best_dir == 'R') {\n            int i = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('R', i);\n            for (int k = 0; k < times; k++) ops.emplace_back('L', i);\n            for (int j = l; j < N; j++) is_oni[i][j] = false;\n        }\n    }\n    \n    // Output\n    for (auto &[d, p] : ops) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    // Best solution found\n    vector<int> best_a(N), best_b(N);\n    long long best_error = (1LL << 60);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_node(0, N-1);\n    uniform_int_distribution<int> dist_choice(0, 1);\n    \n    const auto TIME_LIMIT = 1900; // ms, leave some margin\n    \n    auto evaluate = [&](const vector<int>& a, const vector<int>& b) -> long long {\n        vector<int> cnt(N, 0);\n        int cur = 0;\n        for (int week = 0; week < L; ++week) {\n            cnt[cur]++;\n            if (week == L - 1) break;\n            // If count is odd (1, 3, 5...), go to a[cur]\n            // Since we just incremented, cnt[cur] is the current count\n            if (cnt[cur] & 1) {\n                cur = a[cur];\n            } else {\n                cur = b[cur];\n            }\n        }\n        long long err = 0;\n        for (int i = 0; i < N; ++i) {\n            err += llabs((long long)cnt[i] - T[i]);\n        }\n        return err;\n    };\n    \n    auto solve_one = [&](int seed) {\n        mt19937 local_rng(seed);\n        vector<int> a(N), b(N);\n        \n        // Greedy initialization based on flow approximation\n        // Each node i sends ceil(T[i]/2) to a[i] and floor(T[i]/2) to b[i]\n        // We want to satisfy demands T[j] for each node j\n        vector<long long> remaining(N);\n        for (int i = 0; i < N; ++i) remaining[i] = T[i];\n        \n        for (int i = 0; i < N; ++i) {\n            // Find node with max remaining demand for a[i]\n            int max_j = 0;\n            for (int j = 1; j < N; ++j) {\n                if (remaining[j] > remaining[max_j]) max_j = j;\n            }\n            a[i] = max_j;\n            remaining[max_j] -= (T[i] + 1) / 2; // ceil(T[i]/2)\n            \n            // Find node with max remaining demand for b[i]\n            max_j = 0;\n            for (int j = 1; j < N; ++j) {\n                if (remaining[j] > remaining[max_j]) max_j = j;\n            }\n            b[i] = max_j;\n            remaining[max_j] -= T[i] / 2; // floor(T[i]/2)\n        }\n        \n        // Ensure valid range\n        for (int i = 0; i < N; ++i) {\n            a[i] = max(0, min(N-1, a[i]));\n            b[i] = max(0, min(N-1, b[i]));\n        }\n        \n        long long cur_error = evaluate(a, b);\n        if (cur_error < best_error) {\n            best_error = cur_error;\n            best_a = a;\n            best_b = b;\n        }\n        \n        auto start_time = chrono::steady_clock::now();\n        int iter = 0;\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n            \n            ++iter;\n            \n            // Random modification\n            int idx = uniform_int_distribution<int>(0, N-1)(local_rng);\n            int choice = uniform_int_distribution<int>(0, 1)(local_rng);\n            int new_val = uniform_int_distribution<int>(0, N-1)(local_rng);\n            \n            int old_val;\n            if (choice == 0) {\n                old_val = a[idx];\n                a[idx] = new_val;\n            } else {\n                old_val = b[idx];\n                b[idx] = new_val;\n            }\n            \n            long long new_error = evaluate(a, b);\n            \n            if (new_error <= cur_error) {\n                cur_error = new_error;\n                if (cur_error < best_error) {\n                    best_error = cur_error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                // Revert\n                if (choice == 0) a[idx] = old_val;\n                else b[idx] = old_val;\n            }\n        }\n    };\n    \n    // Try multiple seeds\n    vector<int> seeds = {42, 123, 456, 789, 101112, 131415, 161718, 192021, 222324, 252627};\n    for (int s : seeds) {\n        auto start = chrono::steady_clock::now();\n        solve_one(s);\n        auto end = chrono::steady_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count();\n        if (elapsed > TIME_LIMIT) break; // Don't start new if almost out of time\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Estimated centers\n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n    \n    // Recursive bisection to create spatially coherent groups\n    vector<int> groupId(N, -1);\n    vector<vector<int>> groups(M);\n    \n    function<void(vector<int>&, int, int, int)> partition = [&](vector<int>& ids, int gl, int gr, int depth) {\n        // Assigns cities in ids to groups [gl, gr)\n        if (gl + 1 == gr) {\n            for (int id : ids) {\n                groupId[id] = gl;\n                groups[gl].push_back(id);\n            }\n            return;\n        }\n        \n        // Split point for groups\n        int gmid = (gl + gr) / 2;\n        int leftSize = 0;\n        for (int i = gl; i < gmid; ++i) leftSize += G[i];\n        \n        // Sort by x or y depending on depth\n        if (depth % 2 == 0) {\n            sort(ids.begin(), ids.end(), [&](int a, int b) {\n                if (cx[a] != cx[b]) return cx[a] < cx[b];\n                return cy[a] < cy[b];\n            });\n        } else {\n            sort(ids.begin(), ids.end(), [&](int a, int b) {\n                if (cy[a] != cy[b]) return cy[a] < cy[b];\n                return cx[a] < cx[b];\n            });\n        }\n        \n        vector<int> left(ids.begin(), ids.begin() + leftSize);\n        vector<int> right(ids.begin() + leftSize, ids.end());\n        \n        partition(left, gl, gmid, depth + 1);\n        partition(right, gmid, gr, depth + 1);\n    };\n    \n    vector<int> allIds(N);\n    iota(allIds.begin(), allIds.end(), 0);\n    partition(allIds, 0, M, 0);\n    \n    // For each group, build spanning tree using sliding window queries\n    vector<vector<pair<int,int>>> groupEdges(M);\n    int queriesUsed = 0;\n    \n    for (int gi = 0; gi < M; ++gi) {\n        auto &grp = groups[gi];\n        int gsize = (int)grp.size();\n        if (gsize <= 1) continue;\n        \n        // Sort group by position for sliding window (alternating to match partition)\n        sort(grp.begin(), grp.end(), [&](int a, int b) {\n            if (cx[a] != cx[b]) return cx[a] < cx[b];\n            return cy[a] < cy[b];\n        });\n        \n        // Sliding window: query [i, i+L-1] overlapping by 1 to ensure connectivity\n        for (int i = 0; i < gsize - 1; i += L - 1) {\n            int batchSize = min(L, gsize - i);\n            vector<int> querySet;\n            querySet.reserve(batchSize);\n            for (int j = 0; j < batchSize; ++j) {\n                querySet.push_back(grp[i + j]);\n            }\n            \n            // Make sure we don't exceed query limit\n            if (queriesUsed >= Q) break;\n            \n            cout << \"? \" << (int)querySet.size();\n            for (int v : querySet) cout << ' ' << v;\n            cout << '\\n';\n            cout.flush();\n            \n            int edgesToRead = (int)querySet.size() - 1;\n            for (int j = 0; j < edgesToRead; ++j) {\n                int a, b;\n                cin >> a >> b;\n                groupEdges[gi].emplace_back(a, b);\n            }\n            ++queriesUsed;\n        }\n    }\n    \n    // Output\n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << ' ';\n            cout << grp[i];\n        }\n        cout << '\\n';\n        for (auto [a, b] : groupEdges[gi]) {\n            cout << a << ' ' << b << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.emplace_back(r, c);\n    }\n    \n    vector<pair<char,char>> ans;\n    auto add_move = [&](char d, int cnt) {\n        for (int i = 0; i < cnt; i++) ans.emplace_back('M', d);\n    };\n    auto add_slide = [&](char d) {\n        ans.emplace_back('S', d);\n    };\n    \n    int cr = r0, cc = c0;\n    const int MAXC = N - 1; // 19\n    \n    for (auto [tr, tc] : targets) {\n        int dr = tr - cr;\n        int dc = tc - cc;\n        int abs_dr = abs(dr);\n        int abs_dc = abs(dc);\n        \n        // Direct Manhattan\n        int best_cost = abs_dr + abs_dc;\n        int strategy = 0; // 0=direct, 1=top, 2=bot, 3=left, 4=right, 5=corner\n        \n        // Via Top: slide up to row 0, walk horiz, walk down to tr\n        int cost_top = 1 + abs_dc + tr;\n        if (cost_top < best_cost) {\n            best_cost = cost_top;\n            strategy = 1;\n        }\n        \n        // Via Bottom: slide down to row 19, walk horiz, walk up to tr\n        int cost_bot = 1 + abs_dc + (MAXC - tr);\n        if (cost_bot < best_cost) {\n            best_cost = cost_bot;\n            strategy = 2;\n        }\n        \n        // Via Left: slide left to col 0, walk vert, walk right to tc\n        int cost_left = 1 + abs_dr + tc;\n        if (cost_left < best_cost) {\n            best_cost = cost_left;\n            strategy = 3;\n        }\n        \n        // Via Right: slide right to col 19, walk vert, walk left to tc\n        int cost_right = 1 + abs_dr + (MAXC - tc);\n        if (cost_right < best_cost) {\n            best_cost = cost_right;\n            strategy = 4;\n        }\n        \n        // Via Corner: 2 slides to a corner, then walk\n        int dist_from_corner = min(tr, MAXC - tr) + min(tc, MAXC - tc);\n        int cost_corner = 2 + dist_from_corner;\n        if (cost_corner < best_cost) {\n            best_cost = cost_corner;\n            strategy = 5;\n        }\n        \n        if (strategy == 0) {\n            // Direct: move vertical then horizontal (order doesn't matter)\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n        } else if (strategy == 1) {\n            // Via top\n            add_slide('U');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('D', tr); // down from row 0 to tr\n        } else if (strategy == 2) {\n            // Via bottom\n            add_slide('D');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('U', MAXC - tr); // up from row 19 to tr\n        } else if (strategy == 3) {\n            // Via left\n            add_slide('L');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('R', tc); // right from col 0 to tc\n        } else if (strategy == 4) {\n            // Via right\n            add_slide('R');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('L', MAXC - tc); // left from col 19 to tc\n        } else if (strategy == 5) {\n            // Via best corner\n            // Determine which corner is best (gives min walking distance)\n            int best_corner = 0; // 0:TL, 1:TR, 2:BL, 3:BR\n            int best_corner_cost = 1000;\n            // TL (0,0): walk down tr, right tc. Cost: tr + tc\n            if (tr + tc < best_corner_cost) { best_corner_cost = tr + tc; best_corner = 0; }\n            // TR (0,19): down tr, left (19-tc)\n            if (tr + (MAXC - tc) < best_corner_cost) { best_corner_cost = tr + (MAXC - tc); best_corner = 1; }\n            // BL (19,0): up (19-tr), right tc\n            if ((MAXC - tr) + tc < best_corner_cost) { best_corner_cost = (MAXC - tr) + tc; best_corner = 2; }\n            // BR (19,19): up (19-tr), left (19-tc)\n            if ((MAXC - tr) + (MAXC - tc) < best_corner_cost) { best_corner_cost = (MAXC - tr) + (MAXC - tc); best_corner = 3; }\n            \n            if (best_corner == 0) {\n                add_slide('U');\n                add_slide('L');\n                add_move('D', tr);\n                add_move('R', tc);\n            } else if (best_corner == 1) {\n                add_slide('U');\n                add_slide('R');\n                add_move('D', tr);\n                add_move('L', MAXC - tc);\n            } else if (best_corner == 2) {\n                add_slide('D');\n                add_slide('L');\n                add_move('U', MAXC - tr);\n                add_move('R', tc);\n            } else {\n                add_slide('D');\n                add_slide('R');\n                add_move('U', MAXC - tr);\n                add_move('L', MAXC - tc);\n            }\n        }\n        \n        cr = tr;\n        cc = tc;\n    }\n    \n    for (auto [a, d] : ans) {\n        cout << a << ' ' << d << \"\\n\";\n    }\n    \n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int l, r, b, t;\n    long long area() const { return 1LL * (r - l) * (t - b); }\n};\n\nint n;\nvector<int> X, Y, R;\nvector<Rect> rects; // current rectangles for leaves\n\nstruct Node {\n    bool leaf = false;\n    int idx = -1;          // if leaf\n    bool vert = false;     // if internal: true=vertical cut\n    int child[2] = {-1, -1}; // left/bottom and right/top children\n    int cut = 0;           // cut coordinate (x if vert, y if !vert)\n    // static bounds of points inside this subtree\n    int min_x = 10000, max_x = -1;\n    int min_y = 10000, max_y = -1;\n    long long sum_r = 0;\n};\nvector<Node> tree;\nint root;\n\n// build topology and static point bounds, return node id\nint build(vector<int>& ids) {\n    Node node;\n    for (int id : ids) {\n        node.min_x = min(node.min_x, X[id]);\n        node.max_x = max(node.max_x, X[id]);\n        node.min_y = min(node.min_y, Y[id]);\n        node.max_y = max(node.max_y, Y[id]);\n        node.sum_r += R[id];\n    }\n    if ((int)ids.size() == 1) {\n        node.leaf = true;\n        node.idx = ids[0];\n        int id = (int)tree.size();\n        tree.push_back(node);\n        return id;\n    }\n    // decide orientation based on spread of points\n    bool vert = (node.max_x - node.min_x) >= (node.max_y - node.min_y);\n    if (vert) {\n        sort(ids.begin(), ids.end(), [&](int a, int b){ return X[a] < X[b]; });\n    } else {\n        sort(ids.begin(), ids.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n    }\n    // split by area (balanced)\n    long long half = node.sum_r / 2;\n    long long cur = 0;\n    int split_pos = 1;\n    for (int i = 0; i < (int)ids.size(); ++i) {\n        cur += R[ids[i]];\n        if (cur >= half && i + 1 < (int)ids.size()) {\n            split_pos = i + 1;\n            break;\n        }\n    }\n    vector<int> left_ids(ids.begin(), ids.begin() + split_pos);\n    vector<int> right_ids(ids.begin() + split_pos, ids.end());\n    node.vert = vert;\n    int node_id = (int)tree.size();\n    tree.push_back(node); // placeholder to get index\n    int lch = build(left_ids);\n    int rch = build(right_ids);\n    tree[node_id].child[0] = lch;\n    tree[node_id].child[1] = rch;\n    return node_id;\n}\n\n// current bounding boxes for internal nodes during recalc\nvector<int> cur_x1, cur_y1, cur_x2, cur_y2;\n\n// recompute rects from cuts, also fills cur_x/y for internal nodes\n// returns total score sum\ndouble recalc(int v, int x1, int y1, int x2, int y2) {\n    cur_x1[v] = x1; cur_y1[v] = y1; cur_x2[v] = x2; cur_y2[v] = y2;\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        long long s = rects[node.idx].area();\n        long long r = R[node.idx];\n        double ratio = (s <= r) ? (double)s / r : (double)r / s;\n        double d = 1.0 - ratio;\n        return 1.0 - d * d;\n    }\n    double sum = 0;\n    if (node.vert) {\n        // left: [x1, cut), right: [cut, x2)\n        sum += recalc(node.child[0], x1, y1, node.cut, y2);\n        sum += recalc(node.child[1], node.cut, y1, x2, y2);\n    } else {\n        // bottom: [y1, cut), top: [cut, y2)\n        sum += recalc(node.child[0], x1, y1, x2, node.cut);\n        sum += recalc(node.child[1], x1, node.cut, x2, y2);\n    }\n    return sum;\n}\n\n// initialize cuts to be area-proportional (clamped to valid range)\nvoid init_cuts(int v, int x1, int y1, int x2, int y2) {\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        return;\n    }\n    int lch = node.child[0], rch = node.child[1];\n    if (node.vert) {\n        int lo = max(x1, tree[lch].max_x + 1);\n        int hi = min(x2, tree[rch].min_x);\n        if (lo > hi) lo = hi = (x1 + x2) / 2; // fallback, should not happen\n        // ideal cut based on area proportion\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(x1 + (x2 - x1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, node.cut, y2);\n        init_cuts(rch, node.cut, y1, x2, y2);\n    } else {\n        int lo = max(y1, tree[lch].max_y + 1);\n        int hi = min(y2, tree[rch].min_y);\n        if (lo > hi) lo = hi = (y1 + y2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(y1 + (y2 - y1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, x2, node.cut);\n        init_cuts(rch, x1, node.cut, x2, y2);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---------- input ----------\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; ++i) cin >> X[i] >> Y[i] >> R[i];\n    rects.resize(n);\n    \n    // ---------- build tree ----------\n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    tree.reserve(2 * n);\n    cur_x1.resize(2 * n);\n    cur_y1.resize(2 * n);\n    cur_x2.resize(2 * n);\n    cur_y2.resize(2 * n);\n    root = build(ids);\n    \n    // ---------- initial layout ----------\n    init_cuts(root, 0, 0, 10000, 10000);\n    double current_score = recalc(root, 0, 0, 10000, 10000);\n    \n    // ---------- Simulated Annealing ----------\n    mt19937 rng(1234567);\n    uniform_int_distribution<int> dist_node(0, (int)tree.size() - 1);\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    \n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n    long long iter = 0;\n    \n    // Precompute list of internal nodes for faster sampling\n    vector<int> internal_nodes;\n    for (int i = 0; i < (int)tree.size(); ++i) if (!tree[i].leaf) internal_nodes.push_back(i);\n    uniform_int_distribution<int> dist_internal(0, (int)internal_nodes.size() - 1);\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        ++iter;\n        // Temperature: high at start, low at end\n        double progress = elapsed / TIME_LIMIT;\n        double T = pow(0.001, progress); // from 1.0 down to 0.001\n        \n        // pick random internal node\n        int v = internal_nodes[dist_internal(rng)];\n        Node& node = tree[v];\n        \n        // get current bounds\n        int x1 = cur_x1[v], y1 = cur_y1[v], x2 = cur_x2[v], y2 = cur_y2[v];\n        int lo, hi;\n        if (node.vert) {\n            lo = max(x1, tree[node.child[0]].max_x + 1);\n            hi = min(x2, tree[node.child[1]].min_x);\n        } else {\n            lo = max(y1, tree[node.child[0]].max_y + 1);\n            hi = min(y2, tree[node.child[1]].min_y);\n        }\n        if (lo >= hi) continue; // cannot move\n        \n        int old_cut = node.cut;\n        int new_cut;\n        \n        // Move strategy: 50% small step, 50% random jump\n        if (dist_real(rng) < 0.5) {\n            int max_step = max(1, (int)(T * 200));\n            uniform_int_distribution<int> d(-max_step, max_step);\n            new_cut = old_cut + d(rng);\n        } else {\n            uniform_int_distribution<int> d(lo, hi);\n            new_cut = d(rng);\n        }\n        new_cut = clamp(new_cut, lo, hi);\n        if (new_cut == old_cut) continue;\n        \n        // apply change\n        node.cut = new_cut;\n        double new_score = recalc(root, 0, 0, 10000, 10000);\n        double delta = new_score - current_score;\n        \n        if (delta > 0 || exp(delta / T) > dist_real(rng)) {\n            current_score = new_score; // accept\n        } else {\n            node.cut = old_cut; // reject, revert and recompute\n            recalc(root, 0, 0, 10000, 10000);\n        }\n    }\n    \n    // ---------- output ----------\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].l << ' ' << rects[i].b << ' '\n             << rects[i].r << ' ' << rects[i].t << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 50;\nconstexpr int W = 50;\n\nstruct Solver {\n    static constexpr int DI[4] = {-1, 1, 0, 0};\n    static constexpr int DJ[4] = {0, 0, -1, 1};\n    static constexpr char DC[4] = {'U', 'D', 'L', 'R'};\n    \n    int si, sj;\n    vector<vector<int>> tile;\n    vector<vector<int>> val;\n    int M;\n    \n    uint32_t rng_seed = 123456789;\n    uint32_t rand_u32() {\n        rng_seed ^= rng_seed << 13;\n        rng_seed ^= rng_seed >> 17;\n        rng_seed ^= rng_seed << 5;\n        return rng_seed;\n    }\n    double rand_double() {\n        return (double)rand_u32() / UINT32_MAX;\n    }\n    \n    long long evaluate_path(const string& path) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        long long score = val[i][j];\n        \n        for (char c : path) {\n            int d = 0;\n            if (c == 'U') d = 0;\n            else if (c == 'D') d = 1;\n            else if (c == 'L') d = 2;\n            else if (c == 'R') d = 3;\n            else return -1;\n            \n            int ni = i + DI[d];\n            int nj = j + DJ[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) return -1;\n            int nt = tile[ni][nj];\n            if (vis[nt]) return -1;\n            i = ni; j = nj;\n            vis[nt] = 1;\n            score += val[i][j];\n        }\n        return score;\n    }\n    \n    string greedy_walk(double w_val, double w_deg, double dead_penalty, \n                       double w_next, bool use_random_tiebreak, int forced_first_dir = -1) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        string path;\n        path.reserve(M);\n        int steps = 0;\n        \n        while (true) {\n            struct Cand {\n                double score;\n                int dir;\n                int ni, nj;\n                int deg;\n            };\n            vector<Cand> cands;\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + DI[d];\n                int nj = j + DJ[d];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n                int nt = tile[ni][nj];\n                if (vis[nt]) continue;\n                \n                int deg = 0;\n                int max_next_val = 0;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int ni2 = ni + DI[d2];\n                    int nj2 = nj + DJ[d2];\n                    if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                    int nt2 = tile[ni2][nj2];\n                    if (nt2 == nt) continue;\n                    if (!vis[nt2]) {\n                        deg++;\n                        max_next_val = max(max_next_val, val[ni2][nj2]);\n                    }\n                }\n                \n                double base_score = val[ni][nj] * w_val;\n                \n                // Adaptive: early steps prefer connectivity, late steps prefer value\n                double phase = min(1.0, steps / 100.0);\n                base_score += deg * w_deg * (1.0 - phase * 0.5);\n                \n                if (deg == 0) {\n                    base_score -= dead_penalty;\n                }\n                \n                base_score += max_next_val * w_next;\n                \n                // Prioritize forced moves (deg == 1) slightly to avoid trapping\n                if (deg == 1) base_score += 50.0;\n                \n                if (use_random_tiebreak) {\n                    base_score += rand_double() * 0.5;\n                }\n                \n                cands.push_back({base_score, d, ni, nj, deg});\n            }\n            \n            if (cands.empty()) break;\n            \n            // Forced first move (for initial direction testing)\n            if (forced_first_dir >= 0 && steps == 0) {\n                bool found = false;\n                for (auto& c : cands) {\n                    if (c.dir == forced_first_dir) {\n                        cands = {c};\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break; // Can't go that way\n            }\n            \n            auto best = *max_element(cands.begin(), cands.end(),\n                [](const Cand& a, const Cand& b) { return a.score < b.score; });\n            \n            i = best.ni;\n            j = best.nj;\n            vis[tile[i][j]] = 1;\n            path.push_back(DC[best.dir]);\n            steps++;\n        }\n        return path;\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Phase 1: Try all 4 initial directions with strong heuristics\n        for (int d = 0; d < 4; ++d) {\n            string p = greedy_walk(1.0, 30.0, 10000.0, 0.5, false, d);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 2: Deterministic good heuristics\n        vector<tuple<double, double, double, double>> presets = {\n            {1.0, 20.0, 5000.0, 0.8},\n            {1.0, 40.0, 8000.0, 0.3},\n            {1.0, 10.0, 2000.0, 1.0},\n            {1.0, 0.0, 0.0, 0.0},      // Pure greedy value\n            {1.0, 100.0, 10000.0, 0.0}, // Extreme connectivity\n        };\n        \n        for (auto& [wv, wd, dp, wn] : presets) {\n            string p = greedy_walk(wv, wd, dp, wn, false, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 3: Stochastic search with refined parameters\n        for (int iter = 0; iter < 300; ++iter) {\n            double wv = 1.0;\n            double wd = rand_double() * 80.0 + 5.0;  // 5 to 85\n            double dp = rand_double() * 8000.0 + 500.0; // 500 to 8500\n            double wn = rand_double() * 1.0; // 0 to 1\n            \n            string p = greedy_walk(wv, wd, dp, wn, true, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        return best_path;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    while (true) {\n        int si, sj;\n        if (!(cin >> si >> sj)) break;\n        \n        vector<vector<int>> t(H, vector<int>(W));\n        vector<vector<int>> p(H, vector<int>(W));\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> p[i][j];\n        \n        Solver solver;\n        solver.si = si;\n        solver.sj = sj;\n        solver.tile = t;\n        solver.val = p;\n        \n        int max_id = 0;\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                max_id = max(max_id, t[i][j]);\n        solver.M = max_id + 1;\n        \n        cout << solver.solve() << \"\\n\";\n    }\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    constexpr int N = 30;\n    constexpr int Q = 1000;\n    constexpr double LR = 0.4;          // base learning rate\n    constexpr double SIGMA0 = 1800.0;   // prior std\u2011dev for Thompson sampling\n    constexpr double WMIN = 100.0;\n    constexpr double WMAX = 10000.0;\n    constexpr double SMOOTH_ALPHA = 0.03; // Laplacian smoothing strength\n    constexpr int EXPLORE_UNTIL = 850;   // switch to pure exploitation after this\n    \n    // estimates and counters\n    double H[N][N - 1];\n    double V[N - 1][N];\n    int    CntH[N][N - 1] = {};\n    int    CntV[N - 1][N] = {};\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            H[i][j] = 5000.0;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            V[i][j] = 5000.0;\n    \n    // temporaries for smoothing\n    double tmpH[N][N - 1];\n    double tmpV[N - 1][N];\n    \n    // randomness for Thompson sampling\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    std::normal_distribution<double> gauss(0.0, 1.0);\n    \n    // sampled weights for Dijkstra\n    double sH[N][N - 1];\n    double sV[N - 1][N];\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    for (int q = 0; q < Q; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n        \n        bool use_exploration = (q < EXPLORE_UNTIL);\n        \n        // ---------- 1. Thompson sampling (or mean) ----------\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                if (use_exploration) {\n                    double sigma = SIGMA0 / sqrt((double)CntH[i][j] + 1.0);\n                    double w = H[i][j] + gauss(rng) * sigma;\n                    if (w < WMIN) w = WMIN;\n                    if (w > WMAX) w = WMAX;\n                    sH[i][j] = w;\n                } else {\n                    sH[i][j] = H[i][j];\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (use_exploration) {\n                    double sigma = SIGMA0 / sqrt((double)CntV[i][j] + 1.0);\n                    double w = V[i][j] + gauss(rng) * sigma;\n                    if (w < WMIN) w = WMIN;\n                    if (w > WMAX) w = WMAX;\n                    sV[i][j] = w;\n                } else {\n                    sV[i][j] = V[i][j];\n                }\n            }\n        }\n        \n        // ---------- 2. Dijkstra ----------\n        double dist[N][N];\n        int par_i[N][N];\n        int par_j[N][N];\n        char par_dir[N][N];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = 1e100;\n        \n        using State = tuple<double, int, int>;\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[si][sj] = 0.0;\n        pq.emplace(0.0, si, sj);\n        \n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j] + 1e-9) continue;\n            if (i == ti && j == tj) break;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                double w;\n                if (dir == 0) w = sV[i - 1][j];\n                else if (dir == 1) w = sV[i][j];\n                else if (dir == 2) w = sH[i][j - 1];\n                else               w = sH[i][j];\n                if (dist[ni][nj] > d + w) {\n                    dist[ni][nj] = d + w;\n                    par_i[ni][nj] = i;\n                    par_j[ni][nj] = j;\n                    par_dir[ni][nj] = dc[dir];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n        \n        // reconstruct path\n        string path;\n        int ci = ti, cj = tj;\n        while (ci != si || cj != sj) {\n            char c = par_dir[ci][cj];\n            path.push_back(c);\n            int pi = par_i[ci][cj];\n            int pj = par_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << '\\n';\n        cout.flush();\n        \n        // ---------- 3. Observation & Weighted SGD ----------\n        long long obs_in;\n        cin >> obs_in;\n        double obs = static_cast<double>(obs_in);\n        \n        // compute predicted length and collect edges\n        double lenEst = 0.0;\n        ci = si; cj = sj;\n        struct Edge { char type; int i, j; };\n        vector<Edge> edges;\n        edges.reserve(path.size());\n        for (char c : path) {\n            if (c == 'U') {\n                lenEst += V[ci - 1][cj];\n                edges.push_back({'V', ci - 1, cj});\n                --ci;\n            } else if (c == 'D') {\n                lenEst += V[ci][cj];\n                edges.push_back({'V', ci, cj});\n                ++ci;\n            } else if (c == 'L') {\n                lenEst += H[ci][cj - 1];\n                edges.push_back({'H', ci, cj - 1});\n                --cj;\n            } else {\n                lenEst += H[ci][cj];\n                edges.push_back({'H', ci, cj});\n                ++cj;\n            }\n        }\n        \n        double err = obs - lenEst;\n        // compute uncertainty weights u_e = 1/sqrt(c_e+1)\n        double sumW = 0.0;\n        vector<double> weights;\n        weights.reserve(edges.size());\n        for (auto &e : edges) {\n            int cnt = (e.type == 'H') ? CntH[e.i][e.j] : CntV[e.i][e.j];\n            double u = 1.0 / sqrt((double)cnt + 1.0);\n            weights.push_back(u);\n            sumW += u;\n        }\n        \n        // apply weighted update\n        for (size_t idx = 0; idx < edges.size(); ++idx) {\n            const auto &e = edges[idx];\n            double delta = LR * err * (weights[idx] / sumW);\n            if (e.type == 'H') {\n                H[e.i][e.j] += delta;\n                if (H[e.i][e.j] < WMIN) H[e.i][e.j] = WMIN;\n                if (H[e.i][e.j] > WMAX) H[e.i][e.j] = WMAX;\n                CntH[e.i][e.j]++;\n            } else {\n                V[e.i][e.j] += delta;\n                if (V[e.i][e.j] < WMIN) V[e.i][e.j] = WMIN;\n                if (V[e.i][e.j] > WMAX) V[e.i][e.j] = WMAX;\n                CntV[e.i][e.j]++;\n            }\n        }\n        \n        // ---------- 4. Laplacian smoothing (Jacobi iteration) ----------\n        if (use_exploration) {\n            // Horizontal edges: smooth along each row\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N - 1; ++j) {\n                    double left  = (j > 0)     ? H[i][j - 1] : H[i][j];\n                    double right = (j < N - 2) ? H[i][j + 1] : H[i][j];\n                    tmpH[i][j] = H[i][j] + SMOOTH_ALPHA * (left + right - 2.0 * H[i][j]);\n                    // clamp just in case\n                    if (tmpH[i][j] < WMIN) tmpH[i][j] = WMIN;\n                    if (tmpH[i][j] > WMAX) tmpH[i][j] = WMAX;\n                }\n            }\n            // Vertical edges: smooth along each column\n            for (int i = 0; i < N - 1; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    double up   = (i > 0)     ? V[i - 1][j] : V[i][j];\n                    double down = (i < N - 2) ? V[i + 1][j] : V[i][j];\n                    tmpV[i][j] = V[i][j] + SMOOTH_ALPHA * (up + down - 2.0 * V[i][j]);\n                    if (tmpV[i][j] < WMIN) tmpV[i][j] = WMIN;\n                    if (tmpV[i][j] > WMAX) tmpV[i][j] = WMAX;\n                }\n            }\n            // copy back\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N - 1; ++j)\n                    H[i][j] = tmpH[i][j];\n            for (int i = 0; i < N - 1; ++i)\n                for (int j = 0; j < N; ++j)\n                    V[i][j] = tmpV[i][j];\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int str_id;\n    uint8_t len;\n};\n\nstruct Ref {\n    int pid;\n    uint8_t req;          // 0 \u2026 7  (A \u2026 H)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;                 // Fixed by problem statement\n    int N_input, M;\n    if (!(cin >> N_input >> M)) return 0;\n    // N_input is guaranteed to be 20, but we use the const N for safety\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) cin >> strs[i];\n\n    auto ch2i = [](char c)->int{ return c - 'A'; };   // 'A'..'H' -> 0..7\n\n    const int C = N * N;                 // number of cells\n    vector<vector<Ref>> cell_refs(C);    // reverse index\n    vector<Placement> plc;               // all placements\n    plc.reserve(M * 2 * N * N);\n\n    /* -----------------------------------------------------------\n       generate all placements\n       ----------------------------------------------------------- */\n    for (int s = 0; s < M; ++s) {\n        const string &st = strs[s];\n        int L = (int)st.size();\n        // horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    int cid = r * N + cc;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n        // vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int rr = (r + p) % N;\n                    int cid = rr * N + c;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n    }\n\n    const int P = (int)plc.size();\n    vector<uint8_t> counter(P, 0);\n    vector<int> sat_cnt(M, 0);\n    int total_sat = 0;\n\n    /* -----------------------------------------------------------\n       random initial grid (only letters, 0..7)\n       ----------------------------------------------------------- */\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    vector<uint8_t> grid(C);\n    for (int i = 0; i < C; ++i) grid[i] = (uint8_t)(rng() & 7);\n\n    /* initial counting */\n    for (int cid = 0; cid < C; ++cid) {\n        uint8_t v = grid[cid];\n        for (const auto &rf : cell_refs[cid]) {\n            if (rf.req == v) ++counter[rf.pid];\n        }\n    }\n    for (int pid = 0; pid < P; ++pid) {\n        if (counter[pid] == plc[pid].len) {\n            ++sat_cnt[plc[pid].str_id];\n        }\n    }\n    for (int s = 0; s < M; ++s) if (sat_cnt[s] > 0) ++total_sat;\n\n    /* -----------------------------------------------------------\n       helper: apply change of one cell (old_val -> new_val)\n       updates counter[], sat_cnt[] and total_sat\n       ----------------------------------------------------------- */\n    auto apply_change = [&](int cid, uint8_t old_val, uint8_t new_val) {\n        if (old_val == new_val) return;\n        for (const auto &rf : cell_refs[cid]) {\n            bool old_match = (old_val == rf.req);\n            bool new_match = (new_val == rf.req);\n            if (old_match == new_match) continue;   // nothing changes\n\n            uint8_t &cnt = counter[rf.pid];\n            uint8_t len  = plc[rf.pid].len;\n            if (old_match) {                 // we lose one matching cell\n                --cnt;\n                if (cnt == len - 1) {        // was satisfied, now not\n                    int sid = plc[rf.pid].str_id;\n                    if (--sat_cnt[sid] == 0) --total_sat;\n                }\n            } else {                         // we gain one matching cell\n                ++cnt;\n                if (cnt == len) {            // becomes satisfied\n                    int sid = plc[rf.pid].str_id;\n                    if (sat_cnt[sid]++ == 0) ++total_sat;\n                }\n            }\n        }\n    };\n\n    /* -----------------------------------------------------------\n       Simulated Annealing\n       ----------------------------------------------------------- */\n    const double TIME_LIMIT = 2.5;            // seconds\n    auto start = chrono::steady_clock::now();\n    double temp = 0.8;                        // initial temperature\n    int iter = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        ++iter;\n        if ((iter & 127) == 0) temp *= 0.999; // slow cooling\n\n        int cid = (int)(rng() % C);\n        uint8_t oldv = grid[cid];\n        uint8_t newv = (uint8_t)(rng() & 7);\n        if (oldv == newv) continue;\n\n        int before = total_sat;\n        apply_change(cid, oldv, newv);\n        int after = total_sat;\n        int delta = after - before;\n\n        if (delta < 0) {\n            double accept_prob = exp(delta / temp);\n            if (uniform_real_distribution<double>(0.0, 1.0)(rng) > accept_prob) {\n                // reject: revert\n                apply_change(cid, newv, oldv);\n                // grid[cid] stays oldv\n                continue;\n            }\n        }\n        grid[cid] = newv;   // accept\n    }\n\n    /* -----------------------------------------------------------\n       Phase 2: try to turn cells into '.' (value 8) without breaking\n       ----------------------------------------------------------- */\n    if (total_sat == M) {\n        vector<int> order(C);\n        iota(order.begin(), order.end(), 0);\n        for (int rep = 0; rep < 3; ++rep) {\n            shuffle(order.begin(), order.end(), rng);\n            for (int cid : order) {\n                if (grid[cid] == 8) continue;          // already dot\n                uint8_t oldv = grid[cid];\n                apply_change(cid, oldv, 8);\n                if (total_sat == M) {\n                    grid[cid] = 8;                      // keep dot\n                } else {\n                    apply_change(cid, 8, oldv);         // revert\n                }\n            }\n        }\n    }\n\n    /* -----------------------------------------------------------\n       Output\n       ----------------------------------------------------------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        line.reserve(N);\n        for (int c = 0; c < N; ++c) {\n            int v = grid[r * N + c];\n            if (v == 8) line.push_back('.');\n            else        line.push_back(char('A' + v));\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastBitset {\n    static const int MAXR = 5000;\n    static const int WORDS = (MAXR + 63) / 64;\n    uint64_t w[WORDS];\n    FastBitset() { memset(w, 0, sizeof(w)); }\n    void set(int i) { w[i>>6] |= 1ULL << (i&63); }\n    bool test(int i) const { return (w[i>>6] >> (i&63)) & 1ULL; }\n    void clear() { memset(w, 0, sizeof(w)); }\n    int count() const {\n        int s = 0;\n        for (int i = 0; i < WORDS; i++) s += __builtin_popcountll(w[i]);\n        return s;\n    }\n    FastBitset operator|(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] | o.w[i];\n        return r;\n    }\n    FastBitset operator&(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] & o.w[i];\n        return r;\n    }\n    FastBitset operator~() const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = ~w[i];\n        return r;\n    }\n    FastBitset& operator|=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] |= o.w[i];\n        return *this;\n    }\n    FastBitset& operator&=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] &= o.w[i];\n        return *this;\n    }\n    bool any() const {\n        for (int i = 0; i < WORDS; i++) if (w[i]) return true;\n        return false;\n    }\n    bool is_subset_of(const FastBitset& o) const {\n        for (int i = 0; i < WORDS; i++) {\n            if ((w[i] & ~o.w[i]) != 0) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = cells.size();\n                cells.emplace_back(i, j);\n            }\n        }\n    }\n    int R = cells.size();\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    // Horizontal and vertical segment coverage\n    vector<vector<int>> h_id(N, vector<int>(N, -1));\n    vector<vector<int>> v_id(N, vector<int>(N, -1));\n    vector<FastBitset> h_cover, v_cover;\n    \n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != '#') {\n                int l = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int r = j - 1;\n                FastBitset bs;\n                int sid = h_cover.size();\n                for (int k = l; k <= r; k++) {\n                    h_id[i][k] = sid;\n                    bs.set(id[i][k]);\n                }\n                h_cover.push_back(bs);\n            } else {\n                j++;\n            }\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != '#') {\n                int t = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int b = i - 1;\n                FastBitset bs;\n                int sid = v_cover.size();\n                for (int k = t; k <= b; k++) {\n                    v_id[k][j] = sid;\n                    bs.set(id[k][j]);\n                }\n                v_cover.push_back(bs);\n            } else {\n                i++;\n            }\n        }\n    }\n    \n    vector<FastBitset> cell_cover(R);\n    for (int idx = 0; idx < R; idx++) {\n        auto [i, j] = cells[idx];\n        cell_cover[idx] = h_cover[h_id[i][j]] | v_cover[v_id[i][j]];\n    }\n    \n    int start_idx = id[si][sj];\n    \n    // Greedy set cover\n    FastBitset uncovered;\n    for (int i = 0; i < R; i++) uncovered.set(i);\n    uncovered &= ~cell_cover[start_idx];\n    \n    vector<int> selected;\n    \n    while (uncovered.any()) {\n        int best = -1;\n        int best_cnt = -1;\n        \n        for (int c = 0; c < R; c++) {\n            bool has_overlap = false;\n            for (int w = 0; w < FastBitset::WORDS; w++) {\n                if (cell_cover[c].w[w] & uncovered.w[w]) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            if (!has_overlap) continue;\n            \n            FastBitset inter;\n            for (int w = 0; w < FastBitset::WORDS; w++) \n                inter.w[w] = cell_cover[c].w[w] & uncovered.w[w];\n            int cnt = inter.count();\n            if (cnt > best_cnt) {\n                best_cnt = cnt;\n                best = c;\n            }\n        }\n        \n        if (best == -1) break;\n        selected.push_back(best);\n        for (int w = 0; w < FastBitset::WORDS; w++) \n            uncovered.w[w] &= ~cell_cover[best].w[w];\n    }\n    \n    // Remove redundant points: iteratively remove if coverage is subset of others\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        FastBitset union_cover = cell_cover[start_idx];\n        for (int idx : selected) union_cover |= cell_cover[idx];\n        \n        for (int i = 0; i < (int)selected.size(); i++) {\n            FastBitset without;\n            without = cell_cover[start_idx];\n            for (int j = 0; j < (int)selected.size(); j++) {\n                if (i != j) without |= cell_cover[selected[j]];\n            }\n            // Check if selected[i] is redundant\n            if (cell_cover[selected[i]].is_subset_of(without)) {\n                selected.erase(selected.begin() + i);\n                changed = true;\n                break;\n            }\n        }\n    }\n    \n    // Build point list\n    vector<int> points;\n    points.reserve(selected.size() + 1);\n    points.push_back(start_idx);\n    for (int idx : selected) points.push_back(idx);\n    int K = points.size();\n    \n    if (K == 1) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    vector<int> node_to_point(R, -1);\n    for (int i = 0; i < K; i++) node_to_point[points[i]] = i;\n    \n    const int INF = 1e9;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // Distance matrix (asymmetric)\n    vector<vector<int>> dmat(K, vector<int>(K, INF));\n    \n    for (int pi = 0; pi < K; pi++) {\n        int src = points[pi];\n        vector<int> dist(R, INF);\n        dist[src] = 0;\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.emplace(0, src);\n        int settled = 0;\n        \n        while (!pq.empty() && settled < K) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (node_to_point[u] != -1) settled++;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        for (int pj = 0; pj < K; pj++) {\n            dmat[pi][pj] = dist[points[pj]];\n        }\n    }\n    \n    // TSP: Farthest Insertion (good for asymmetric)\n    vector<int> best_tour;\n    int best_cost = INF;\n    \n    // Try multiple strategies\n    for (int attempt = 0; attempt < 3; attempt++) {\n        vector<int> tour;\n        vector<bool> used(K, false);\n        tour.push_back(0);\n        used[0] = true;\n        \n        while ((int)tour.size() < K) {\n            // Find farthest node from tour\n            int farthest = -1;\n            int max_dist = -1;\n            for (int i = 0; i < K; i++) if (!used[i]) {\n                int min_dist = INF;\n                for (int j : tour) {\n                    min_dist = min(min_dist, dmat[j][i]);\n                }\n                if (min_dist > max_dist) {\n                    max_dist = min_dist;\n                    farthest = i;\n                }\n            }\n            \n            if (farthest == -1) break;\n            \n            // Find best insertion position\n            int best_pos = -1;\n            int best_increase = INF;\n            for (int pos = 0; pos < (int)tour.size(); pos++) {\n                int a = tour[pos];\n                int b = tour[(pos + 1) % tour.size()];\n                // Insert between a and b: a -> farthest -> b\n                int increase = dmat[a][farthest] + dmat[farthest][b] - dmat[a][b];\n                if (increase < best_increase) {\n                    best_increase = increase;\n                    best_pos = pos;\n                }\n            }\n            \n            tour.insert(tour.begin() + best_pos + 1, farthest);\n            used[farthest] = true;\n        }\n        \n        // Calculate cost\n        int cost = 0;\n        for (int i = 0; i < K; i++) {\n            cost += dmat[tour[i]][tour[(i+1)%K]];\n        }\n        \n        // 2-opt improvement (accept if better despite asymmetry)\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < K; i++) {\n                for (int j = i + 2; j < K; j++) {\n                    int a = tour[i];\n                    int b = tour[(i+1)%K];\n                    int c = tour[j];\n                    int d = tour[(j+1)%K];\n                    \n                    int cur = dmat[a][b] + dmat[c][d];\n                    int rev = dmat[a][c] + dmat[b][d];\n                    \n                    if (rev < cur) {\n                        reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                        improved = true;\n                        cost += rev - cur;\n                    }\n                }\n            }\n        }\n        \n        if (cost < best_cost) {\n            best_cost = cost;\n            best_tour = tour;\n        }\n    }\n    \n    // Build route string\n    string route;\n    route.reserve(N * N * 4);\n    \n    for (int ii = 0; ii < K; ii++) {\n        int from_idx = points[best_tour[ii]];\n        int to_idx = points[best_tour[(ii+1)%K]];\n        if (from_idx == to_idx) continue;\n        \n        vector<int> dist(R, INF);\n        vector<int> prev(R, -1);\n        vector<int> prev_dir(R, -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[from_idx] = 0;\n        pq.emplace(0, from_idx);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == to_idx) break;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_dir[v] = dir;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int cur_node = to_idx;\n        while (cur_node != from_idx) {\n            dirs.push_back(prev_dir[cur_node]);\n            cur_node = prev[cur_node];\n        }\n        reverse(dirs.begin(), dirs.end());\n        for (int d : dirs) {\n            if (d == 0) route += 'U';\n            else if (d == 1) route += 'D';\n            else if (d == 2) route += 'L';\n            else route += 'R';\n        }\n    }\n    \n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if(!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> sum_d(N, 0);\n    vector<int> max_d(N, 0);\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<K; j++) {\n            cin >> d[i][j];\n            sum_d[i] += d[i][j];\n            max_d[i] = max(max_d[i], d[i][j]);\n        }\n    }\n    \n    vector<vector<int>> adj(N);\n    vector<vector<int>> radj(N);\n    vector<int> indeg(N, 0);\n    for(int i=0; i<R; i++) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n        indeg[v]++;\n    }\n    \n    // State: estimate and bounds for skills\n    vector<vector<double>> est_s(M, vector<double>(K, 30.0));\n    vector<vector<double>> lb(M, vector<double>(K, 0.0));\n    vector<vector<int>> obs_count(M, vector<int>(K, 0));\n    vector<int> total_obs(M, 0);\n    \n    vector<int> indeg_cur = indeg;\n    vector<int> task_state(N, 0); // 0:not ready, 1:ready, 2:running, 3:done\n    vector<int> member_task(M, -1);\n    vector<int> task_start_day(N, -1);\n    vector<int> task_member(N, -1);\n    \n    int day = 0;\n    const int MAX_DAY = 2000;\n    \n    while(day < MAX_DAY) {\n        ++day;\n        \n        // Update available tasks\n        vector<int> available;\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 0 && indeg_cur[i] == 0) {\n                task_state[i] = 1;\n            }\n            if(task_state[i] == 1) available.push_back(i);\n        }\n        \n        // Find free members\n        vector<int> free_members;\n        for(int j=0; j<M; j++) if(member_task[j] == -1) free_members.push_back(j);\n        \n        if(!available.empty() && !free_members.empty()) {\n            // Calculate estimated times and critical path\n            vector<double> min_time(N, 1.0), second_min_time(N, 1e18);\n            vector<vector<double>> est_time(M, vector<double>(N, 1.0));\n            vector<vector<double>> uncertainty(M, vector<double>(N, 0.0));\n            \n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                double best = 1e18, second = 1e18;\n                for(int j=0; j<M; j++) {\n                    double w = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > est_s[j][k]) w += d[i][k] - est_s[j][k];\n                    double t = (w <= 0) ? 1.0 : max(1.0, w);\n                    est_time[j][i] = t;\n                    \n                    // Uncertainty based on observation count\n                    double unc = 10.0 / (1.0 + total_obs[j]);\n                    uncertainty[j][i] = unc;\n                    \n                    if(t < best) { second = best; best = t; }\n                    else if(t < second) second = t;\n                }\n                min_time[i] = best;\n                second_min_time[i] = (second < 1e17) ? second : best;\n            }\n            \n            // DP for critical path\n            vector<double> dp(N, -1.0);\n            function<double(int)> solve_dp = [&](int u) -> double {\n                if(task_state[u] == 3) return 0.0;\n                if(dp[u] >= 0) return dp[u];\n                double max_next = 0.0;\n                for(int v : adj[u]) if(task_state[v] != 3) {\n                    max_next = max(max_next, solve_dp(v));\n                }\n                dp[u] = min_time[u] + max_next;\n                return dp[u];\n            };\n            for(int i : available) solve_dp(i);\n            \n            // Calculate priority: critical path + bottleneck penalty + parallelism bonus\n            vector<double> priority(N, 0.0);\n            for(int i : available) {\n                double bottleneck = second_min_time[i] - min_time[i];\n                // Higher priority for tasks with high bottleneck (few good assignees)\n                // and tasks on critical path\n                priority[i] = dp[i] + 0.5 * bottleneck;\n            }\n            \n            sort(available.begin(), available.end(), [&](int a, int b) {\n                return priority[a] > priority[b];\n            });\n            \n            // Greedy assignment with exploration bonus\n            vector<bool> used(M, false);\n            vector<pair<int,int>> assignments;\n            \n            for(int task_id : available) {\n                if(assignments.size() >= free_members.size()) break;\n                \n                int best_j = -1;\n                double best_score = 1e18;\n                \n                for(int j : free_members) {\n                    if(used[j]) continue;\n                    \n                    double base_time = est_time[j][task_id];\n                    // Exploration bonus: prefer members with fewer total observations\n                    // This ensures we learn skills quickly across all members\n                    double explore_bonus = 0.0;\n                    if(total_obs[j] < 5) {\n                        explore_bonus = (5 - total_obs[j]) * 0.5; // Small bonus for unexplored members\n                    }\n                    \n                    double score = base_time + explore_bonus;\n                    \n                    if(score < best_score) {\n                        best_score = score;\n                        best_j = j;\n                    }\n                }\n                \n                if(best_j != -1) {\n                    assignments.emplace_back(best_j, task_id);\n                    used[best_j] = true;\n                }\n            }\n            \n            cout << assignments.size();\n            for(auto& [j, i] : assignments) {\n                cout << \" \" << j+1 << \" \" << i+1;\n                member_task[j] = i;\n                task_state[i] = 2;\n                task_start_day[i] = day;\n                task_member[i] = j;\n            }\n            cout << endl;\n        } else {\n            cout << 0 << endl;\n        }\n        cout.flush();\n        \n        // Read completions\n        int n_comp;\n        cin >> n_comp;\n        if(n_comp == -1) break;\n        \n        vector<int> completed(n_comp);\n        for(int i=0; i<n_comp; i++) cin >> completed[i], completed[i]--;\n        \n        // Process completions and update skills\n        for(int j : completed) {\n            int task_id = member_task[j];\n            if(task_id == -1) continue;\n            \n            int duration = day - task_start_day[task_id] + 1;\n            double obs_w = max(0, duration - 1);\n            total_obs[j]++;\n            \n            // Calculate predicted deficiency\n            double pred_w = 0;\n            vector<int> active_dims;\n            vector<double> deficiencies;\n            for(int k=0; k<K; k++) {\n                if(d[task_id][k] > est_s[j][k]) {\n                    double def = d[task_id][k] - est_s[j][k];\n                    pred_w += def;\n                    active_dims.push_back(k);\n                    deficiencies.push_back(def);\n                }\n            }\n            \n            // Update skills based on observation\n            if(obs_w == 0) {\n                // Task completed optimally: skills are at least requirements\n                for(int k=0; k<K; k++) {\n                    est_s[j][k] = max(est_s[j][k], (double)d[task_id][k]);\n                    lb[j][k] = max(lb[j][k], (double)d[task_id][k]);\n                    obs_count[j][k]++;\n                }\n            } else if(active_dims.empty()) {\n                // We thought expert but wasn't: reduce all skills proportionally\n                double scale = obs_w / sum_d[task_id];\n                for(int k=0; k<K; k++) {\n                    double target = d[task_id][k] * (1.0 - scale);\n                    est_s[j][k] = max(0.0, min(est_s[j][k], target));\n                }\n            } else {\n                // Adjust active dimensions to match observed total deficiency\n                if(pred_w > 0) {\n                    double ratio = obs_w / pred_w;\n                    // More aggressive update when error is large\n                    double alpha = min(0.8, 0.3 + 0.5 * abs(ratio - 1.0));\n                    \n                    for(size_t idx=0; idx<active_dims.size(); idx++) {\n                        int k = active_dims[idx];\n                        double current_def = deficiencies[idx];\n                        double target_def = current_def * ratio;\n                        double new_def = current_def * (1-alpha) + target_def * alpha;\n                        est_s[j][k] = d[task_id][k] - new_def;\n                        est_s[j][k] = max(lb[j][k], est_s[j][k]);\n                        obs_count[j][k]++;\n                    }\n                }\n            }\n            \n            task_state[task_id] = 3;\n            member_task[j] = -1;\n            task_member[task_id] = -1;\n            for(int v : adj[task_id]) indeg_cur[v]--;\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double now() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 1000;\n    const int OFFICE = 0;\n    const int OFFICE_X = 400, OFFICE_Y = 400;\n    const int MAX_P = 2 * N + 1; // 0..2000\n    \n    vector<int> a(N), b(N), c(N), d(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> a[i] >> b[i] >> c[i] >> d[i];\n    }\n    \n    // Coordinate compression: 0 = office, 1..N = pickup, N+1..2N = delivery\n    vector<int> xs(MAX_P), ys(MAX_P);\n    xs[OFFICE] = OFFICE_X; ys[OFFICE] = OFFICE_Y;\n    for (int i = 0; i < N; ++i) {\n        xs[1 + i] = a[i]; ys[1 + i] = b[i];\n        xs[1 + N + i] = c[i]; ys[1 + N + i] = d[i];\n    }\n    \n    // Flat distance matrix: dist[i * MAX_P + j]\n    vector<int> dist(MAX_P * MAX_P);\n    auto D = [&](int i, int j) -> int& { return dist[i * MAX_P + j]; };\n    for (int i = 0; i < MAX_P; ++i) {\n        for (int j = 0; j < MAX_P; ++j) {\n            D(i, j) = abs(xs[i] - xs[j]) + abs(ys[i] - ys[j]);\n        }\n    }\n    \n    Timer timer;\n    \n    // ---------- Greedy Insertion ----------\n    vector<int> route;\n    route.reserve(105);\n    route.push_back(OFFICE);\n    route.push_back(OFFICE);\n    vector<int> selected; selected.reserve(50);\n    vector<bool> used(N, false);\n    \n    for (int iter = 0; iter < 50; ++iter) {\n        int m = (int)route.size();\n        int best_o = -1, best_i = -1, best_j = -1;\n        int best_delta = 1e9;\n        \n        for (int o = 0; o < N; ++o) if (!used[o]) {\n            int p = 1 + o;\n            int del = 1 + N + o;\n            for (int i = 0; i < m - 1; ++i) {\n                int ri = route[i];\n                int ri1 = route[i+1];\n                int dpi = -D(ri, ri1);\n                for (int j = i; j < m - 1; ++j) {\n                    int rj = route[j];\n                    int rj1 = route[j+1];\n                    int delta;\n                    if (i == j) {\n                        delta = dpi + D(ri, p) + D(p, del) + D(del, rj1);\n                    } else {\n                        int dpj = -D(rj, rj1);\n                        delta = dpi + dpj + D(ri, p) + D(p, ri1) + D(rj, del) + D(del, rj1);\n                    }\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_o = o;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        int p = 1 + best_o;\n        int del = 1 + N + best_o;\n        if (best_i == best_j) {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_i + 2, del);\n        } else {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_j + 2, del);\n        }\n        selected.push_back(best_o);\n        used[best_o] = true;\n    }\n    \n    // Prepare for SA: cur sequence and position array\n    vector<int> cur = route; // size 102\n    const int LEN = 102;\n    const int MIDDLE = 100; // indices 1..100 are movable\n    \n    array<int, MAX_P> pos;\n    for (int i = 0; i < LEN; ++i) pos[cur[i]] = i;\n    \n    auto calc_full = [&](const vector<int>& seq) {\n        int s = 0;\n        for (int i = 0; i + 1 < LEN; ++i) s += D(seq[i], seq[i+1]);\n        return s;\n    };\n    int cur_cost = calc_full(cur);\n    int best_cost = cur_cost;\n    vector<int> best_seq = cur;\n    \n    // Type: 0 = pickup, 1 = delivery\n    auto is_pickup = [&](int idx)->bool{ return idx >= 1 && idx <= N; };\n    auto is_delivery = [&](int idx)->bool{ return idx > N; };\n    \n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(1, 100); // movable range\n    \n    // Precompute exp table for fast annealing\n    const int EXP_TABLE_SIZE = 1000;\n    vector<double> exp_table(EXP_TABLE_SIZE);\n    for (int i = 0; i < EXP_TABLE_SIZE; ++i) {\n        double t = (double)i / 100.0; // delta / T\n        exp_table[i] = exp(-t);\n    }\n    \n    double T_start = 1000.0;\n    double T_end = 0.1;\n    double time_limit = 1.98 - timer.now(); // remaining time for SA\n    if (time_limit < 0.1) time_limit = 0.1;\n    double start_time = timer.now();\n    \n    long long iter = 0;\n    while (timer.now() - start_time < time_limit) {\n        double elapsed = timer.now() - start_time;\n        double progress = elapsed / time_limit;\n        double T = T_start * pow(T_end / T_start, progress);\n        \n        int type = rng() & 1; // 0 = swap, 1 = 2-opt\n        bool accept = false;\n        int delta = 0;\n        \n        if (type == 0) {\n            // Swap\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l == r) continue;\n            if (l > r) swap(l, r);\n            \n            int u = cur[l];\n            int v = cur[r];\n            \n            // Validity check: O(1)\n            bool ok = true;\n            if (is_pickup(u)) {\n                if (pos[u + N] <= r) ok = false; // delivery must be after new pos r\n            } else {\n                if (pos[u - N] >= r) ok = false; // pickup must be before new pos r\n            }\n            if (ok && is_pickup(v)) {\n                if (pos[v + N] <= l) ok = false;\n            } else if (ok) {\n                if (pos[v - N] >= l) ok = false;\n            }\n            if (!ok) continue;\n            \n            // Delta calculation\n            int ul = cur[l-1];\n            int ur = cur[l+1];\n            int vl = cur[r-1];\n            int vr = cur[r+1];\n            \n            if (r == l + 1) {\n                // Adjacent: ... ul, u, v, vr ...\n                delta = -D(ul, u) - D(u, v) - D(v, vr)\n                        + D(ul, v) + D(v, u) + D(u, vr);\n            } else {\n                delta = -D(ul, u) - D(u, ur) - D(vl, v) - D(v, vr)\n                        + D(ul, v) + D(v, ur) + D(vl, u) + D(u, vr);\n            }\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    if (uniform_real_distribution<double>(0,1)(rng) >= 0) continue; // reject with high probability\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                swap(cur[l], cur[r]);\n                pos[u] = r;\n                pos[v] = l;\n            }\n        } else {\n            // 2-opt reverse [l, r]\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l >= r) continue;\n            \n            // Validity: no order has both ends inside [l, r]\n            bool ok = true;\n            for (int o : selected) {\n                int p = 1 + o;\n                int d = 1 + N + o;\n                if (l <= pos[p] && pos[p] <= r && l <= pos[d] && pos[d] <= r) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            \n            int before = cur[l-1];\n            int after = cur[r+1];\n            int left = cur[l];\n            int right = cur[r];\n            delta = -D(before, left) - D(right, after) + D(before, right) + D(left, after);\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    continue;\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n                for (int i = l; i <= r; ++i) pos[cur[i]] = i;\n            }\n        }\n        \n        if (accept) {\n            cur_cost += delta;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_seq = cur;\n            }\n        }\n        ++iter;\n    }\n    \n    // ---------- Output ----------\n    cout << 50;\n    for (int o : selected) cout << ' ' << (o + 1);\n    cout << '\\n';\n    \n    cout << best_seq.size();\n    for (int idx : best_seq) {\n        cout << ' ' << xs[idx] << ' ' << ys[idx];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        r.assign(n, 0);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        return p[x] == x ? x : p[x] = find(p[x]);\n    }\n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n    void unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> xs[i] >> ys[i];\n    }\n    \n    vector<int> u(M), v(M);\n    vector<long long> d(M);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        long long dx = (long long)xs[u[i]] - xs[v[i]];\n        long long dy = (long long)ys[u[i]] - ys[v[i]];\n        long long dist_sq = dx * dx + dy * dy;\n        long long dist = llround(sqrt((double)dist_sq));\n        d[i] = dist;\n    }\n    \n    // Precompute which edges are bridges in the suffix graph\n    vector<char> is_bridge(M, 0);\n    DSU dsu_back(N);\n    for (int i = M - 1; i >= 0; --i) {\n        if (dsu_back.same(u[i], v[i])) {\n            is_bridge[i] = 0;\n        } else {\n            is_bridge[i] = 1;\n            dsu_back.unite(u[i], v[i]);\n        }\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;\n        cin >> l;\n        \n        if (dsu.same(u[i], v[i])) {\n            cout << 0 << '\\n';\n        } else {\n            int need = components - 1;\n            int remaining = M - i;\n            bool take = false;\n            \n            // Must take if it's a bridge in suffix\n            if (is_bridge[i]) {\n                take = true;\n            } \n            // Must take if we can't afford to skip\n            else if (need >= remaining) {\n                take = true;\n            } \n            else {\n                double ratio = (double)need / (double)remaining;\n                // Base linear threshold: 1.0 + 2.0 * ratio (ranges 1.4 to 3.0)\n                double base_threshold = 1.0 + 2.0 * ratio;\n                \n                // Bonus for small edges: small d_i means less absolute risk\n                // For d_i <= 50, add up to +0.5 bonus\n                double bonus = min(0.5, 25.0 / (double)d[i]);\n                \n                double threshold = min(3.0, base_threshold + bonus);\n                \n                if ((double)l <= threshold * (double)d[i]) {\n                    take = true;\n                } else {\n                    take = false;\n                }\n            }\n            \n            if (take) {\n                cout << 1 << '\\n';\n                dsu.unite(u[i], v[i]);\n                components--;\n            } else {\n                cout << 0 << '\\n';\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool blocked[32][32];\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char wall_cmd[4] = {'u', 'd', 'l', 'r'};\nconst char move_cmd[4] = {'U', 'D', 'L', 'R'};\n\nbool is_passable(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30 && !blocked[x][y];\n}\n\nbool can_place_wall(int x, int y) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) return false;\n    if (blocked[x][y]) return false;\n    \n    for (auto& p : pets) {\n        if (p.x == x && p.y == y) return false;\n    }\n    for (auto& h : humans) {\n        if (h.x == x && h.y == y) return false;\n    }\n    \n    for (auto& p : pets) {\n        for (int d = 0; d < 4; d++) {\n            if (p.x + dx[d] == x && p.y + dy[d] == y) return false;\n        }\n    }\n    return true;\n}\n\nint bfs_area(int sx, int sy) {\n    if (!is_passable(sx, sy)) return 0;\n    bool visited[32][32] = {};\n    queue<pair<int,int>> q;\n    q.push({sx, sy});\n    visited[sx][sy] = true;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (is_passable(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return cnt;\n}\n\nint bfs_next_move(int sx, int sy, int tx, int ty, const vector<pair<int,int>>& obstacles) {\n    if (sx == tx && sy == ty) return -1;\n    \n    queue<pair<int,int>> q;\n    int dist[32][32];\n    memset(dist, -1, sizeof(dist));\n    \n    q.push({sx, sy});\n    dist[sx][sy] = 0;\n    int first_move[32][32];\n    memset(first_move, -1, sizeof(first_move));\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (!is_passable(nx, ny)) continue;\n            if (dist[nx][ny] != -1) continue;\n            \n            bool occupied = false;\n            for (auto& obs : obstacles) {\n                if (obs.first == nx && obs.second == ny) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (occupied) continue;\n            \n            dist[nx][ny] = dist[x][y] + 1;\n            first_move[nx][ny] = (dist[x][y] == 0) ? d : first_move[x][y];\n            \n            if (nx == tx && ny == ty) {\n                return first_move[nx][ny];\n            }\n            q.push({nx, ny});\n        }\n    }\n    return -1;\n}\n\nint nearest_pet_dist(int hx, int hy) {\n    int dist = 1000;\n    for (auto& p : pets) {\n        dist = min(dist, abs(p.x - hx) + abs(p.y - hy));\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    memset(blocked, false, sizeof(blocked));\n    \n    // Calculate initial fortress bounds\n    int min_x = 30, max_x = 1, min_y = 30, max_y = 1;\n    for (auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n    \n    int expand = 2;\n    int f_min_x = max(2, min_x - expand);\n    int f_max_x = min(29, max_x + expand);\n    int f_min_y = max(2, min_y - expand);\n    int f_max_y = min(29, max_y + expand);\n    \n    // Check if pets are initially inside\n    bool individual_mode = false;\n    for (auto& p : pets) {\n        if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n            individual_mode = true;\n            break;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> human_targets(M);\n    \n    if (individual_mode) {\n        // Each human builds their own 3x3 cell\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx + dx[d];\n                int wy = hy + dy[d];\n                if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                    human_targets[i].push_back({wx, wy});\n                }\n            }\n        }\n    } else {\n        // Shared fortress - assign perimeter sections\n        vector<pair<int,int>> all_targets;\n        for (int y = f_min_y; y <= f_max_y; y++) {\n            all_targets.push_back({f_min_x, y});\n            all_targets.push_back({f_max_x, y});\n        }\n        for (int x = f_min_x + 1; x <= f_max_x - 1; x++) {\n            all_targets.push_back({x, f_min_y});\n            all_targets.push_back({x, f_max_y});\n        }\n        \n        // Sort by angle from center to distribute evenly\n        double cx = (min_x + max_x) / 2.0;\n        double cy = (min_y + max_y) / 2.0;\n        sort(all_targets.begin(), all_targets.end(), [&](auto& a, auto& b) {\n            double ang_a = atan2(a.first - cx, a.second - cy);\n            double ang_b = atan2(b.first - cx, b.second - cy);\n            return ang_a < ang_b;\n        });\n        \n        // Round-robin assignment\n        for (int i = 0; i < (int)all_targets.size(); i++) {\n            human_targets[i % M].push_back(all_targets[i]);\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        // Check for invasion (pets inside fortress)\n        if (!individual_mode && turn > 0) {\n            for (auto& p : pets) {\n                if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n                    // Pet invaded! Switch to emergency individual mode\n                    individual_mode = true;\n                    human_targets.assign(M, {});\n                    for (int i = 0; i < M; i++) {\n                        int hx = humans[i].x, hy = humans[i].y;\n                        for (int d = 0; d < 4; d++) {\n                            int wx = hx + dx[d], wy = hy + dy[d];\n                            if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                                human_targets[i].push_back({wx, wy});\n                            }\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n        \n        string actions(M, '.');\n        vector<pair<int,int>> next_pos(M);\n        vector<bool> will_build(M, false);\n        \n        // Process humans in order of threat (most threatened first)\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return nearest_pet_dist(humans[a].x, humans[a].y) < nearest_pet_dist(humans[b].x, humans[b].y);\n        });\n        \n        // Track occupied positions for collision avoidance\n        vector<pair<int,int>> occupied;\n        for (auto& h : humans) occupied.push_back({h.x, h.y});\n        \n        for (int idx : order) {\n            int hx = humans[idx].x, hy = humans[idx].y;\n            bool acted = false;\n            \n            // Remove completed targets\n            human_targets[idx].erase(\n                remove_if(human_targets[idx].begin(), human_targets[idx].end(),\n                    [&](auto& t) { return blocked[t.first][t.second]; }),\n                human_targets[idx].end()\n            );\n            \n            // Try to build adjacent wall\n            for (auto& target : human_targets[idx]) {\n                int tx = target.first, ty = target.second;\n                if (abs(tx - hx) + abs(ty - hy) == 1) {\n                    if (can_place_wall(tx, ty)) {\n                        // Safety check: ensure building this wall doesn't trap us in tiny space\n                        blocked[tx][ty] = true;\n                        int area = bfs_area(hx, hy);\n                        blocked[tx][ty] = false;\n                        \n                        if (area >= 4) { // Ensure at least 4 cells accessible\n                            int d = (tx == hx - 1) ? 0 : (tx == hx + 1) ? 1 : (ty == hy - 1) ? 2 : 3;\n                            actions[idx] = wall_cmd[d];\n                            will_build[idx] = true;\n                            next_pos[idx] = {hx, hy};\n                            acted = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (acted) continue;\n            \n            // Move toward nearest target\n            if (!human_targets[idx].empty()) {\n                // Find nearest reachable target\n                int best_target = -1;\n                int best_dist = 1000;\n                \n                for (int i = 0; i < (int)human_targets[idx].size(); i++) {\n                    int tx = human_targets[idx][i].first;\n                    int ty = human_targets[idx][i].second;\n                    int d = abs(tx - hx) + abs(ty - hy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_target = i;\n                    }\n                }\n                \n                if (best_target != -1) {\n                    int tx = human_targets[idx][best_target].first;\n                    int ty = human_targets[idx][best_target].second;\n                    int d = bfs_next_move(hx, hy, tx, ty, occupied);\n                    \n                    if (d != -1) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        actions[idx] = move_cmd[d];\n                        next_pos[idx] = {nx, ny};\n                        // Update occupied for subsequent humans\n                        for (auto& o : occupied) {\n                            if (o.first == hx && o.second == hy) {\n                                o = {nx, ny};\n                                break;\n                            }\n                        }\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                // Defensive: move away from pets if too close\n                int min_dist = nearest_pet_dist(hx, hy);\n                if (min_dist <= 2) {\n                    int best_d = -1;\n                    int max_new_dist = min_dist;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (!is_passable(nx, ny)) continue;\n                        \n                        bool collides = false;\n                        for (auto& o : occupied) {\n                            if (o.first == nx && o.second == ny && !(o.first == hx && o.second == hy)) {\n                                collides = true;\n                                break;\n                            }\n                        }\n                        if (collides) continue;\n                        \n                        int new_dist = 1000;\n                        for (auto& p : pets) {\n                            new_dist = min(new_dist, abs(p.x - nx) + abs(p.y - ny));\n                        }\n                        if (new_dist > max_new_dist) {\n                            max_new_dist = new_dist;\n                            best_d = d;\n                        }\n                    }\n                    if (best_d != -1) {\n                        actions[idx] = move_cmd[best_d];\n                        next_pos[idx] = {hx + dx[best_d], hy + dy[best_d]};\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                actions[idx] = '.';\n                next_pos[idx] = {hx, hy};\n            }\n        }\n        \n        // Final conflict resolution for moves\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    // Later human stays\n                    actions[j] = '.';\n                    next_pos[j] = {humans[j].x, humans[j].y};\n                }\n            }\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n        \n        // Update state\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u') blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    double score;  // Accumulated expected score from terminated paths\n    double value;  // Upper bound = score + sum(prob[i] * V[step][i])\n    array<double, 400> prob;\n    string s;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    const int N = 20;\n    auto ID = [&](int i, int j) { return i * N + j; };\n    const int target = ID(ti, tj);\n    const int start = ID(si, sj);\n    const double q = 1.0 - p;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    /*------------------------------------------------------------\n        1. Precompute transitions\n      ------------------------------------------------------------*/\n    int nxt[400][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            int id = ID(i, j);\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                bool wall = false;\n                if (dir == 0) wall = (i == 0) ? true : (v[i-1][j] == '1');\n                else if (dir == 1) wall = (i == 19) ? true : (v[i][j] == '1');\n                else if (dir == 2) wall = (j == 0) ? true : (h[i][j-1] == '1');\n                else wall = (j == 19) ? true : (h[i][j] == '1');\n                nxt[id][dir] = wall ? id : ID(ni, nj);\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        2. Compute closed-loop optimal values V[t][i] (corrected)\n           V[t][i] = max expected additional score from step t (0-indexed)\n      ------------------------------------------------------------*/\n    vector<array<double, 400>> V(201);\n    for (int i = 0; i < 400; ++i) V[200][i] = 0.0;\n    \n    for (int t = 199; t >= 0; --t) {\n        double turn_score = 401.0 - (t + 1);\n        for (int i = 0; i < 400; ++i) {\n            if (i == target) {\n                V[t][i] = 0.0; // Already stopped\n                continue;\n            }\n            double best_val = 0.0;\n            for (int dir = 0; dir < 4; ++dir) {\n                int to = nxt[i][dir];\n                double reward = (to == target) ? turn_score : V[t+1][to];\n                double val = p * V[t+1][i] + q * reward;\n                if (val > best_val) best_val = val;\n            }\n            V[t][i] = best_val;\n        }\n    }\n    \n    /*------------------------------------------------------------\n        3. Exact evaluation function\n      ------------------------------------------------------------*/\n    auto evaluate = [&](const string& s) -> double {\n        array<double, 400> cur{}, nxt_arr{};\n        cur.fill(0.0);\n        cur[start] = 1.0;\n        double score = 0.0;\n        for (int step = 0; step < (int)s.size(); ++step) {\n            nxt_arr.fill(0.0);\n            int dir = (s[step] == 'U') ? 0 : (s[step] == 'D') ? 1 : (s[step] == 'L') ? 2 : 3;\n            double ts = 401.0 - (step + 1);\n            for (int i = 0; i < 400; ++i) {\n                double pr = cur[i];\n                if (pr < 1e-15) continue;\n                // Forgot\n                nxt_arr[i] += pr * p;\n                // Move\n                int to = nxt[i][dir];\n                if (to == target) score += pr * q * ts;\n                else nxt_arr[to] += pr * q;\n            }\n            cur.swap(nxt_arr);\n        }\n        return score;\n    };\n    \n    /*------------------------------------------------------------\n        4. Beam Search (width 100)\n      ------------------------------------------------------------*/\n    const int BEAM = 100;\n    vector<State> beam;\n    State init;\n    init.score = 0.0;\n    init.prob.fill(0.0);\n    init.prob[start] = 1.0;\n    init.s.clear();\n    init.value = V[0][start]; // Upper bound for initial state\n    beam.push_back(init);\n    \n    string best_string;\n    double best_score = 0.0;\n    \n    for (int step = 0; step < 200; ++step) {\n        vector<State> cand;\n        cand.reserve(beam.size() * 4);\n        \n        for (const State& st : beam) {\n            // Pruning: if upper bound <= best found, skip\n            if (st.value <= best_score) continue;\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                State ns;\n                ns.score = st.score;\n                ns.prob.fill(0.0);\n                double ts = 401.0 - (step + 1);\n                \n                for (int i = 0; i < 400; ++i) {\n                    double pr = st.prob[i];\n                    if (pr < 1e-15) continue;\n                    // Forgot\n                    ns.prob[i] += pr * p;\n                    // Move\n                    int to = nxt[i][dir];\n                    if (to == target) ns.score += pr * q * ts;\n                    else ns.prob[to] += pr * q;\n                }\n                \n                ns.s = st.s + dc[dir];\n                \n                // Compute heuristic for next step\n                double future = 0.0;\n                if (step + 1 < 200) {\n                    for (int i = 0; i < 400; ++i) future += ns.prob[i] * V[step+1][i];\n                }\n                ns.value = ns.score + future;\n                \n                if (ns.score > best_score) {\n                    best_score = ns.score;\n                    best_string = ns.s;\n                }\n                \n                cand.push_back(ns);\n            }\n        }\n        \n        if (cand.empty()) break;\n        \n        // Keep top BEAM states by value\n        if ((int)cand.size() > BEAM) {\n            nth_element(cand.begin(), cand.begin() + BEAM, cand.end(),\n                [](const State& a, const State& b) { return a.value > b.value; });\n            cand.resize(BEAM);\n        }\n        beam.swap(cand);\n    }\n    \n    // If beam didn't find anything (unlikely), use simple path\n    if (best_string.empty()) {\n        best_string = string(100, 'D'); // Dummy fallback\n        best_score = evaluate(best_string);\n    }\n    \n    /*------------------------------------------------------------\n        5. Hill Climbing with Incremental Evaluation\n      ------------------------------------------------------------*/\n    string cur_s = best_string;\n    double cur_val = evaluate(cur_s);\n    best_score = cur_val;\n    best_string = cur_s;\n    \n    mt19937 rng(12345);\n    const int MAX_EVAL = 3000;\n    int eval_count = 0;\n    bool improved = true;\n    \n    while (improved && eval_count < MAX_EVAL) {\n        improved = false;\n        int L = cur_s.size();\n        vector<array<double, 400>> pref(L + 1);\n        vector<double> pref_score(L + 1);\n        pref[0].fill(0.0);\n        pref[0][start] = 1.0;\n        pref_score[0] = 0.0;\n        \n        // Precompute prefix distributions and scores\n        for (int i = 0; i < L; ++i) {\n            pref[i+1].fill(0.0);\n            int dir = (cur_s[i] == 'U') ? 0 : (cur_s[i] == 'D') ? 1 : (cur_s[i] == 'L') ? 2 : 3;\n            double ts = 401.0 - (i + 1);\n            double sc = 0.0;\n            for (int j = 0; j < 400; ++j) {\n                double pr = pref[i][j];\n                if (pr < 1e-15) continue;\n                // Forgot\n                pref[i+1][j] += pr * p;\n                // Move\n                int to = nxt[j][dir];\n                if (to == target) sc += pr * q * ts;\n                else pref[i+1][to] += pr * q;\n            }\n            pref_score[i+1] = pref_score[i] + sc;\n        }\n        \n        // Try changing each position\n        for (int pos = 0; pos < L && eval_count < MAX_EVAL; ++pos) {\n            char orig = cur_s[pos];\n            for (int nd = 0; nd < 4; ++nd) {\n                char c = dc[nd];\n                if (c == orig) continue;\n                \n                // Evaluate change at pos using prefix[pos] and simulating suffix\n                array<double, 400> dist = pref[pos];\n                double sc = pref_score[pos];\n                \n                // Apply new char at pos\n                {\n                    array<double, 400> ndist{};\n                    ndist.fill(0.0);\n                    int dir = nd;\n                    double ts = 401.0 - (pos + 1);\n                    for (int j = 0; j < 400; ++j) {\n                        double pr = dist[j];\n                        if (pr < 1e-15) continue;\n                        ndist[j] += pr * p;\n                        int to = nxt[j][dir];\n                        if (to == target) sc += pr * q * ts;\n                        else ndist[to] += pr * q;\n                    }\n                    dist = ndist;\n                }\n                \n                // Apply suffix s[pos+1..]\n                for (int k = pos + 1; k < L; ++k) {\n                    array<double, 400> ndist{};\n                    ndist.fill(0.0);\n                    int dir = (cur_s[k] == 'U') ? 0 : (cur_s[k] == 'D') ? 1 : (cur_s[k] == 'L') ? 2 : 3;\n                    double ts = 401.0 - (k + 1);\n                    for (int j = 0; j < 400; ++j) {\n                        double pr = dist[j];\n                        if (pr < 1e-15) continue;\n                        ndist[j] += pr * p;\n                        int to = nxt[j][dir];\n                        if (to == target) sc += pr * q * ts;\n                        else ndist[to] += pr * q;\n                    }\n                    dist = ndist;\n                }\n                \n                ++eval_count;\n                \n                if (sc > cur_val + 1e-9) {\n                    cur_s[pos] = c;\n                    cur_val = sc;\n                    improved = true;\n                    if (sc > best_score) {\n                        best_score = sc;\n                        best_string = cur_s;\n                    }\n                    goto next_iter; // Restart with new string\n                }\n            }\n        }\n        next_iter:;\n    }\n    \n    cout << best_string << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG() { s = chrono::steady_clock::now().time_since_epoch().count(); }\n    inline uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline int rand(int n) { return next() % n; }\n    inline int rand(int l, int r) { return l + rand(r - l + 1); }\n    inline double drand() { return (double)next() / UINT32_MAX; }\n} rng;\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\ninline int rot_type(int t, int r) {\n    r &= 3;\n    if (t < 4) return (t + r) & 3;\n    if (t < 6) return (r & 1) ? (t ^ 1) : t;\n    return (r & 1) ? (t ^ 1) : t;\n}\n\n// Global buffers - zero-initialized\nstatic int16_t nxt[3600];\nstatic int cyc_id[3600];\nstatic int dist_arr[3600];\nstatic uint32_t visited[3600];\nstatic uint32_t visit_token = 1;\n\n// Find cycles, return L1*L2, fill cyc_len array\nint eval_cycles(int* cyc_len) {\n    if (++visit_token == 0) {\n        memset(visited, 0, sizeof(visited));\n        visit_token = 1;\n    }\n    \n    int max1 = 0, max2 = 0;\n    int cyc_cnt = 0;\n    \n    // Simple iterative cycle finding\n    for (int s = 0; s < 3600; s++) {\n        if (visited[s] == visit_token || nxt[s] < 0) continue;\n        \n        int cur = s;\n        int depth = 0;\n        \n        while (cur >= 0) {\n            if (visited[cur] == visit_token) {\n                if (dist_arr[cur] >= 0) {\n                    int len = depth - dist_arr[cur];\n                    if (len > max1) { max2 = max1; max1 = len; }\n                    else if (len > max2) { max2 = len; }\n                    cyc_cnt++;\n                }\n                break;\n            }\n            visited[cur] = visit_token;\n            dist_arr[cur] = depth++;\n            cur = nxt[cur];\n        }\n        \n        // Reset dist for this path\n        cur = s;\n        while (cur >= 0 && visited[cur] == visit_token && dist_arr[cur] >= 0) {\n            dist_arr[cur] = -1;\n            cur = nxt[cur];\n        }\n    }\n    \n    if (cyc_cnt <= 1) return 0;\n    return max1 * max2;\n}\n\n// Build transition graph\ninline void build_graph(const array<array<int, 30>, 30>& rot, \n                       const array<array<int, 30>, 30>& init) {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = rot_type(init[i][j], rot[i][j]);\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                int d2 = to[t][d];\n                if (d2 < 0) {\n                    nxt[base + d] = -1;\n                } else {\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) {\n                        nxt[base + d] = -1;\n                    } else {\n                        nxt[base + d] = (ni * 30 + nj) * 4 + ((d2 + 2) & 3);\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Fast copy\ninline void copy_rot(array<array<int, 30>, 30>& dst, \n                    const array<array<int, 30>, 30>& src) {\n    memcpy(&dst[0][0], &src[0][0], 900 * sizeof(int));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    array<array<int, 30>, 30> init{};\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) init[i][j] = s[j] - '0';\n    }\n    \n    // Try different initialization strategies\n    array<array<int, 30>, 30> best{}, cur{};\n    int best_score = -1;\n    int dummy[3600];\n    \n    const double TL = 1.95;\n    clock_t start = clock();\n    \n    for (int rep = 0; rep < 3; rep++) {\n        // Random init\n        for (int i = 0; i < 30; i++)\n            for (int j = 0; j < 30; j++)\n                cur[i][j] = rng.rand(4);\n        \n        build_graph(cur, init);\n        int cur_score = eval_cycles(dummy);\n        \n        if (cur_score > best_score) {\n            best_score = cur_score;\n            copy_rot(best, cur);\n        }\n        \n        // SA\n        double temp = 30.0;\n        int iter = 0;\n        int last_imp = 0;\n        \n        while (true) {\n            double elap = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elap > TL || elap > (rep + 1) * TL / 3) break;\n            \n            // Pick random tile\n            int i = rng.rand(30);\n            int j = rng.rand(30);\n            int old = cur[i][j];\n            \n            // Try 3 rotations, pick best\n            int best_r = old;\n            int best_s = cur_score;\n            \n            for (int k = 1; k <= 3; k++) {\n                cur[i][j] = (old + k) & 3;\n                build_graph(cur, init);\n                int s = eval_cycles(dummy);\n                if (s > best_s) {\n                    best_s = s;\n                    best_r = cur[i][j];\n                }\n            }\n            \n            // Accept?\n            if (best_s >= cur_score) {\n                cur[i][j] = best_r;\n                cur_score = best_s;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    copy_rot(best, cur);\n                    last_imp = iter;\n                }\n            } else {\n                // SA condition\n                if (rng.drand() < exp((best_s - cur_score) / temp)) {\n                    cur[i][j] = best_r;\n                    cur_score = best_s;\n                } else {\n                    cur[i][j] = old;\n                }\n            }\n            \n            temp *= 0.9999;\n            iter++;\n            \n            // Restart if stuck\n            if (iter - last_imp > 5000) {\n                // Randomize 5% of tiles\n                for (int k = 0; k < 45; k++) {\n                    cur[rng.rand(30)][rng.rand(30)] = rng.rand(4);\n                }\n                build_graph(cur, init);\n                cur_score = eval_cycles(dummy);\n                last_imp = iter;\n                temp = 20.0;\n            }\n        }\n    }\n    \n    // Final greedy pass\n    copy_rot(cur, best);\n    build_graph(cur, init);\n    int cur_score = eval_cycles(dummy);\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int t = 0; t < 900; t++) {\n            double elap = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elap > TL) break;\n            \n            int i = rng.rand(30);\n            int j = rng.rand(30);\n            int old = cur[i][j];\n            \n            for (int r = 0; r < 4; r++) {\n                if (r == old) continue;\n                cur[i][j] = r;\n                build_graph(cur, init);\n                int s = eval_cycles(dummy);\n                if (s > cur_score) {\n                    cur_score = s;\n                    improved = true;\n                    if (s > best_score) {\n                        best_score = s;\n                        copy_rot(best, cur);\n                    }\n                    goto next_tile;\n                }\n            }\n            cur[i][j] = old;\n            next_tile:;\n        }\n    }\n    \n    string out;\n    out.reserve(900);\n    for (int i = 0; i < 30; i++)\n        for (int j = 0; j < 30; j++)\n            out += char('0' + best[i][j]);\n    cout << out << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> initial_board;\nint target_score; // N*N - 1\n\nstruct State {\n    array<array<int, 10>, 10> bd;\n    int er, ec;\n    string moves;\n    \n    State() {}\n    State(const vector<string>& b, int _er, int _ec) : er(_er), ec(_ec), moves(\"\") {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = b[i][j];\n                bd[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            }\n        }\n    }\n    \n    bool in_bounds(int r, int c) const {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    char reverse(char c) const {\n        if (c == 'U') return 'D';\n        if (c == 'D') return 'U';\n        if (c == 'L') return 'R';\n        return 'L';\n    }\n    \n    bool can_move(char c) const {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else if (c == 'R') nc++;\n        return in_bounds(nr, nc);\n    }\n    \n    void move(char c) {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else if (c == 'R') nc++;\n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n        moves.push_back(c);\n    }\n    \n    // Fast scoring: returns (size of largest tree, is_perfect)\n    pair<int, bool> calc_score() const {\n        int V = N * N;\n        vector<int> parent(V);\n        iota(parent.begin(), parent.end(), 0);\n        \n        function<int(int)> find = [&](int x) -> int {\n            while (parent[x] != x) {\n                parent[x] = parent[parent[x]];\n                x = parent[x];\n            }\n            return x;\n        };\n        \n        auto unite = [&](int x, int y) {\n            x = find(x);\n            y = find(y);\n            if (x != y) parent[x] = y;\n        };\n        \n        // Build connectivity\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    unite(i * N + j, i * N + j + 1);\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    unite(i * N + j, (i + 1) * N + j);\n                }\n            }\n        }\n        \n        vector<int> verts(V, 0), edges(V, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] != 0) {\n                    verts[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N - 1; j++) {\n                if (bd[i][j] == 0 || bd[i][j+1] == 0) continue;\n                if ((bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] == 0 || bd[i+1][j] == 0) continue;\n                if ((bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    edges[find(i * N + j)]++;\n                }\n            }\n        }\n        \n        int best = 0;\n        for (int i = 0; i < V; i++) {\n            if (verts[i] > 0 && edges[i] == verts[i] - 1) {\n                best = max(best, verts[i]);\n            }\n        }\n        return {best, best == target_score};\n    }\n};\n\nstruct Solution {\n    State st;\n    int score;\n    double eval_score; // For perfect solutions: higher is better (fewer moves)\n};\n\nstring solve() {\n    // Find initial empty cell\n    int er = -1, ec = -1;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (initial_board[i][j] == '0') {\n                er = i;\n                ec = j;\n                break;\n            }\n        }\n        if (er != -1) break;\n    }\n    \n    if (er == -1) return \"\";\n    \n    auto start = chrono::steady_clock::now();\n    const double TL = 2.8;\n    \n    Solution global_best;\n    global_best.score = -1;\n    global_best.eval_score = -1;\n    \n    // Multi-epoch strategy: run multiple independent searches\n    const int EPOCHS = 5;\n    \n    for (int epoch = 0; epoch < EPOCHS; epoch++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TL - 0.1) break;\n        \n        double time_per_epoch = (TL - elapsed) / (EPOCHS - epoch);\n        auto epoch_start = chrono::steady_clock::now();\n        \n        State cur(initial_board, er, ec);\n        auto [cur_score, is_perfect] = cur.calc_score();\n        \n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count() + epoch * 12345);\n        \n        double temp = 30.0;\n        const double cooling = 0.99997;\n        \n        int iter = 0;\n        int last_improve = 0;\n        \n        while (true) {\n            now = chrono::steady_clock::now();\n            double epoch_elapsed = chrono::duration<double>(now - epoch_start).count();\n            if (epoch_elapsed > time_per_epoch) break;\n            \n            // Hard time limit\n            elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > TL - 0.05) break;\n            \n            // Path length limit\n            if ((int)cur.moves.size() >= T - 5) {\n                // Restart from initial\n                cur = State(initial_board, er, ec);\n                auto [sc, _] = cur.calc_score();\n                cur_score = sc;\n                temp = 30.0;\n                continue;\n            }\n            \n            // Generate candidates\n            char prev_rev = cur.moves.empty() ? 'X' : cur.reverse(cur.moves.back());\n            vector<pair<char, int>> candidates; // move, score\n            \n            for (char c : {'U', 'D', 'L', 'R'}) {\n                if (c == prev_rev) continue;\n                if (!cur.can_move(c)) continue;\n                \n                // Temporarily apply\n                State nxt = cur;\n                nxt.move(c);\n                auto [sc, perf] = nxt.calc_score();\n                candidates.push_back({c, sc});\n            }\n            \n            if (candidates.empty()) continue;\n            \n            // Sort by score descending\n            sort(candidates.begin(), candidates.end(), \n                 [](const auto& a, const auto& b) { return a.second > b.second; });\n            \n            char chosen;\n            int new_score;\n            bool accept = false;\n            \n            // Always take improvement\n            if (candidates[0].second > cur_score) {\n                chosen = candidates[0].first;\n                new_score = candidates[0].second;\n                accept = true;\n                last_improve = iter;\n            } \n            // Sometimes take equal to explore\n            else if (candidates[0].second == cur_score && (rng() & 0x3) == 0) {\n                chosen = candidates[0].first;\n                new_score = candidates[0].second;\n                accept = true;\n            }\n            // SA acceptance for worse\n            else {\n                // Pick random from top 3\n                int range = min(3, (int)candidates.size());\n                uniform_int_distribution<int> dist(0, range - 1);\n                int idx = dist(rng);\n                chosen = candidates[idx].first;\n                new_score = candidates[idx].second;\n                \n                double delta = new_score - cur_score;\n                if (delta >= 0 || exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    accept = true;\n                }\n            }\n            \n            if (accept) {\n                cur.move(chosen);\n                cur_score = new_score;\n                \n                // Update global best\n                bool is_better = false;\n                if (cur_score > global_best.score) {\n                    is_better = true;\n                } else if (cur_score == global_best.score && cur_score == target_score) {\n                    // Both perfect, prefer shorter\n                    if (cur.moves.size() < global_best.st.moves.size()) {\n                        is_better = true;\n                    }\n                }\n                \n                if (is_better) {\n                    global_best.st = cur;\n                    global_best.score = cur_score;\n                    // For perfect solutions, eval_score is based on move count\n                    global_best.eval_score = (cur_score == target_score) ? \n                        (2.0 - (double)cur.moves.size() / T) : cur_score;\n                }\n            }\n            \n            // Adaptive restart if stuck\n            if (iter - last_improve > 5000 && global_best.score < target_score) {\n                // Reset with some probability\n                if (uniform_int_distribution<int>(0, 100)(rng) < 30) {\n                    cur = State(initial_board, er, ec);\n                    auto [sc, _] = cur.calc_score();\n                    cur_score = sc;\n                    temp = 30.0;\n                    last_improve = iter;\n                }\n            }\n            \n            temp *= cooling;\n            iter++;\n        }\n    }\n    \n    // Validate result\n    if (global_best.score < 0) return \"\";\n    \n    State validator(initial_board, er, ec);\n    for (char c : global_best.st.moves) {\n        if (!validator.can_move(c)) return \"\";\n        validator.move(c);\n    }\n    \n    // Verify score matches\n    auto [final_score, _] = validator.calc_score();\n    if (final_score != global_best.score) return \"\";\n    \n    return global_best.st.moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    initial_board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> initial_board[i];\n    }\n    \n    target_score = N * N - 1;\n    \n    string ans = solve();\n    cout << ans << \"\\n\";\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long x1, y1, x2, y2;\n};\n\nint N, K;\nint target[11];\nvector<Point> pts;\nvector<Line> cuts;\n\n// Current partition: piece_id[i] = index of piece for strawberry i\nvector<int> piece_id;\n// List of pieces (each is list of indices)\nvector<vector<int>> pieces;\nint cur_cnt[12]; // cur_cnt[d] for d=1..10, cur_cnt[0] for >10 or empty\n\nint calc_score() {\n    int res = 0;\n    for (int d = 1; d <= 10; d++) {\n        res += min(cur_cnt[d], target[d]);\n    }\n    return res;\n}\n\n// side: -1 for left, 1 for right, 0 for on line\nint side(const Point& p, const Line& ln) {\n    long long v1x = ln.x2 - ln.x1;\n    long long v1y = ln.y2 - ln.y1;\n    long long v2x = p.x - ln.x1;\n    long long v2y = p.y - ln.y1;\n    long long cr = v1x * v2y - v1y * v2x;\n    if (cr < 0) return -1;\n    if (cr > 0) return 1;\n    return 0;\n}\n\n// Apply cut and update state\nvoid apply_cut(const Line& ln) {\n    vector<vector<int>> new_pieces;\n    vector<int> new_id(N);\n    new_pieces.reserve(pieces.size() * 2);\n    \n    int pid = 0;\n    for (auto& pc : pieces) {\n        vector<int> left, right;\n        left.reserve(pc.size());\n        right.reserve(pc.size());\n        for (int idx : pc) {\n            int s = side(pts[idx], ln);\n            if (s == 0) {\n                // Should not happen if we generate lines correctly\n                // Put to left arbitrarily\n                left.push_back(idx);\n            } else if (s < 0) {\n                left.push_back(idx);\n            } else {\n                right.push_back(idx);\n            }\n        }\n        if (!left.empty()) {\n            for (int idx : left) new_id[idx] = pid;\n            new_pieces.push_back(move(left));\n            pid++;\n        }\n        if (!right.empty()) {\n            for (int idx : right) new_id[idx] = pid;\n            new_pieces.push_back(move(right));\n            pid++;\n        }\n    }\n    \n    pieces = move(new_pieces);\n    piece_id = move(new_id);\n    \n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    for (auto& pc : pieces) {\n        int s = pc.size();\n        if (1 <= s && s <= 10) cur_cnt[s]++;\n        else if (s > 10) cur_cnt[0]++;\n    }\n}\n\n// Generate a random line attempting to split a specific piece\n// Returns line and the expected sizes (approximate)\nLine generate_cut_for_piece(const vector<int>& pc, int& out_left, int& out_right) {\n    int n = pc.size();\n    out_left = n/2;\n    out_right = n - n/2;\n    \n    if (n < 2) return {0,0,0,0};\n    \n    // Random projection direction\n    double theta = (double)rand() / RAND_MAX * 2.0 * M_PI;\n    long long dx = (long long)(cos(theta) * 1000000);\n    long long dy = (long long)(sin(theta) * 1000000);\n    \n    // Project\n    vector<pair<long long, int>> proj;\n    proj.reserve(n);\n    for (int idx : pc) {\n        long long dot = pts[idx].x * dx + pts[idx].y * dy;\n        proj.emplace_back(dot, idx);\n    }\n    sort(proj.begin(), proj.end());\n    \n    // Try to cut at various positions\n    vector<int> try_pos;\n    // Try to isolate small groups that are needed\n    for (int d = 1; d <= min(10, n-1); d++) {\n        if (target[d] > cur_cnt[d]) {\n            try_pos.push_back(d);\n        }\n    }\n    // Also try middle\n    try_pos.push_back(n/2);\n    \n    for (int d : try_pos) {\n        if (d <= 0 || d >= n) continue;\n        // Cut between d-1 and d\n        // Find perpendicular direction\n        // Original direction: (dx, dy), perpendicular: (-dy, dx)\n        long long px = -dy;\n        long long py = dx;\n        \n        // Midpoint between proj[d-1] and proj[d]\n        long long midx = (pts[proj[d-1].second].x + pts[proj[d].second].x) / 2;\n        long long midy = (pts[proj[d-1].second].y + pts[proj[d].second].y) / 2;\n        \n        // Line: passes through (midx, midy), direction (px, py)\n        // Use points far away to ensure integer coordinates and range\n        Line ln;\n        ln.x1 = midx - px;\n        ln.y1 = midy - py;\n        ln.x2 = midx + px;\n        ln.y2 = midy + py;\n        \n        // Check range\n        if (abs(ln.x1) > 1e9 || abs(ln.y1) > 1e9 || abs(ln.x2) > 1e9 || abs(ln.y2) > 1e9) {\n            // Scale down or skip\n            continue;\n        }\n        \n        // Verify no point on line\n        bool ok = true;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) == 0) {\n                ok = false;\n                break;\n            }\n        }\n        if (!ok) continue;\n        \n        // Count actual split\n        int lc = 0, rc = 0;\n        for (int idx : pc) {\n            if (side(pts[idx], ln) < 0) lc++;\n            else rc++;\n        }\n        if (lc == 0 || rc == 0) continue;\n        \n        out_left = lc;\n        out_right = rc;\n        return ln;\n    }\n    \n    return {0,0,0,0};\n}\n\n// Generate completely random line\nLine generate_random_cut() {\n    Line ln;\n    ln.x1 = (rand() % 2000000000) - 1000000000;\n    ln.y1 = (rand() % 2000000000) - 1000000000;\n    ln.x2 = (rand() % 2000000000) - 1000000000;\n    ln.y2 = (rand() % 2000000000) - 1000000000;\n    if (ln.x1 == ln.x2 && ln.y1 == ln.y2) {\n        ln.x2++;\n    }\n    \n    // Ensure no point on line\n    bool bad = true;\n    int attempts = 0;\n    while (bad && attempts < 10) {\n        bad = false;\n        for (int i = 0; i < N; i++) {\n            if (side(pts[i], ln) == 0) {\n                bad = true;\n                ln.x2 += (rand() % 10) - 5;\n                ln.y2 += (rand() % 10) - 5;\n                attempts++;\n                break;\n            }\n        }\n    }\n    return ln;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(42); // Fixed seed for reproducibility, can use time(0) in contest\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> target[i];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n    \n    // Initial state: one piece containing all\n    pieces.resize(1);\n    pieces[0].resize(N);\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n    piece_id.assign(N, 0);\n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    if (N <= 10) cur_cnt[N] = 1;\n    else cur_cnt[0] = 1;\n    \n    int current_score = calc_score();\n    \n    for (int iter = 0; iter < K; iter++) {\n        Line best_ln = {0,0,0,0};\n        int best_new_score = current_score;\n        bool found = false;\n        \n        // Identify candidate pieces to split\n        vector<int> cand_pieces;\n        for (int i = 0; i < pieces.size(); i++) {\n            int s = pieces[i].size();\n            if (s > 1) {\n                // Split if too large or we have excess of this size\n                if (s > 10 || (s <= 10 && cur_cnt[s] > target[s])) {\n                    cand_pieces.push_back(i);\n                }\n            }\n        }\n        \n        if (cand_pieces.empty()) {\n            // Try to improve by splitting any piece that might allow better distribution\n            for (int i = 0; i < pieces.size(); i++) {\n                if (pieces[i].size() > 1) cand_pieces.push_back(i);\n            }\n        }\n        \n        if (cand_pieces.empty()) break;\n        \n        // Try candidates from specific pieces\n        for (int pid : cand_pieces) {\n            for (int t = 0; t < 30; t++) {\n                int lc, rc;\n                Line ln = generate_cut_for_piece(pieces[pid], lc, rc);\n                if (ln.x1 == 0 && ln.y1 == 0) continue;\n                \n                // Quick evaluation: compute delta score\n                int delta = 0;\n                int s = pieces[pid].size();\n                \n                // Remove s\n                if (s <= 10) {\n                    delta -= min(cur_cnt[s], target[s]) - min(cur_cnt[s]-1, target[s]);\n                }\n                // Add lc, rc\n                if (lc <= 10 && lc >= 1) {\n                    delta += min(cur_cnt[lc]+1, target[lc]) - min(cur_cnt[lc], target[lc]);\n                }\n                if (rc <= 10 && rc >= 1 && rc != lc) {\n                    delta += min(cur_cnt[rc]+1, target[rc]) - min(cur_cnt[rc], target[rc]);\n                } else if (rc == lc && rc <= 10 && rc >= 1) {\n                    // If both sides same size, we added 2, but above counted 1\n                    delta += min(cur_cnt[rc]+2, target[rc]) - min(cur_cnt[rc]+1, target[rc]);\n                }\n                \n                // But this delta calculation ignores other pieces being split!\n                // The generate_cut_for_piece only checks the target piece.\n                // We need full simulation.\n                \n                // Full simulation\n                auto old_pieces = pieces;\n                auto old_pid = piece_id;\n                auto old_cnt = cur_cnt;\n                int old_score = current_score;\n                \n                apply_cut(ln);\n                int new_score = calc_score();\n                \n                if (new_score > best_new_score) {\n                    best_new_score = new_score;\n                    best_ln = ln;\n                    found = true;\n                }\n                \n                // Restore\n                pieces = old_pieces;\n                piece_id = old_pid;\n                memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n                current_score = old_score;\n            }\n        }\n        \n        // Also try some random cuts\n        for (int t = 0; t < 20; t++) {\n            Line ln = generate_random_cut();\n            \n            auto old_pieces = pieces;\n            auto old_pid = piece_id;\n            auto old_cnt = cur_cnt;\n            \n            apply_cut(ln);\n            int new_score = calc_score();\n            \n            if (new_score > best_new_score) {\n                best_new_score = new_score;\n                best_ln = ln;\n                found = true;\n            }\n            \n            pieces = old_pieces;\n            piece_id = old_pid;\n            memcpy(cur_cnt, old_cnt, sizeof(cur_cnt));\n        }\n        \n        if (!found) break;\n        \n        apply_cut(best_ln);\n        cuts.push_back(best_ln);\n        current_score = best_new_score;\n    }\n    \n    cout << cuts.size() << \"\\n\";\n    for (auto& ln : cuts) {\n        cout << ln.x1 << \" \" << ln.y1 << \" \" << ln.x2 << \" \" << ln.y2 << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nusing ull = unsigned long long;\nusing ll = long long;\n\nint N, M, C;\n\n/* bit masks for fast axis\u2011aligned checks */\nvector<ull> dot_row;   // dot_row[y] : bit x = 1 \u21d4 dot at (x,y)\nvector<ull> dot_col;   // dot_col[x] : bit y = 1 \u21d4 dot at (x,y)\n\nvector<ull> edge_h_row; // horizontal edge (x,y)-(x+1,y) stored at row y, bit x\nvector<ull> edge_v_col; // vertical   edge (x,y)-(x,y+1) stored at col x, bit y\n\n/* diagonal edge arrays (canonical, as in the previous AC solution) */\nvector<vector<bool>> edge_d1; // (x,y)-(x+1,y+1)\nvector<vector<bool>> edge_d2; // (x,y)-(x+1,y-1)\n\nstruct Operation {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\nstatic inline double get_time() {\n    return chrono::duration<double>(chrono::steady_clock::now().time_since_epoch()).count();\n}\n\n/*---------- axis aligned helpers (bit mask version) ----------*/\n\ninline ull mask_range(int l, int r) { // bits [l, r) , r>l, length <= 60\n    return ((1ULL << (r - l)) - 1ULL) << l;\n}\n\n// check axis rectangle (x1,y1)-(x2,y2)  (xl,yl)-(xr,yr)\nbool check_axis_fast(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    if (xl == xr || yl == yr) return false;\n\n    /* dots on perimeter (excluding the four corners) */\n    if (xr - xl > 1) {\n        ull m = mask_range(xl + 1, xr);\n        if (dot_row[yl] & m) return false; // bottom side\n        if (dot_row[yr] & m) return false; // top side\n    }\n    if (yr - yl > 1) {\n        ull m = mask_range(yl + 1, yr);\n        if (dot_col[xl] & m) return false; // left side\n        if (dot_col[xr] & m) return false; // right side\n    }\n\n    /* edges must be free */\n    ull mh = mask_range(xl, xr); // length xr-xl\n    if ( (edge_h_row[yl] & mh) || (edge_h_row[yr] & mh) ) return false;\n\n    ull mv = mask_range(yl, yr); // length yr-yl\n    if ( (edge_v_col[xl] & mv) || (edge_v_col[xr] & mv) ) return false;\n\n    return true;\n}\n\nvoid add_axis_fast(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    ull mh = mask_range(xl, xr);\n    edge_h_row[yl] |= mh;\n    edge_h_row[yr] |= mh;\n    ull mv = mask_range(yl, yr);\n    edge_v_col[xl] |= mv;\n    edge_v_col[xr] |= mv;\n}\n\n/*---------- 45 degree helpers (same as before, canonical indices) ----------*/\n\nbool walk_check(int xs, int ys, int xt, int yt) {\n    int dx = (xt > xs) ? 1 : -1;\n    int dy = (yt > ys) ? 1 : -1;\n    int len = abs(xt - xs);\n    for (int i = 1; i < len; ++i) {\n        int x = xs + i * dx, y = ys + i * dy;\n        if ( (dot_row[y] >> x) & 1ULL ) return false;\n    }\n    for (int i = 0; i < len; ++i) {\n        int x = xs + i * dx, y = ys + i * dy;\n        if (dx == dy) {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == 1) ? y : y - 1;\n            if (edge_d1[ex][ey]) return false;\n        } else {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == -1) ? y : y + 1;\n            if (edge_d2[ex][ey]) return false;\n        }\n    }\n    return true;\n}\n\nvoid walk_mark(int xs, int ys, int xt, int yt) {\n    int dx = (xt > xs) ? 1 : -1;\n    int dy = (yt > ys) ? 1 : -1;\n    int len = abs(xt - xs);\n    for (int i = 0; i < len; ++i) {\n        int x = xs + i * dx, y = ys + i * dy;\n        if (dx == dy) {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == 1) ? y : y - 1;\n            edge_d1[ex][ey] = true;\n        } else {\n            int ex = (dx == 1) ? x : x - 1;\n            int ey = (dy == -1) ? y : y + 1;\n            edge_d2[ex][ey] = true;\n        }\n    }\n}\n\nbool check_45_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    return walk_check(x1,y1,x2,y2) && walk_check(x2,y2,x3,y3) &&\n           walk_check(x3,y3,x4,y4) && walk_check(x4,y4,x1,y1);\n}\n\nvoid add_45(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    walk_mark(x1,y1,x2,y2); walk_mark(x2,y2,x3,y3);\n    walk_mark(x3,y3,x4,y4); walk_mark(x4,y4,x1,y1);\n}\n\n/*---------- candidate description ----------*/\nstruct Cand {\n    int x2,y2,x3,y3,x4,y4;\n    int perim;\n    bool axis;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    C = (N-1)/2;\n\n    vector<pair<int,int>> init_dots;\n    init_dots.reserve(M);\n    for (int i=0;i<M;i++) {\n        int x,y; cin>>x>>y;\n        init_dots.emplace_back(x,y);\n    }\n\n    /* weights */\n    vector<vector<int>> W(N, vector<int>(N));\n    for (int x=0;x<N;x++)\n        for (int y=0;y<N;y++)\n            W[x][y] = (x-C)*(x-C)+(y-C)*(y-C)+1;\n\n    const double TL = 4.8;\n    double start = get_time();\n\n    vector<Operation> best_ops;\n    ll best_score = -1;\n    unsigned rng_seed = (unsigned)chrono::steady_clock::now().time_since_epoch().count();\n    mt19937 rng(rng_seed);\n\n    /* list of empty cells */\n    vector<tuple<int,int,int>> all_cells; // (weight, x, y)\n    all_cells.reserve(N*N);\n    for (int x=0;x<N;x++)\n        for (int y=0;y<N;y++)\n            all_cells.emplace_back(W[x][y], x, y);\n\n    int iteration = 0;\n    while (get_time() - start < TL) {\n        ++iteration;\n        /* reset structures */\n        dot_row.assign(N, 0ULL);\n        dot_col.assign(N, 0ULL);\n        for (auto &p: init_dots) {\n            int x=p.first, y=p.second;\n            dot_row[y] |= (1ULL<<x);\n            dot_col[x] |= (1ULL<<y);\n        }\n\n        edge_h_row.assign(N, 0ULL);\n        edge_v_col.assign(N, 0ULL);\n        edge_d1.assign(N, vector<bool>(N,false));\n        edge_d2.assign(N, vector<bool>(N,false));\n\n        vector<pair<int,int>> dots = init_dots; // list of existing dots, grows\n\n        /* prepare processing order */\n        vector<tuple<int,int,int>> cells = all_cells;\n        shuffle(cells.begin(), cells.end(), rng);\n        sort(cells.begin(), cells.end(),\n             [](const auto&a, const auto&b){ return get<0>(a) > get<0>(b); });\n\n        vector<Operation> ops;\n        ll cur_score = 0;\n        for (auto &p: init_dots) cur_score += W[p.first][p.second];\n\n        /* multi\u2011pass greedy */\n        bool progress = true;\n        while (progress) {\n            progress = false;\n            for (auto &[val, x1, y1] : cells) {\n                if ( (dot_row[y1]>>x1) & 1ULL ) continue; // already has dot\n\n                vector<Cand> cand;\n                cand.reserve(dots.size()*2);\n\n                /* axis\u2011aligned: iterate dots in same row / same col */\n                // row y1 gives p2 candidates\n                ull rowbits = dot_row[y1];\n                while (rowbits) {\n                    int x2 = __builtin_ctzll(rowbits);\n                    rowbits &= rowbits-1;\n                    if (x2==x1) continue;\n                    // need p4 = (x1, y2) and p3 = (x2, y2)\n                    // iterate over y2 where dot_col[x1] has bit and dot_row[y2] has bit x2\n                    ull colbits = dot_col[x1];\n                    while (colbits) {\n                        int y2 = __builtin_ctzll(colbits);\n                        colbits &= colbits-1;\n                        if (y2==y1) continue;\n                        if ( (dot_row[y2]>>x2)&1ULL ) {\n                            int perim = 2*(abs(x1-x2)+abs(y1-y2));\n                            cand.push_back({x2,y1,x2,y2,x1,y2,perim,true});\n                        }\n                    }\n                }\n\n                /* 45\u2011degree: iterate all dots as diagonal (slower but M is small) */\n                for (auto &[x3,y3] : dots) {\n                    int dx = x3-x1, dy = y3-y1;\n                    if ( ((dx+dy)&1) || ((dx-dy)&1) ) continue;\n                    int a = (dx+dy)>>1, b = (dx-dy)>>1;\n                    if (a==0 || b==0) continue;\n                    int x2 = x1+a, y2 = y1+a;\n                    int x4 = x1+b, y4 = y1-b;\n                    if (x2<0||x2>=N||y2<0||y2>=N) continue;\n                    if (x4<0||x4>=N||y4<0||y4>=N) continue;\n                    if ( ((dot_row[y2]>>x2)&1ULL)==0 ) continue;\n                    if ( ((dot_row[y4]>>x4)&1ULL)==0 ) continue;\n                    int perim = 2*(abs(a)+abs(b));\n                    cand.push_back({x2,y2,x3,y3,x4,y4,perim,false});\n                }\n\n                if (cand.empty()) continue;\n\n                /* strategy: 0 = min perimeter, 1 = max perimeter, 2 = random shuffle */\n                int strat = uniform_int_distribution<int>(0,2)(rng);\n                if (strat==0)\n                    sort(cand.begin(), cand.end(), [](const Cand&a,const Cand&b){return a.perim<b.perim;});\n                else if (strat==1)\n                    sort(cand.begin(), cand.end(), [](const Cand&a,const Cand&b){return a.perim>b.perim;});\n                else\n                    shuffle(cand.begin(), cand.end(), rng);\n\n                bool placed = false;\n                for (const auto &c : cand) {\n                    bool ok = c.axis ?\n                        check_axis_fast(x1,y1,c.x3,c.y3) :\n                        check_45_edges(x1,y1,c.x2,c.y2,c.x3,c.y3,c.x4,c.y4);\n                    if (ok) {\n                        ops.push_back({x1,y1,c.x2,c.y2,c.x3,c.y3,c.x4,c.y4});\n                        dot_row[y1] |= (1ULL<<x1);\n                        dot_col[x1] |= (1ULL<<y1);\n                        dots.emplace_back(x1,y1);\n                        cur_score += val;\n                        if (c.axis) add_axis_fast(x1,y1,c.x3,c.y3);\n                        else        add_45(x1,y1,c.x2,c.y2,c.x3,c.y3,c.x4,c.y4);\n                        placed = true;\n                        progress = true;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            best_ops = ops;\n        }\n    }\n\n    cout << best_ops.size() << \"\\n\";\n    for (auto &op: best_ops) {\n        cout << op.x1 << \" \" << op.y1 << \" \"\n             << op.x2 << \" \" << op.y2 << \" \"\n             << op.x3 << \" \" << op.y3 << \" \"\n             << op.x4 << \" \" << op.y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed = chrono::steady_clock::now().time_since_epoch().count()) {\n        s = seed;\n    }\n    uint64_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return s;\n    }\n    int randint(int n) {\n        return next() % n;\n    }\n} rng;\n\nstruct Grid {\n    uint8_t a[10][10];\n    \n    Grid() {\n        memset(a, 0, sizeof(a));\n    }\n    \n    void place(int p, int f) {\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void placeRandom(int f, int numEmpty) {\n        int p = rng.randint(numEmpty) + 1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') {\n            for (int j = 0; j < 10; j++) {\n                int write = 0;\n                for (int i = 0; i < 10; i++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write++][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'B') {\n            for (int j = 0; j < 10; j++) {\n                int write = 9;\n                for (int i = 9; i >= 0; i--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write--][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'L') {\n            for (int i = 0; i < 10; i++) {\n                int write = 0;\n                for (int j = 0; j < 10; j++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write++] = val;\n                    }\n                }\n            }\n        } else if (dir == 'R') {\n            for (int i = 0; i < 10; i++) {\n                int write = 9;\n                for (int j = 9; j >= 0; j--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write--] = val;\n                    }\n                }\n            }\n        }\n    }\n    \n    int countEmpty() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++)\n            for (int j = 0; j < 10; j++)\n                if (a[i][j] == 0) cnt++;\n        return cnt;\n    }\n    \n    long long calcScore() const {\n        bool vis[10][10] = {};\n        long long res = 0;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] != 0 && !vis[i][j]) {\n                    uint8_t f = a[i][j];\n                    int sz = 0;\n                    int q[100];\n                    int qe = 0;\n                    q[qe++] = i * 10 + j;\n                    vis[i][j] = true;\n                    \n                    while (qe > 0) {\n                        int cur = q[--qe];\n                        int x = cur / 10, y = cur % 10;\n                        sz++;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !vis[nx][ny] && a[nx][ny] == f) {\n                                vis[nx][ny] = true;\n                                q[qe++] = nx * 10 + ny;\n                            }\n                        }\n                    }\n                    res += 1LL * sz * sz;\n                }\n            }\n        }\n        return res;\n    }\n    \n    // Fast heuristic: count same-flavor adjacent pairs\n    int countEdges() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) continue;\n                if (i < 9 && a[i][j] == a[i+1][j]) cnt++;\n                if (j < 9 && a[i][j] == a[i][j+1]) cnt++;\n            }\n        }\n        return cnt;\n    }\n    \n    // Greedy tilt: choose direction maximizing edges\n    char greedyTilt() {\n        char bestDir = 'F';\n        int bestEdges = -1;\n        char dirs[4] = {'F', 'B', 'L', 'R'};\n        \n        for (int d = 0; d < 4; d++) {\n            Grid tmp = *this;\n            tmp.tilt(dirs[d]);\n            int e = tmp.countEdges();\n            if (e > bestEdges) {\n                bestEdges = e;\n                bestDir = dirs[d];\n            }\n        }\n        return bestDir;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> f[i];\n    }\n    \n    Grid grid;\n    const char dirs[4] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        grid.place(p, f[t]);\n        \n        if (t == 99) {\n            cout << \"F\\n\" << flush;\n            break;\n        }\n        \n        int remaining = 99 - t;\n        // Adaptive samples: more samples early when structure matters\n        int samples = max(15, min(50, 2000 / (remaining + 5)));\n        \n        long long bestTotal = -1;\n        char bestDir = 'F';\n        \n        // Try each direction for the current tilt\n        for (int d = 0; d < 4; d++) {\n            long long totalScore = 0;\n            \n            for (int s = 0; s < samples; s++) {\n                Grid sim = grid;\n                sim.tilt(dirs[d]);\n                int numEmpty = 100 - (t + 1);\n                \n                // Rollout with greedy policy\n                for (int tt = t + 1; tt < 100; tt++) {\n                    sim.placeRandom(f[tt], numEmpty--);\n                    char gdir = sim.greedyTilt();\n                    sim.tilt(gdir);\n                }\n                \n                totalScore += sim.calcScore();\n            }\n            \n            if (totalScore > bestTotal) {\n                bestTotal = totalScore;\n                bestDir = dirs[d];\n            }\n        }\n        \n        cout << bestDir << \"\\n\" << flush;\n        grid.tilt(bestDir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Adaptive N: use larger N for higher epsilon to maintain distinguishability\n    int N;\n    if (eps < 0.12) N = 20;\n    else if (eps < 0.22) N = 30;\n    else if (eps < 0.32) N = 50;\n    else if (eps < 0.38) N = 80;\n    else N = 100;\n    \n    if (N > 100) N = 100;\n    if (N < 4) N = 4;\n    \n    // Precompute reference graphs\n    vector<vector<int>> ref_degs(M, vector<int>(N));\n    vector<Eigen::VectorXd> ref_eigs(M);\n    vector<string> ref_strs(M);\n    \n    for (int i = 0; i < M; ++i) {\n        mt19937 gen(i * 1234567 + 42);\n        bernoulli_distribution d(0.5);\n        \n        Eigen::MatrixXd A = Eigen::MatrixXd::Zero(N, N);\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        vector<int> deg(N, 0);\n        \n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (d(gen)) {\n                    A(u, v) = A(v, u) = 1.0;\n                    deg[u]++;\n                    deg[v]++;\n                    s.push_back('1');\n                } else {\n                    s.push_back('0');\n                }\n            }\n        }\n        \n        ref_strs[i] = s;\n        sort(deg.begin(), deg.end());\n        ref_degs[i] = deg;\n        \n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(A);\n        Eigen::VectorXd eig = solver.eigenvalues();\n        sort(eig.data(), eig.data() + N, greater<double>());\n        ref_eigs[i] = eig;\n    }\n    \n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << ref_strs[i] << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        // Parse query graph\n        Eigen::MatrixXd H = Eigen::MatrixXd::Zero(N, N);\n        vector<int> h_deg(N, 0);\n        int pos = 0;\n        \n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (h_str[pos++] == '1') {\n                    H(u, v) = H(v, u) = 1.0;\n                    h_deg[u]++;\n                    h_deg[v]++;\n                }\n            }\n        }\n        \n        sort(h_deg.begin(), h_deg.end());\n        \n        // Compute eigenvalues\n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(H);\n        Eigen::VectorXd h_eig = solver.eigenvalues();\n        sort(h_eig.data(), h_eig.data() + N, greater<double>());\n        \n        // Find best match using weighted combination of degree and spectral distance\n        int best_idx = 0;\n        double min_score = 1e300;\n        \n        for (int i = 0; i < M; ++i) {\n            // L2 distance between sorted degree sequences (normalized)\n            double deg_dist = 0.0;\n            for (int j = 0; j < N; ++j) {\n                double diff = ref_degs[i][j] - h_deg[j];\n                deg_dist += diff * diff;\n            }\n            deg_dist = sqrt(deg_dist) / N;\n            \n            // L2 distance between eigenvalues (normalized)\n            double eig_dist = (ref_eigs[i] - h_eig).norm() / N;\n            \n            // Weight: rely more on degrees for high epsilon, more on eigenvalues for low epsilon\n            double weight_deg = 0.7 + 0.2 * eps;  // 0.7 to 0.78\n            double weight_eig = 1.0 - weight_deg;\n            \n            double total_score = weight_deg * deg_dist + weight_eig * eig_dist;\n            \n            if (total_score < min_score) {\n                min_score = total_score;\n                best_idx = i;\n            }\n        }\n        \n        cout << best_idx << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    const long long INF = (long long)1e12;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Compute all-pairs shortest paths (original graph)\n    vector<vector<long long>> orig_dist(N, vector<long long>(N, INF));\n    for (int s = 0; s < N; s++) {\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        orig_dist[s][s] = 0;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != orig_dist[s][u]) continue;\n            for (auto [v, eid] : adj[u]) {\n                int w = edges[eid].w;\n                if (orig_dist[s][v] > d + w) {\n                    orig_dist[s][v] = d + w;\n                    pq.push({orig_dist[s][v], v});\n                }\n            }\n        }\n    }\n    \n    // Compute edge criticality: expected distance increase when this edge is removed\n    vector<double> crit(M, 0.0);\n    const int CRIT_SAMPLES = 200;\n    \n    for (int iter = 0; iter < CRIT_SAMPLES; iter++) {\n        int s = rng() % N;\n        \n        // Dijkstra from s without each edge (one at a time)\n        // Actually, compute all distances from s once, then check which edges are critical\n        vector<long long> base_dist = orig_dist[s];\n        \n        for (int eid = 0; eid < M; eid++) {\n            int u = edges[eid].u, v = edges[eid].v, w = edges[eid].w;\n            // If this edge is on a shortest path from s\n            if (base_dist[u] + w == base_dist[v] || base_dist[v] + w == base_dist[u]) {\n                // It's potentially critical - but we need to know if there's an alternative\n                // For now, just count it. Later we can do better.\n                crit[eid] += 1.0;\n            }\n        }\n    }\n    \n    // Normalize\n    double max_crit = *max_element(crit.begin(), crit.end());\n    if (max_crit > 0) {\n        for (int i = 0; i < M; i++) crit[i] /= max_crit;\n    }\n    \n    // Build adjacency (distance 1 only)\n    vector<vector<int>> edge_adj(M);\n    vector<vector<int>> vertex_edges(N);\n    for (int i = 0; i < M; i++) {\n        vertex_edges[edges[i].u].push_back(i);\n        vertex_edges[edges[i].v].push_back(i);\n    }\n    for (int i = 0; i < M; i++) {\n        unordered_set<int> neigh;\n        for (int v : {edges[i].u, edges[i].v}) {\n            for (int e : vertex_edges[v]) {\n                if (e != i) neigh.insert(e);\n            }\n        }\n        edge_adj[i] = vector<int>(neigh.begin(), neigh.end());\n    }\n    \n    // Initial greedy assignment\n    vector<int> assign(M, -1);\n    vector<vector<int>> day_edges(D);\n    vector<double> day_crit(D, 0.0);\n    vector<int> day_adj(D, 0);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return crit[a] > crit[b];\n    });\n    \n    for (int eid : order) {\n        int best_day = -1;\n        double best_score = 1e300;\n        for (int d = 0; d < D; d++) {\n            if ((int)day_edges[d].size() >= K) continue;\n            double new_crit = day_crit[d] + crit[eid];\n            int adj_cnt = 0;\n            for (int other : edge_adj[eid]) {\n                if (assign[other] == d) adj_cnt++;\n            }\n            // Score: penalize variance in criticality and local clustering\n            double score = new_crit * new_crit + 2.0 * adj_cnt;\n            if (score < best_score) {\n                best_score = score;\n                best_day = d;\n            }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if ((int)day_edges[d].size() < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n        }\n        assign[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_crit[best_day] += crit[eid];\n        for (int other : edge_adj[eid]) {\n            if (assign[other] == best_day) day_adj[best_day]++;\n        }\n    }\n    \n    // Simulated Annealing\n    auto compute_day_score = [&](int d) -> double {\n        return day_crit[d] * day_crit[d] + 2.0 * day_adj[d];\n    };\n    \n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 5.5;\n    \n    double T = 100.0;\n    const double cooling = 0.99997;\n    int iterations = 0;\n    int accepted = 0;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        iterations++;\n        \n        // Pick two random edges from different days\n        int e1 = rng() % M;\n        int d1 = assign[e1];\n        int e2, d2;\n        int attempts = 0;\n        do {\n            e2 = rng() % M;\n            d2 = assign[e2];\n            attempts++;\n        } while (d1 == d2 && attempts < 5);\n        if (d1 == d2) continue;\n        \n        double old_score = compute_day_score(d1) + compute_day_score(d2);\n        \n        // Calculate new state after swap\n        double new_crit1 = day_crit[d1] - crit[e1] + crit[e2];\n        double new_crit2 = day_crit[d2] - crit[e2] + crit[e1];\n        \n        // Calculate new adjacencies\n        int new_adj1 = day_adj[d1];\n        int new_adj2 = day_adj[d2];\n        \n        // Remove e1 from d1\n        for (int other : edge_adj[e1]) {\n            if (other != e2 && assign[other] == d1) new_adj1--;\n        }\n        // Remove e2 from d2\n        for (int other : edge_adj[e2]) {\n            if (other != e1 && assign[other] == d2) new_adj2--;\n        }\n        // Add e2 to d1\n        for (int other : edge_adj[e2]) {\n            if (other != e1 && assign[other] == d1) new_adj1++;\n        }\n        // Add e1 to d2\n        for (int other : edge_adj[e1]) {\n            if (other != e2 && assign[other] == d2) new_adj2++;\n        }\n        \n        double new_score = new_crit1 * new_crit1 + 2.0 * new_adj1 + new_crit2 * new_crit2 + 2.0 * new_adj2;\n        double delta = new_score - old_score;\n        \n        if (delta < 0 || (T > 0.01 && uniform_real_distribution<double>(0, 1)(rng) < exp(-delta / T))) {\n            // Accept\n            auto it1 = find(day_edges[d1].begin(), day_edges[d1].end(), e1);\n            auto it2 = find(day_edges[d2].begin(), day_edges[d2].end(), e2);\n            if (it1 != day_edges[d1].end() && it2 != day_edges[d2].end()) {\n                *it1 = e2;\n                *it2 = e1;\n                assign[e1] = d2;\n                assign[e2] = d1;\n                day_crit[d1] = new_crit1;\n                day_crit[d2] = new_crit2;\n                day_adj[d1] = new_adj1;\n                day_adj[d2] = new_adj2;\n                accepted++;\n            }\n        }\n        \n        T *= cooling;\n    }\n    \n    // Verify and fix constraints\n    for (int d = 0; d < D; d++) {\n        while ((int)day_edges[d].size() > K) {\n            int e = day_edges[d].back();\n            day_edges[d].pop_back();\n            for (int d2 = 0; d2 < D; d2++) {\n                if ((int)day_edges[d2].size() < K) {\n                    day_edges[d2].push_back(e);\n                    assign[e] = d2;\n                    break;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << assign[i] + 1;\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<array<array<int,3>,3>> rotations;\n\nvoid init_rotations() {\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int parity[6] = {1, -1, -1, 1, 1, -1};\n    for (int p=0; p<6; p++) {\n        for (int sx : {1, -1}) {\n            for (int sy : {1, -1}) {\n                for (int sz : {1, -1}) {\n                    if (sx * sy * sz * parity[p] == 1) {\n                        array<array<int,3>,3> mat = {};\n                        mat[0][perms[p][0]] = sx;\n                        mat[1][perms[p][1]] = sy;\n                        mat[2][perms[p][2]] = sz;\n                        rotations.push_back(mat);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvector<array<int,3>> normalize_shape(vector<array<int,3>> cells) {\n    if (cells.empty()) return cells;\n    int minx = 1e9, miny = 1e9, minz = 1e9;\n    for (auto& c : cells) {\n        minx = min(minx, c[0]);\n        miny = min(miny, c[1]);\n        minz = min(minz, c[2]);\n    }\n    for (auto& c : cells) {\n        c[0] -= minx;\n        c[1] -= miny;\n        c[2] -= minz;\n    }\n    vector<vector<array<int,3>>> candidates;\n    for (auto& rot : rotations) {\n        vector<array<int,3>> cur;\n        for (auto& c : cells) {\n            int x = c[0], y = c[1], z = c[2];\n            int nx = rot[0][0]*x + rot[0][1]*y + rot[0][2]*z;\n            int ny = rot[1][0]*x + rot[1][1]*y + rot[1][2]*z;\n            int nz = rot[2][0]*x + rot[2][1]*y + rot[2][2]*z;\n            cur.push_back({nx, ny, nz});\n        }\n        int mix = 1e9, miy = 1e9, miz = 1e9;\n        for (auto& c : cur) {\n            mix = min(mix, c[0]);\n            miy = min(miy, c[1]);\n            miz = min(miz, c[2]);\n        }\n        for (auto& c : cur) {\n            c[0] -= mix;\n            c[1] -= miy;\n            c[2] -= miz;\n        }\n        sort(cur.begin(), cur.end());\n        candidates.push_back(cur);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\nstruct Component {\n    vector<array<int,3>> cells;\n    vector<array<int,3>> shape;\n    int id;\n};\n\nvector<Component> extract_components(const vector<vector<vector<bool>>>& valid) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<Component> comps;\n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid[x][y][z] && !vis[x][y][z]) {\n                    Component comp;\n                    queue<array<int,3>> q;\n                    q.push({x,y,z});\n                    vis[x][y][z] = true;\n                    while (!q.empty()) {\n                        auto cur = q.front(); q.pop();\n                        comp.cells.push_back(cur);\n                        int cx=cur[0], cy=cur[1], cz=cur[2];\n                        for (int dir=0; dir<6; dir++) {\n                            int nx=cx+dx[dir], ny=cy+dy[dir], nz=cz+dz[dir];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && valid[nx][ny][nz] && !vis[nx][ny][nz]) {\n                                vis[nx][ny][nz] = true;\n                                q.push({nx,ny,nz});\n                            }\n                        }\n                    }\n                    comp.shape = normalize_shape(comp.cells);\n                    comps.push_back(comp);\n                }\n            }\n        }\n    }\n    return comps;\n}\n\n// Improved reduction: prioritize removing leaf nodes to preserve connectivity\nvoid reduce_set_improved(vector<vector<vector<bool>>>& cells, \n                const vector<vector<vector<bool>>>& base,\n                const vector<string>& f, const vector<string>& r) {\n    vector<vector<int>> front(D, vector<int>(D, 0));\n    vector<vector<int>> right(D, vector<int>(D, 0));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (base[x][y][z] || cells[x][y][z]) {\n                    front[z][x]++;\n                    right[z][y]++;\n                }\n            }\n        }\n    }\n    \n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    // Compute initial degrees\n    vector<vector<vector<int>>> degree(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (!cells[x][y][z]) continue;\n                for (int dir=0; dir<6; dir++) {\n                    int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                    if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz])\n                        degree[x][y][z]++;\n                }\n            }\n        }\n    }\n    \n    // Priority: degree (lower first), prefer leaves\n    using T = tuple<int, int, int, int>; // degree, x, y, z\n    priority_queue<T, vector<T>, greater<T>> pq;\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (cells[x][y][z] && front[z][x] > 1 && right[z][y] > 1) {\n                    pq.push({degree[x][y][z], x, y, z});\n                }\n            }\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [d, x, y, z] = pq.top(); pq.pop();\n        if (!cells[x][y][z]) continue;\n        if (front[z][x] <= 1 || right[z][y] <= 1) continue;\n        \n        // Remove the cell\n        cells[x][y][z] = false;\n        front[z][x]--;\n        right[z][y]--;\n        \n        // Update neighbors\n        for (int dir=0; dir<6; dir++) {\n            int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz]) {\n                degree[nx][ny][nz]--;\n                if (front[nz][nx] > 1 && right[nz][ny] > 1) {\n                    pq.push({degree[nx][ny][nz], nx, ny, nz});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotations();\n    \n    cin >> D;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i=0; i<2; i++) {\n        for (int j=0; j<D; j++) cin >> f[i][j];\n        for (int j=0; j<D; j++) cin >> r[i][j];\n    }\n    \n    vector<vector<vector<bool>>> P1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> P2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1') P1[x][y][z] = true;\n                if (f[1][z][x] == '1' && r[1][z][y] == '1') P2[x][y][z] = true;\n            }\n        }\n    }\n    \n    vector<vector<vector<bool>>> C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (P1[x][y][z] && P2[x][y][z]) C[x][y][z] = true;\n                else if (P1[x][y][z]) R1[x][y][z] = true;\n                else if (P2[x][y][z]) R2[x][y][z] = true;\n            }\n        }\n    }\n    \n    reduce_set_improved(R1, C, f[0], r[0]);\n    reduce_set_improved(R2, C, f[1], r[1]);\n    \n    auto compsC = extract_components(C);\n    auto compsR1 = extract_components(R1);\n    auto compsR2 = extract_components(R2);\n    \n    int n = 0;\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto idx = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n    \n    for (auto& comp : compsC) {\n        n++;\n        for (auto& c : comp.cells) {\n            b1[idx(c[0], c[1], c[2])] = n;\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    map<vector<array<int,3>>, vector<Component*>> shape_map;\n    for (auto& comp : compsR1) {\n        shape_map[comp.shape].push_back(&comp);\n    }\n    \n    vector<Component*> unmatched_R2;\n    for (auto& comp : compsR2) {\n        auto& vec = shape_map[comp.shape];\n        if (!vec.empty()) {\n            Component* c1 = vec.back();\n            vec.pop_back();\n            n++;\n            for (auto& c : c1->cells) b1[idx(c[0], c[1], c[2])] = n;\n            for (auto& c : comp.cells) b2[idx(c[0], c[1], c[2])] = n;\n        } else {\n            unmatched_R2.push_back(&comp);\n        }\n    }\n    \n    for (auto& [shape, vec] : shape_map) {\n        for (auto* comp : vec) {\n            n++;\n            for (auto& c : comp->cells) b1[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    for (auto* comp : unmatched_R2) {\n        n++;\n        for (auto& c : comp->cells) b2[idx(c[0], c[1], c[2])] = n;\n    }\n    \n    cout << n << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b2[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {int x, y;};\nstruct Edge{int u, v; int w;};\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    void unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a!=b) p[a]=b;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<Point> V(N);\n    for(int i=0;i<N;i++) cin>>V[i].x>>V[i].y;\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++) {\n        int u,v,w;\n        cin>>u>>v>>w;\n        u--; v--;\n        edges[i] = {u,v,w};\n        adj[u].push_back({v,i});\n        adj[v].push_back({u,i});\n    }\n    vector<Point> R(K);\n    for(int i=0;i<K;i++) cin>>R[i].x>>R[i].y;\n    \n    const int COVER_DIST2 = 5000*5000;\n    const long long INF = (1LL<<60);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Precompute shortest paths between vertices (Dijkstra from each)\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    vector<vector<int>> parent_edge(N, vector<int>(N, -1));\n    \n    for(int s=0; s<N; s++) {\n        distV[s][s] = 0;\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u] = pq.top(); pq.pop();\n            if(d!=distV[s][u]) continue;\n            for(auto [v,eid]: adj[u]){\n                long long nd = d + edges[eid].w;\n                if(nd < distV[s][v]){\n                    distV[s][v] = nd;\n                    parent_edge[s][v] = eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // Precompute resident-vertex distances and required P\n    vector<vector<int>> resVdist2(K, vector<int>(N));\n    vector<vector<int>> needP(K, vector<int>(N));\n    for(int i=0;i<K;i++){\n        for(int j=0;j<N;j++){\n            long long dx = (long long)R[i].x - V[j].x;\n            long long dy = (long long)R[i].y - V[j].y;\n            int d2 = (int)(dx*dx + dy*dy);\n            resVdist2[i][j] = d2;\n            needP[i][j] = (int)ceil(sqrt((double)d2) - 1e-9);\n        }\n    }\n    \n    // Fast cost evaluation\n    auto evaluate = [&](const vector<int>& S, vector<int>& assign_out)->pair<long long,bool>{\n        int sz = (int)S.size();\n        if(sz==0) return {INF,false};\n        vector<int> maxP(N,0);\n        assign_out.assign(K,-1);\n        \n        for(int r=0;r<K;r++){\n            int bestv = -1, bestd2 = COVER_DIST2+1;\n            for(int v: S){\n                if(resVdist2[r][v] < bestd2){\n                    bestd2 = resVdist2[r][v];\n                    bestv = v;\n                }\n            }\n            if(bestv==-1 || bestd2 > COVER_DIST2) return {INF,false};\n            assign_out[r] = bestv;\n            maxP[bestv] = max(maxP[bestv], needP[r][bestv]);\n        }\n        \n        long long fac_cost = 0;\n        for(int v: S) fac_cost += 1LL*maxP[v]*maxP[v];\n        \n        // MST on metric closure (Prim's algorithm)\n        long long tree_cost = 0;\n        if(sz > 1){\n            vector<long long> min_dist(sz, INF);\n            vector<bool> used(sz, false);\n            min_dist[0] = 0;\n            for(int iter=0; iter<sz; iter++){\n                int v = -1;\n                for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_dist[i]<min_dist[v])) v=i;\n                if(v==-1 || min_dist[v]==INF) return {INF,false};\n                used[v] = true;\n                tree_cost += min_dist[v];\n                for(int i=0;i<sz;i++) if(!used[i]){\n                    long long d = distV[S[v]][S[i]];\n                    if(d < min_dist[i]) min_dist[i] = d;\n                }\n            }\n        }\n        return {tree_cost + fac_cost, true};\n    };\n    \n    // Precompute which residents each vertex can cover\n    vector<vector<int>> covResidents(N);\n    for(int v=0;v<N;v++){\n        for(int r=0;r<K;r++){\n            if(resVdist2[r][v] <= COVER_DIST2) covResidents[v].push_back(r);\n        }\n    }\n    \n    // Greedy initial solution\n    vector<int> S;\n    vector<bool> inS(N,false);\n    S.push_back(0);\n    inS[0] = true;\n    vector<bool> covered(K,false);\n    \n    while(true){\n        bool all = true;\n        for(bool c: covered) if(!c){all=false; break;}\n        if(all) break;\n        \n        int bestv = -1;\n        double best_score = -1.0;\n        \n        for(int v=0; v<N; v++) if(!inS[v]){\n            int newly = 0, max_need = 0;\n            for(int r: covResidents[v]) if(!covered[r]){\n                newly++;\n                max_need = max(max_need, needP[r][v]);\n            }\n            if(newly==0) continue;\n            long long conn = INF;\n            for(int u: S) conn = min(conn, distV[u][v]);\n            long long total_cost = conn + 1LL*max_need*max_need;\n            double score = (double)newly / (double)total_cost;\n            if(score > best_score){\n                best_score = score;\n                bestv = v;\n            }\n        }\n        \n        if(bestv==-1) break;\n        inS[bestv] = true;\n        S.push_back(bestv);\n        for(int r: covResidents[bestv]) covered[r] = true;\n    }\n    \n    // Ensure coverage\n    for(int r=0;r<K;r++){\n        bool ok=false;\n        for(int v: S) if(resVdist2[r][v]<=COVER_DIST2){ok=true; break;}\n        if(!ok){\n            int bestv=-1, bestd2=COVER_DIST2+1;\n            for(int v=0;v<N;v++) if(!inS[v] && resVdist2[r][v]<bestd2){\n                bestd2=resVdist2[r][v]; bestv=v;\n            }\n            if(bestv!=-1){\n                inS[bestv]=true;\n                S.push_back(bestv);\n            }\n        }\n    }\n    \n    // Simulated Annealing\n    vector<int> bestS = S;\n    vector<int> cur_assign;\n    auto [best_cost, _] = evaluate(S, cur_assign);\n    long long cur_cost = best_cost;\n    \n    double T = (double)cur_cost * 0.1; // Initial temperature\n    const double T_min = 1.0;\n    const double alpha = 0.999;\n    const int ITERATIONS = 5000;\n    \n    for(int iter=0; iter<ITERATIONS && T > T_min; iter++){\n        vector<int> newS = S;\n        bool is_add = false;\n        int removed_v = -1, added_v = -1;\n        \n        // Generate neighbor\n        if(rng() % 2 == 0 && S.size() < N){\n            // Add random vertex\n            vector<int> not_in_S;\n            for(int v=0;v<N;v++) if(!inS[v]) not_in_S.push_back(v);\n            if(!not_in_S.empty()){\n                int v = not_in_S[rng() % not_in_S.size()];\n                newS.push_back(v);\n                inS[v] = true;\n                added_v = v;\n                is_add = true;\n            }\n        } else if(S.size() > 1){\n            // Remove random vertex (not 0)\n            vector<int> candidates;\n            for(int v: S) if(v!=0) candidates.push_back(v);\n            if(!candidates.empty()){\n                int v = candidates[rng() % candidates.size()];\n                inS[v] = false;\n                newS.erase(remove(newS.begin(), newS.end(), v), newS.end());\n                removed_v = v;\n            }\n        }\n        \n        if(newS == S){\n            T *= alpha;\n            continue;\n        }\n        \n        vector<int> new_assign;\n        auto [new_cost, feasible] = evaluate(newS, new_assign);\n        \n        if(feasible){\n            long long delta = new_cost - cur_cost;\n            bool accept = false;\n            if(delta < 0) accept = true;\n            else{\n                double prob = exp(-(double)delta / T);\n                if((double)(rng() % 10000) / 10000.0 < prob) accept = true;\n            }\n            \n            if(accept){\n                S = newS;\n                cur_cost = new_cost;\n                cur_assign = new_assign;\n                if(cur_cost < best_cost){\n                    best_cost = cur_cost;\n                    bestS = S;\n                }\n            } else {\n                // Revert inS\n                if(is_add && added_v!=-1) inS[added_v] = false;\n                else if(removed_v!=-1) inS[removed_v] = true;\n            }\n        } else {\n            // Revert inS\n            if(is_add && added_v!=-1) inS[added_v] = false;\n            else if(removed_v!=-1) inS[removed_v] = true;\n        }\n        \n        T *= alpha;\n    }\n    \n    S = bestS;\n    fill(inS.begin(), inS.end(), false);\n    for(int v: S) inS[v] = true;\n    \n    // Final local search (hill climbing)\n    bool improved = true;\n    while(improved){\n        improved = false;\n        // Try removes\n        for(size_t i=0;i<S.size();i++){\n            if(S[i]==0) continue;\n            vector<int> testS = S;\n            testS.erase(testS.begin()+i);\n            vector<int> tmp;\n            auto [c,f] = evaluate(testS, tmp);\n            if(f && c < best_cost){\n                best_cost = c;\n                S = testS;\n                inS[S[i]] = false;\n                improved = true;\n                break;\n            }\n        }\n        if(improved) continue;\n        // Try adds\n        for(int v=0;v<N;v++) if(!inS[v]){\n            vector<int> testS = S;\n            testS.push_back(v);\n            vector<int> tmp;\n            auto [c,f] = evaluate(testS, tmp);\n            if(f && c < best_cost){\n                best_cost = c;\n                S = testS;\n                inS[v] = true;\n                improved = true;\n                break;\n            }\n        }\n    }\n    \n    // Build output\n    int sz = S.size();\n    vector<int> P(N,0);\n    vector<int> final_assign;\n    evaluate(S, final_assign); // Get final assignment\n    \n    for(int r=0;r<K;r++){\n        int v = final_assign[r];\n        P[v] = max(P[v], needP[r][v]);\n    }\n    \n    // Build tree via MST on metric closure then map to actual edges\n    vector<int> B(M,0);\n    if(sz > 1){\n        // Prim on S to get metric MST structure\n        vector<long long> min_edge(sz, INF);\n        vector<bool> used(sz, false);\n        vector<int> parent_idx(sz, -1);\n        min_edge[0] = 0;\n        \n        for(int iter=0; iter<sz; iter++){\n            int v = -1;\n            for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_edge[i]<min_edge[v])) v=i;\n            used[v] = true;\n            for(int i=0;i<sz;i++) if(!used[i]){\n                long long d = distV[S[v]][S[i]];\n                if(d < min_edge[i]){\n                    min_edge[i] = d;\n                    parent_idx[i] = v;\n                }\n            }\n        }\n        \n        // Activate edges from shortest paths\n        vector<bool> edge_active(M, false);\n        for(int i=1;i<sz;i++){\n            int u = S[parent_idx[i]];\n            int v = S[i];\n            int cur = v;\n            while(cur != u){\n                int e = parent_edge[u][cur];\n                if(e==-1) break;\n                edge_active[e] = true;\n                int pu = edges[e].u == cur ? edges[e].v : edges[e].u;\n                cur = pu;\n            }\n        }\n        \n        // Kruskal on activated edges\n        vector<int> active_edges;\n        for(int i=0;i<M;i++) if(edge_active[i]) active_edges.push_back(i);\n        sort(active_edges.begin(), active_edges.end(), [&](int a, int b){return edges[a].w < edges[b].w;});\n        \n        DSU dsu(N);\n        for(int e: active_edges){\n            int u=edges[e].u, v=edges[e].v;\n            if(dsu.find(u)!=dsu.find(v)){\n                dsu.unite(u,v);\n                B[e]=1;\n            }\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int i=0;i<M;i++){\n        if(i) cout << ' ';\n        cout << B[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\n// Hungarian algorithm for minimization, n workers, m jobs (n <= m)\n// Returns pair(min_cost, assignment) where assignment[i] = job assigned to worker i\npair<int, vector<int>> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i = 1; i <= n; ++i) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= m; ++j) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j = 0; j <= m; ++j) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        \n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> assignment(n);\n    for (int j = 1; j <= m; ++j) {\n        if (p[j] != 0) {\n            assignment[p[j]-1] = j-1;\n        }\n    }\n    return {-v[0], assignment};\n}\n\nint calc_dist(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    return max({abs(dx), abs(dy), abs(dx - dy)});\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    const int BALLS = N * (N + 1) / 2;\n    \n    vector<vector<int>> init_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> init_pos(BALLS);\n    \n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v; \n            cin >> v;\n            init_grid[x][y] = v;\n            init_pos[v] = {x, y};\n        }\n    }\n    \n    // Determine optimal target assignment using Hungarian per row\n    vector<vector<int>> target_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> target_pos(BALLS); // where each value should go\n    \n    for (int x = 0; x < N; ++x) {\n        int m = x + 1;\n        int start = x * (x + 1) / 2;\n        \n        // Cost matrix: cost[i][j] = distance from initial pos of value (start+i) to cell (x,j)\n        vector<vector<int>> cost(m, vector<int>(m));\n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            auto [vx, vy] = init_pos[v];\n            for (int j = 0; j < m; ++j) {\n                cost[i][j] = calc_dist(vx, vy, x, j);\n            }\n        }\n        \n        auto [min_cost, assignment] = hungarian(cost);\n        // assignment[i] = column j where value (start+i) should go\n        \n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            int y = assignment[i];\n            target_grid[x][y] = v;\n            target_pos[v] = {x, y};\n        }\n    }\n    \n    // Routing phase: bottom-up greedy swapping\n    vector<vector<int>> cur_grid = init_grid;\n    vector<pair<int,int>> cur_pos = init_pos;\n    vector<array<int,4>> ops;\n    \n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = x; y >= 0; --y) {\n            int target_val = target_grid[x][y];\n            auto [cx, cy] = cur_pos[target_val];\n            \n            while (cx != x || cy != y) {\n                int nx, ny;\n                if (cx < x) {\n                    if (cy > y) {\n                        nx = cx; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx + 1; ny = cy + 1;\n                    } else {\n                        nx = cx + 1; ny = cy;\n                    }\n                } else if (cx > x) {\n                    if (cy > y) {\n                        nx = cx - 1; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx - 1; ny = cy;\n                    } else {\n                        nx = cx - 1; ny = cy;\n                    }\n                } else {\n                    if (cy < y) {\n                        nx = cx; ny = cy + 1;\n                    } else {\n                        nx = cx; ny = cy - 1;\n                    }\n                }\n                \n                int v1 = cur_grid[cx][cy];\n                int v2 = cur_grid[nx][ny];\n                \n                swap(cur_grid[cx][cy], cur_grid[nx][ny]);\n                cur_pos[v1] = {nx, ny};\n                cur_pos[v2] = {cx, cy};\n                ops.push_back({cx, cy, nx, ny});\n                \n                cx = nx; cy = ny;\n            }\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto &op : ops) {\n        cout << op[0] << ' ' << op[1] << ' ' << op[2] << ' ' << op[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    \n    const int si = 0, sj = (D - 1) / 2;\n    const int M = D * D - 1 - N;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // BFS to compute distances from entrance (for heuristic)\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (dist[ni][nj] != -1) continue;\n            dist[ni][nj] = dist[i][j] + 1;\n            q.push({ni, nj});\n        }\n    }\n    \n    // Collect valid cells and sort by distance descending\n    // (far cells first, close cells last)\n    vector<pair<int, int>> cells;\n    cells.reserve(M);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == si && j == sj) continue;\n            if (obstacle[i][j]) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](const auto &a, const auto &b) {\n        return dist[a.first][a.second] > dist[b.first][b.second];\n    });\n    \n    // Map from cell to its index in sorted order\n    map<pair<int, int>, int> cell_to_idx;\n    for (int i = 0; i < cells.size(); i++) {\n        cell_to_idx[cells[i]] = i;\n    }\n    \n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    vector<vector<int>> value_at(D, vector<int>(D, -1));\n    \n    // Helper: check if removing cell (ri, rj) keeps all empty cells connected to entrance\n    auto is_safe = [&](int ri, int rj) -> bool {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        vis[si][sj] = true;\n        qq.push({si, sj});\n        int reachable_count = 1;\n        \n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (ni == ri && nj == rj) continue; // Pretend this cell is blocked\n                if (vis[ni][nj]) continue;\n                vis[ni][nj] = true;\n                reachable_count++;\n                qq.push({ni, nj});\n            }\n        }\n        \n        // Count total empty cells (excluding the one we're testing)\n        int total_empty = 1; // entrance\n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == si && j == sj) continue;\n                if (obstacle[i][j]) continue;\n                if (occupied[i][j]) continue;\n                if (i == ri && j == rj) continue;\n                total_empty++;\n            }\n        }\n        \n        return reachable_count == total_empty;\n    };\n    \n    // Placement phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        \n        // Target: small t should be near entrance (end of cells list)\n        // Large t should be far from entrance (beginning of cells list)\n        int target_idx = M - 1 - t;\n        \n        // Compute current reachable cells\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        reachable[si][sj] = true;\n        qq.push({si, sj});\n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (reachable[ni][nj]) continue;\n                reachable[ni][nj] = true;\n                qq.push({ni, nj});\n            }\n        }\n        \n        pair<int, int> chosen = {-1, -1};\n        int best_diff = M + 1;\n        \n        // Find safe reachable cell closest to target position\n        for (int idx = 0; idx < M; idx++) {\n            auto [i, j] = cells[idx];\n            if (occupied[i][j]) continue;\n            if (!reachable[i][j]) continue;\n            \n            // Check safety: removing this cell should not disconnect the graph\n            if (!is_safe(i, j)) continue;\n            \n            int diff = abs(idx - target_idx);\n            if (diff < best_diff) {\n                best_diff = diff;\n                chosen = {i, j};\n            }\n        }\n        \n        // If no safe cell found, try without safety check (should not happen with valid input)\n        if (chosen.first == -1) {\n            for (int idx = 0; idx < M; idx++) {\n                auto [i, j] = cells[idx];\n                if (occupied[i][j]) continue;\n                if (!reachable[i][j]) continue;\n                int diff = abs(idx - target_idx);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    chosen = {i, j};\n                }\n            }\n        }\n        \n        // Last resort: any reachable cell\n        if (chosen.first == -1) {\n            for (auto [i, j] : cells) {\n                if (!occupied[i][j] && reachable[i][j]) {\n                    chosen = {i, j};\n                    break;\n                }\n            }\n        }\n        \n        occupied[chosen.first][chosen.second] = true;\n        value_at[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << \"\\n\";\n        cout.flush();\n    }\n    \n    // Retrieval phase: always take smallest available value\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[si][sj] = true;\n    \n    using P = pair<int, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    \n    // Helper to add neighbors of (i,j) to PQ\n    auto add_neighbors = [&](int i, int j) {\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (is_empty[ni][nj]) continue;\n            if (value_at[ni][nj] == -1) continue; // No container\n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    };\n    \n    // Initialize with cells adjacent to entrance\n    add_neighbors(si, sj);\n    \n    vector<pair<int, int>> retrieval;\n    retrieval.reserve(M);\n    \n    while ((int)retrieval.size() < M) {\n        if (pq.empty()) {\n            // This should not happen if placement was correct\n            break;\n        }\n        auto [val, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (is_empty[i][j]) continue; // Already retrieved\n        \n        is_empty[i][j] = true;\n        retrieval.push_back(pos);\n        add_neighbors(i, j);\n    }\n    \n    for (auto [i, j] : retrieval) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc024":"","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    vector<double> score(N, 1.0);  // Estimated weight for each item\n    vector<int> belong(N, 0);      // Current group assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    auto do_query = [&](const vector<int>& L, const vector<int>& R) -> char {\n        cout << L.size() << \" \" << R.size();\n        for (int x : L) cout << \" \" << x;\n        for (int x : R) cout << \" \" << x;\n        cout << endl;\n        char res;\n        cin >> res;\n        return res;\n    };\n    \n    // Determine query budget for each phase\n    // Phase 1: Estimate weights via pairwise comparisons\n    // Phase 3: Refine partition by comparing groups and swapping\n    int refine_budget = 0;\n    if (Q > 150) {\n        refine_budget = min(Q / 3, 600);  // Reserve up to 1/3 or 600 for refinement\n    }\n    int phase1_budget = Q - refine_budget;\n    \n    // Phase 1: Pairwise comparisons to estimate relative weights\n    // First, ensure every item is compared at least once (connectivity)\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; i++) {\n        pairs.emplace_back(i, (i + 1) % N);\n    }\n    // Add random pairs for remaining budget\n    while ((int)pairs.size() < phase1_budget) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a != b) {\n            if (a > b) swap(a, b);\n            pairs.emplace_back(a, b);\n        }\n    }\n    shuffle(pairs.begin(), pairs.end(), rng);\n    \n    for (int q = 0; q < phase1_budget && q < (int)pairs.size(); q++) {\n        auto [a, b] = pairs[q];\n        char res = do_query({a}, {b});\n        const double delta = 1.0;\n        if (res == '>') {\n            score[a] += delta;\n            score[b] -= delta;\n        } else if (res == '<') {\n            score[a] -= delta;\n            score[b] += delta;\n        }\n    }\n    \n    // Normalize scores to positive values\n    double min_score = *min_element(score.begin(), score.end());\n    for (double& s : score) {\n        s = s - min_score + 1.0;\n    }\n    \n    // Phase 2: Initial partition using LPT (Longest Processing Time) rule\n    // Sort items by estimated weight descending\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    vector<double> group_sum(D, 0.0);\n    for (int idx : items) {\n        // Assign to the currently lightest group\n        int best_g = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_g]) best_g = g;\n        }\n        belong[idx] = best_g;\n        group_sum[best_g] += score[idx];\n    }\n    \n    // Phase 3: Refinement using remaining queries\n    // Compare heavy vs light groups and swap items to balance\n    for (int q = phase1_budget; q < Q; q++) {\n        // Find currently heaviest and lightest groups by estimate\n        int heavy_g = max_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        int light_g = min_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        \n        if (heavy_g == light_g) break;  // Already balanced\n        \n        // Collect items in these groups\n        vector<int> heavy_items, light_items;\n        for (int i = 0; i < N; i++) {\n            if (belong[i] == heavy_g) heavy_items.push_back(i);\n            else if (belong[i] == light_g) light_items.push_back(i);\n        }\n        \n        if (heavy_items.empty() || light_items.empty()) continue;\n        \n        // Pick candidate items: heaviest in heavy group, lightest in light group\n        int h_item = *max_element(heavy_items.begin(), heavy_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        int l_item = *min_element(light_items.begin(), light_items.end(),\n            [&](int a, int b) { return score[a] < score[b]; });\n        \n        // Compare the two groups to check actual imbalance direction\n        char res = do_query(heavy_items, light_items);\n        \n        // Also update individual scores based on group comparison (small adjustment)\n        const double eps = 0.1;\n        if (res == '>') {\n            // Heavy group is indeed heavier\n            for (int x : heavy_items) score[x] += eps;\n            for (int x : light_items) score[x] -= eps;\n            \n            // Swap heaviest from heavy with lightest from light\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else if (res == '<') {\n            // Opposite of estimate: light group is actually heavier\n            for (int x : heavy_items) score[x] -= eps;\n            for (int x : light_items) score[x] += eps;\n            \n            // Swap in opposite direction (move \"light\" from heavy to light, \"heavy\" from light to heavy)\n            // Actually, swap the candidates we picked (which might be wrong, but let's swap anyway to fix)\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        } else {\n            // Equal, do a random beneficial swap or nothing\n            // Swap to explore\n            belong[h_item] = light_g;\n            belong[l_item] = heavy_g;\n            group_sum[heavy_g] += score[l_item] - score[h_item];\n            group_sum[light_g] += score[h_item] - score[l_item];\n        }\n    }\n    \n    // Output final partition\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << belong[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> st(m);\n    vector<int> pos(n + 1); // pos[v] = which stack (0-indexed) contains v\n    \n    for (int i = 0; i < m; ++i) {\n        int h = n / m;\n        for (int j = 0; j < h; ++j) {\n            int x; \n            cin >> x;\n            st[i].push_back(x);\n            pos[x] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops; // (v, i). i=0 for removal, else 1-indexed destination stack\n    \n    for (int target = 1; target <= n; ++target) {\n        int s = pos[target];\n        \n        // Find position of target in its stack\n        int idx = -1;\n        for (int i = 0; i < (int)st[s].size(); ++i) {\n            if (st[s][i] == target) {\n                idx = i;\n                break;\n            }\n        }\n        \n        // Move boxes above target until it becomes the top\n        while (idx < (int)st[s].size() - 1) {\n            int w = st[s].back(); // current top, will become top of moved segment\n            \n            int best_d = -1;\n            int min_valid_top = INT_MAX;\n            int max_top = -1;\n            \n            for (int d = 0; d < m; ++d) {\n                if (d == s) continue;\n                if (st[d].empty()) {\n                    best_d = d;          // empty is ideal\n                    break;\n                }\n                int top_d = st[d].back();\n                if (top_d > w) {         // valid: won't block existing top\n                    if (top_d < min_valid_top) {\n                        min_valid_top = top_d;\n                        best_d = d;\n                    }\n                }\n                if (top_d > max_top) {\n                    max_top = top_d;\n                }\n            }\n            \n            if (best_d == -1) {          // no empty and no valid top>w\n                for (int d = 0; d < m; ++d) {\n                    if (d == s) continue;\n                    if (st[d].back() == max_top) {\n                        best_d = d;\n                        break;\n                    }\n                }\n            }\n            \n            // The box immediately above target\n            int u = st[s][idx + 1];\n            \n            // Perform move: take suffix starting at idx+1\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            st[s].resize(idx + 1);\n            \n            for (int x : seg) pos[x] = best_d;\n            st[best_d].insert(st[best_d].end(), seg.begin(), seg.end());\n            \n            ops.emplace_back(u, best_d + 1); // convert to 1-indexed for output\n            // After this, target is at top of stack s (loop will exit)\n        }\n        \n        // Remove target (Operation 2)\n        st[s].pop_back();\n        ops.emplace_back(target, 0);\n    }\n    \n    for (auto [v, i] : ops) {\n        cout << v << ' ' << i << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n    \n    auto id = [&](int i, int j){ return i*N + j; };\n    int V = N*N;\n    vector<vector<pair<int,char>>> adj(V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n    const int rev[4] = {1,0,3,2};\n    \n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                bool ok = false;\n                if (dir == 0) { // up\n                    ok = h[ni][j] == '0';\n                } else if (dir == 1) { // down\n                    ok = h[i][j] == '0';\n                } else if (dir == 2) { // left\n                    ok = v[i][nj] == '0';\n                } else { // right\n                    ok = v[i][j] == '0';\n                }\n                if (ok) {\n                    adj[id(i,j)].push_back({id(ni,nj), dc[dir]});\n                }\n            }\n        }\n    }\n    \n    int root = 0;\n    vector<int> parent(V, -1);\n    vector<vector<int>> children(V);\n    vector<char> move_to_parent(V, 0);\n    {\n        queue<int> q;\n        q.push(root);\n        parent[root] = -2;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, c] : adj[u]) {\n                if (parent[v] == -1) {\n                    parent[v] = u;\n                    move_to_parent[v] = dc[rev[strchr(dc, c) - dc]];\n                    children[u].push_back(v);\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    // BFS order for top\u2011down, reverse for bottom\u2011up\n    vector<int> bfs_order;\n    bfs_order.reserve(V);\n    {\n        queue<int> q;\n        q.push(root);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            bfs_order.push_back(u);\n            for (int w : children[u]) q.push(w);\n        }\n    }\n    vector<int> rev_order = bfs_order;\n    reverse(rev_order.begin(), rev_order.end());\n    \n    vector<double> dval(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            dval[id(i,j)] = sqrt((double)d[i][j]);\n    \n    const long long LIM = 100000LL;\n    const int B = 3; // max excursions per slot\n    \n    vector<long long> k(V, 1);\n    \n    auto feasible = [&](double c)->bool {\n        for (int u : rev_order) {\n            if (u == root) continue;\n            long long sum_child = 0;\n            for (int w : children[u]) sum_child += k[w];\n            long long need = (sum_child + B - 1) / B; // ceil(sum/B)\n            long long kv = (long long)(c * dval[u]);\n            if (kv < 1) kv = 1;\n            if (kv < need) kv = need;\n            k[u] = kv;\n        }\n        long long total = 0;\n        for (int u = 0; u < V; ++u) {\n            if (u == root) continue;\n            total += 2 * k[u];\n            if (total > LIM) return false;\n        }\n        return total <= LIM;\n    };\n    \n    double lo = 0, hi = 1e6;\n    for (int it = 0; it < 60; ++it) {\n        double mid = (lo + hi) * 0.5;\n        if (feasible(mid)) lo = mid;\n        else hi = mid;\n    }\n    feasible(lo); // fill k with the final feasible value\n    \n    long long k_root = 0;\n    for (int w : children[root]) k_root += k[w];\n    k[root] = k_root; // root's own dirtiness is handled by its k\n    \n    // Build schedules: for each node, list of children for each slot\n    vector<vector<vector<int>>> sched(V);\n    for (int u : bfs_order) {\n        if (children[u].empty()) {\n            sched[u].assign((size_t)k[u], {});\n            continue;\n        }\n        vector<int> exc; // excursions (child ids repeated k[child] times)\n        exc.reserve(10000);\n        for (int w : children[u]) {\n            for (long long i = 0; i < k[w]; ++i) exc.push_back(w);\n        }\n        sched[u].assign((size_t)k[u], {});\n        for (size_t i = 0; i < exc.size(); ++i) {\n            int slot = (int)(i % k[u]);\n            sched[u][slot].push_back(exc[i]);\n        }\n    }\n    \n    string ans;\n    ans.reserve((size_t)LIM);\n    vector<size_t> cur_slot(V, 0);\n    \n    auto get_char = [&](int u, int v)->char {\n        for (auto [to, c] : adj[u]) if (to == v) return c;\n        return '?';\n    };\n    \n    function<void(int)> visit = [&](int u) {\n        size_t slot = cur_slot[u]++;\n        for (int w : sched[u][slot]) {\n            ans.push_back(get_char(u, w));\n            visit(w);\n            ans.push_back(get_char(w, u));\n        }\n    };\n    \n    // Process root slots\n    for (size_t slot = 0; slot < (size_t)k[root]; ++slot) {\n        for (int w : sched[root][slot]) {\n            ans.push_back(get_char(root, w));\n            visit(w);\n            ans.push_back(get_char(w, root));\n        }\n    }\n    \n    if ((long long)ans.size() > LIM) {\n        ans.resize((size_t)LIM);\n    }\n    cout << ans << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint calc_overlap(const string& a, const string& b) {\n    // If b is already a substring of a, we don't need to add anything\n    if (a.find(b) != string::npos) return (int)b.length();\n    // Find maximum k such that suffix of a matches prefix of b\n    int max_k = min((int)a.length(), (int)b.length());\n    for (int k = max_k; k > 0; --k) {\n        if (a.compare(a.length() - k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    int si, sj;\n    cin >> N >> M >> si >> sj;\n    \n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n    }\n    \n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n    \n    // Build superstring using greedy SCS (Shortest Common Superstring)\n    vector<string> pool = targets;\n    while (pool.size() > 1) {\n        int n = pool.size();\n        int best_ov = -1;\n        int best_i = -1, best_j = -1;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(pool[i], pool[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        \n        // Merge pool[best_i] and pool[best_j]\n        string merged = pool[best_i] + pool[best_j].substr(best_ov);\n        \n        // Remove best_j and best_i (remove higher index first to keep indices valid)\n        if (best_i > best_j) swap(best_i, best_j);\n        pool.erase(pool.begin() + best_j);\n        pool.erase(pool.begin() + best_i);\n        pool.push_back(merged);\n    }\n    \n    const string& U = pool[0];\n    const int L = U.size();\n    \n    // Precompute positions for each character\n    vector<vector<int>> pos(26); // store cell indices (i*N + j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int c = grid[i][j] - 'A';\n            pos[c].push_back(i * N + j);\n        }\n    }\n    \n    // Precompute Manhattan distances between all cells\n    const int V = N * N;\n    vector<vector<int>> dist(V, vector<int>(V));\n    for (int i = 0; i < V; ++i) {\n        int i1 = i / N, j1 = i % N;\n        for (int j = 0; j < V; ++j) {\n            int i2 = j / N, j2 = j % N;\n            dist[i][j] = abs(i1 - i2) + abs(j1 - j2);\n        }\n    }\n    \n    const int INF = 1e9;\n    // dp_curr[v] = min cost to reach cell v at current step\n    vector<int> dp_prev(V, INF), dp_curr(V, INF);\n    // parent[step][v] = previous cell index that achieved dp_curr[v]\n    vector<vector<int>> parent(L, vector<int>(V, -1));\n    \n    // Initialize for first character\n    int first_c = U[0] - 'A';\n    for (int v : pos[first_c]) {\n        int vi = v / N, vj = v % N;\n        dp_curr[v] = dist[si * N + sj][v] + 1;\n    }\n    \n    // DP for subsequent characters\n    for (int step = 1; step < L; ++step) {\n        dp_prev = dp_curr;\n        fill(dp_curr.begin(), dp_curr.end(), INF);\n        \n        int curr_c = U[step] - 'A';\n        int prev_c = U[step - 1] - 'A';\n        \n        for (int v : pos[curr_c]) {\n            int best = INF;\n            int best_u = -1;\n            for (int u : pos[prev_c]) {\n                if (dp_prev[u] == INF) continue;\n                int cost = dp_prev[u] + dist[u][v] + 1;\n                if (cost < best) {\n                    best = cost;\n                    best_u = u;\n                }\n            }\n            if (best < INF) {\n                dp_curr[v] = best;\n                parent[step][v] = best_u;\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_v = -1;\n    int best_cost = INF;\n    for (int v = 0; v < V; ++v) {\n        if (dp_curr[v] < best_cost) {\n            best_cost = dp_curr[v];\n            best_v = v;\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int, int>> path;\n    int cur = best_v;\n    for (int step = L - 1; step >= 0; --step) {\n        int i = cur / N;\n        int j = cur % N;\n        path.push_back({i, j});\n        if (step > 0) {\n            cur = parent[step][cur];\n        }\n    }\n    reverse(path.begin(), path.end());\n    \n    // Output\n    for (auto [i, j] : path) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ------------------------------------------------------------\n// Problem parameters\nint N, M;\ndouble eps;\nconst int MAX_N2 = 400; // 20*20\n\nstruct Placement {\n    bitset<MAX_N2> cells;\n    int area; // popcount\n};\n\nvector<vector<Placement>> placements; // [field][placement_idx]\nvector<int> num_placements; // [field]\n\n// ------------------------------------------------------------\n// Particle\nstruct Particle {\n    vector<int> pos; // size M, index of placement for each field\n    double weight;\n    Particle(int M_) : pos(M_), weight(1.0) {}\n};\n\nvector<Particle> particles;\nconst int NUM_PARTICLES = 2000;\n\n// ------------------------------------------------------------\n// Utilities\nint flat(int i, int j) { return i * N + j; }\n\n// ------------------------------------------------------------\n// Random generator\nmt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\ndouble rand_double() {\n    return uniform_real_distribution<double>(0.0, 1.0)(rng);\n}\n\n// ------------------------------------------------------------\n// Enumerate all valid placements for each field\nvoid enumerate_placements(const vector<vector<pair<int,int>>>& shapes) {\n    placements.resize(M);\n    num_placements.resize(M);\n    for (int k = 0; k < M; ++k) {\n        const auto& shape = shapes[k];\n        int h = 0, w = 0;\n        for (auto [i, j] : shape) {\n            h = max(h, i);\n            w = max(w, j);\n        }\n        // translations\n        for (int di = 0; di + h < N; ++di) {\n            for (int dj = 0; dj + w < N; ++dj) {\n                Placement p;\n                p.area = (int)shape.size();\n                for (auto [i, j] : shape) {\n                    int ni = di + i;\n                    int nj = dj + j;\n                    p.cells.set(flat(ni, nj));\n                }\n                placements[k].push_back(p);\n            }\n        }\n        num_placements[k] = (int)placements[k].size();\n        if (num_placements[k] == 0) {\n            // should not happen with valid input\n        }\n    }\n}\n\n// ------------------------------------------------------------\n// Initialize particles uniformly at random\nvoid init_particles(const vector<int>& forced_val = {}) {\n    particles.clear();\n    particles.reserve(NUM_PARTICLES);\n    for (int i = 0; i < NUM_PARTICLES; ++i) {\n        Particle p(M);\n        for (int k = 0; k < M; ++k) {\n            p.pos[k] = rand_int(0, num_placements[k] - 1);\n        }\n        p.weight = 1.0;\n        particles.push_back(p);\n    }\n}\n\n// ------------------------------------------------------------\n// Compute cell probabilities from particles\n// Returns vector<double> prob (size N*N), and also fills drilled constraints\nvector<double> compute_cell_probs(const vector<int>& drilled_val) {\n    vector<double> prob(N*N, 0.0);\n    for (const auto& p : particles) {\n        // coverage bitset of this particle\n        bitset<MAX_N2> cov;\n        for (int k = 0; k < M; ++k) {\n            cov |= placements[k][p.pos[k]].cells;\n        }\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (cov[idx]) prob[idx] += 1.0;\n        }\n    }\n    double invP = 1.0 / particles.size();\n    for (int i = 0; i < N*N; ++i) prob[i] *= invP;\n    return prob;\n}\n\n// ------------------------------------------------------------\n// Resample particles according to weights\nvoid resample() {\n    double sumw = 0.0;\n    for (auto& p : particles) sumw += p.weight;\n    if (sumw == 0) {\n        // all weights zero, reinitialize\n        init_particles();\n        return;\n    }\n    for (auto& p : particles) p.weight /= sumw;\n    \n    vector<Particle> new_parts;\n    new_parts.reserve(particles.size());\n    double step = 1.0 / particles.size();\n    double r = rand_double() * step;\n    double csum = 0.0;\n    size_t idx = 0;\n    for (size_t i = 0; i < particles.size(); ++i) {\n        double target = r + i * step;\n        while (idx < particles.size() && csum + particles[idx].weight < target) {\n            csum += particles[idx].weight;\n            ++idx;\n        }\n        if (idx >= particles.size()) idx = particles.size() - 1;\n        new_parts.push_back(particles[idx]);\n        new_parts.back().weight = 1.0;\n    }\n    particles.swap(new_parts);\n}\n\n// ------------------------------------------------------------\n// Filter particles by a drilled cell (exact value v)\nvoid filter_by_drill(int cell, int v) {\n    vector<Particle> filtered;\n    filtered.reserve(particles.size());\n    for (const auto& p : particles) {\n        int cnt = 0;\n        for (int k = 0; k < M; ++k) {\n            if (placements[k][p.pos[k]].cells[cell]) ++cnt;\n        }\n        if (cnt == v) filtered.push_back(p);\n    }\n    if ((int)filtered.size() < 10) {\n        // keep some random ones to avoid collapse, or reinitialize with constraint\n        // For simplicity, if too few, we keep original but this is rare\n        if (filtered.empty()) {\n            // total collapse, reinitialize and hope for the best\n            init_particles();\n            return;\n        }\n    }\n    particles.swap(filtered);\n    // reset weights\n    for (auto& p : particles) p.weight = 1.0;\n}\n\n// ------------------------------------------------------------\n// Main\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---- Input ------------------------------------------------\n    if (!(cin >> N >> M >> eps)) return 0;\n    vector<vector<pair<int,int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n    \n    enumerate_placements(shapes);\n    init_particles();\n    \n    vector<char> is_drilled(N*N, 0);\n    vector<int> drilled_val(N*N, -1);\n    \n    const int MAX_Q = 2 * N * N;\n    \n    for (int qcnt = 0; qcnt < MAX_Q - 5; ++qcnt) {\n        // Compute current beliefs\n        vector<double> prob = compute_cell_probs(drilled_val);\n        \n        // Identify uncertain cells\n        vector<int> uncertain;\n        uncertain.reserve(N*N);\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (is_drilled[idx]) continue;\n            if (prob[idx] > 0.1 && prob[idx] < 0.9) {\n                uncertain.push_back(idx);\n            }\n        }\n        \n        // Decide action\n        bool do_answer = false;\n        bool do_drill = false;\n        int drill_cell = -1;\n        vector<int> query_cells; // for divine\n        \n        // If almost all cells are certain, try to answer\n        if ((int)uncertain.size() <= 3 || qcnt > MAX_Q - 10) {\n            do_answer = true;\n        } else if (qcnt < 30) {\n            // Exploration: random large divine query\n            bitset<MAX_N2> mask;\n            for (int i = 0; i < N*N; ++i) {\n                if (rand_int(0,1)) query_cells.push_back(i);\n            }\n            if ((int)query_cells.size() < 2) {\n                query_cells.push_back(0);\n                query_cells.push_back(1);\n            }\n        } else {\n            // Exploitation: divine a batch of uncertain cells\n            // Take up to 25 cells to keep noise moderate (sigma ~ 0.5 for eps=0.01)\n            int take = min((int)uncertain.size(), 25);\n            // Sort by closest to 0.5\n            sort(uncertain.begin(), uncertain.end(), [&](int a, int b){\n                double da = abs(prob[a] - 0.5);\n                double db = abs(prob[b] - 0.5);\n                return da < db;\n            });\n            query_cells.assign(uncertain.begin(), uncertain.begin() + take);\n        }\n        \n        if (do_answer) {\n            vector<int> ans_cells;\n            for (int idx = 0; idx < N*N; ++idx) {\n                if (is_drilled[idx]) {\n                    if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n                } else {\n                    if (prob[idx] > 0.5) ans_cells.push_back(idx);\n                }\n            }\n            // Output answer\n            cout << \"a \" << ans_cells.size();\n            for (int idx : ans_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            int resp; cin >> resp;\n            if (resp == 1) {\n                return 0; // success\n            } else {\n                // Wrong answer, penalized 1 cost, continue\n                continue;\n            }\n        }\n        \n        if (!query_cells.empty() && !do_drill) {\n            // Divine query\n            int k = (int)query_cells.size();\n            cout << \"q \" << k;\n            for (int idx : query_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            \n            int obs; cin >> obs;\n            \n            // Prepare query mask\n            bitset<MAX_N2> qmask;\n            for (int idx : query_cells) qmask.set(idx);\n            \n            // Update weights\n            double kdbl = k;\n            double mu0 = kdbl * eps;\n            double sigma2 = kdbl * eps * (1.0 - eps);\n            double sigma = sqrt(sigma2);\n            if (sigma < 1e-9) sigma = 1e-9;\n            \n            for (auto& p : particles) {\n                int v = 0;\n                for (int m = 0; m < M; ++m) {\n                    v += (placements[m][p.pos[m]].cells & qmask).count();\n                }\n                double mu = mu0 + v * (1.0 - 2.0 * eps);\n                // Gaussian likelihood (ignoring round/max)\n                double z = (obs - mu) / sigma;\n                double w = exp(-0.5 * z * z);\n                p.weight = w;\n            }\n            resample();\n        } else if (do_drill && drill_cell >= 0) {\n            // Single drill\n            cout << \"q 1 \" << drill_cell / N << \" \" << drill_cell % N << endl;\n            int val; cin >> val;\n            is_drilled[drill_cell] = 1;\n            drilled_val[drill_cell] = val;\n            filter_by_drill(drill_cell, val);\n        }\n    }\n    \n    // Fallback: if we exit loop without answering, just answer with current belief\n    vector<int> ans_cells;\n    vector<double> prob = compute_cell_probs(drilled_val);\n    for (int idx = 0; idx < N*N; ++idx) {\n        if (is_drilled[idx]) {\n            if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n        } else {\n            if (prob[idx] > 0.5) ans_cells.push_back(idx);\n        }\n    }\n    cout << \"a \" << ans_cells.size();\n    for (int idx : ans_cells) {\n        cout << \" \" << idx / N << \" \" << idx % N;\n    }\n    cout << endl;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> day_dist(0, D-1);\n    uniform_int_distribution<int> strip_dist(0, N-1);\n    \n    // Heights h[d][k]\n    vector<vector<int>> h(D, vector<int>(N, 1));\n    \n    // Greedy initialization\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> needs;\n        for (int k = 0; k < N; k++) {\n            int need = (a[d][k] + W - 1) / W;\n            needs.push_back({need, k});\n        }\n        sort(needs.rbegin(), needs.rend());\n        \n        int remaining = W - N;\n        for (auto &[need, k] : needs) {\n            int give = min(remaining, max(0, need - 1));\n            h[d][k] = 1 + give;\n            remaining -= give;\n        }\n        int idx = 0;\n        while (remaining > 0) {\n            h[d][idx % N]++;\n            remaining--;\n            idx++;\n        }\n    }\n    \n    // Cumulative positions y[d][k]\n    vector<vector<int>> y(D, vector<int>(N+1));\n    for (int d = 0; d < D; d++) {\n        y[d][0] = 0;\n        for (int k = 0; k < N; k++) y[d][k+1] = y[d][k] + h[d][k];\n    }\n    \n    // Precompute area deficits\n    auto area_cost = [&](int d, int k) -> long long {\n        long long area = 1LL * h[d][k] * W;\n        if (area < a[d][k]) return 100LL * (a[d][k] - area);\n        return 0;\n    };\n    \n    long long cur_area_cost = 0, cur_part_cost = 0;\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cur_area_cost += area_cost(d, k);\n    }\n    for (int d = 1; d < D; d++) {\n        for (int k = 1; k < N; k++) {\n            if (y[d][k] != y[d-1][k]) cur_part_cost += 2LL * W;\n        }\n    }\n    \n    long long current_cost = cur_area_cost + cur_part_cost;\n    long long best_cost = current_cost;\n    auto best_h = h;\n    \n    const double TIME_LIMIT = 2.85;\n    clock_t start_time = clock();\n    \n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > TIME_LIMIT) break;\n        \n        double progress = elapsed / TIME_LIMIT;\n        double T = 500000.0 * (1.0 - progress) + 1.0;\n        \n        int d = day_dist(rng);\n        int i = strip_dist(rng);\n        int j = strip_dist(rng);\n        if (i == j) continue;\n        if (h[d][i] <= 1) continue;\n        \n        int l = min(i, j) + 1;\n        int r = max(i, j);\n        int delta = (i < j) ? -1 : +1;\n        \n        // Compute delta cost\n        long long da = 0;\n        \n        // Area changes\n        long long old_i = area_cost(d, i);\n        long long new_i = (1LL * (h[d][i]-1) * W < a[d][i]) ? 100LL * (a[d][i] - 1LL * (h[d][i]-1) * W) : 0;\n        da += new_i - old_i;\n        \n        long long old_j = area_cost(d, j);\n        long long new_j = (1LL * (h[d][j]+1) * W < a[d][j]) ? 100LL * (a[d][j] - 1LL * (h[d][j]+1) * W) : 0;\n        da += new_j - old_j;\n        \n        // Partition changes\n        long long dp = 0;\n        for (int k = l; k <= r; k++) {\n            int old_y = y[d][k];\n            int new_y = old_y + delta;\n            \n            if (d > 0) {\n                bool oeq = (old_y == y[d-1][k]);\n                bool neq = (new_y == y[d-1][k]);\n                if (oeq && !neq) dp += 2LL * W;\n                else if (!oeq && neq) dp -= 2LL * W;\n            }\n            if (d < D - 1) {\n                bool oeq = (old_y == y[d+1][k]);\n                bool neq = (new_y == y[d+1][k]);\n                if (oeq && !neq) dp += 2LL * W;\n                else if (!oeq && neq) dp -= 2LL * W;\n            }\n        }\n        \n        long long delta_cost = da + dp;\n        \n        bool accept = (delta_cost < 0);\n        if (!accept && T > 0.1) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < exp(-(double)delta_cost / T)) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            h[d][i]--;\n            h[d][j]++;\n            for (int k = l; k <= r; k++) y[d][k] += delta;\n            current_cost += delta_cost;\n            \n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_h = h;\n            }\n        }\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        int cur = 0;\n        for (int k = 0; k < N; k++) {\n            int i1 = cur;\n            cur += best_h[d][k];\n            int i2 = cur;\n            cout << i1 << \" 0 \" << i2 << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m, p, q;\n    int pos[9];\n    int val[9];\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int tc = 0; tc < 150; ++tc) {\n        int n, m, k;\n        if (!(cin >> n >> m >> k)) return 0;\n        \n        vector<long long> grid(n * n);\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cin >> grid[i * n + j];\n            }\n        }\n        \n        int stamp_vals[20][3][3];\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                for (int l = 0; l < 3; ++l) {\n                    cin >> stamp_vals[i][j][l];\n                }\n            }\n        }\n        \n        // Precompute all 980 operations\n        vector<Op> ops;\n        ops.reserve(m * (n-2) * (n-2));\n        for (int mi = 0; mi < m; ++mi) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    Op op;\n                    op.m = mi; op.p = p; op.q = q;\n                    int cnt = 0;\n                    for (int i = 0; i < 3; ++i) {\n                        for (int j = 0; j < 3; ++j) {\n                            op.pos[cnt] = (p + i) * n + (q + j);\n                            op.val[cnt] = stamp_vals[mi][i][j];\n                            cnt++;\n                        }\n                    }\n                    ops.push_back(op);\n                }\n            }\n        }\n        \n        const int NUM_OPS = ops.size();\n        vector<int> sol;\n        sol.reserve(k);\n        \n        mt19937 rng(tc + 12345);\n        \n        auto calc_delta = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv + op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto calc_delta_remove = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv - op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto apply_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] += op.val[i];\n        };\n        \n        auto remove_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] -= op.val[i];\n        };\n        \n        // Greedy construction\n        for (int iter = 0; iter < k; ++iter) {\n            long long best_d = 0;\n            int best_idx = -1;\n            \n            // Random shuffle to break ties and add diversity\n            vector<int> order(NUM_OPS);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            \n            for (int idx : order) {\n                long long d = calc_delta(ops[idx]);\n                if (d > best_d) {\n                    best_d = d;\n                    best_idx = idx;\n                }\n            }\n            \n            if (best_idx == -1) break;\n            apply_op(ops[best_idx]);\n            sol.push_back(best_idx);\n        }\n        \n        // Simulated Annealing\n        const int SA_ITER = 30000;\n        double temp = 1e9;\n        double alpha = pow(0.1 / temp, 1.0 / SA_ITER);\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < SA_ITER; ++iter) {\n            if (sol.empty()) {\n                int idx = rng() % NUM_OPS;\n                long long d = calc_delta(ops[idx]);\n                apply_op(ops[idx]);\n                sol.push_back(idx);\n            } else if ((int)sol.size() >= k) {\n                int sidx = rng() % sol.size();\n                const Op& op = ops[sol[sidx]];\n                long long d = calc_delta_remove(op);\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    remove_op(op);\n                    sol[sidx] = sol.back();\n                    sol.pop_back();\n                }\n            } else {\n                int type = rng() % 3;\n                if (type == 0) {\n                    int idx = rng() % NUM_OPS;\n                    long long d = calc_delta(ops[idx]);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        apply_op(ops[idx]);\n                        sol.push_back(idx);\n                    }\n                } else if (type == 1) {\n                    int sidx = rng() % sol.size();\n                    const Op& op = ops[sol[sidx]];\n                    long long d = calc_delta_remove(op);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        remove_op(op);\n                        sol[sidx] = sol.back();\n                        sol.pop_back();\n                    }\n                } else {\n                    // Replace\n                    int sidx = rng() % sol.size();\n                    int new_idx = rng() % NUM_OPS;\n                    const Op& old_op = ops[sol[sidx]];\n                    \n                    long long d_rem = calc_delta_remove(old_op);\n                    remove_op(old_op);\n                    \n                    const Op& new_op = ops[new_idx];\n                    long long d_add = calc_delta(new_op);\n                    \n                    long long total = d_rem + d_add;\n                    if (total > 0 || exp(total / temp) > dist(rng)) {\n                        apply_op(new_op);\n                        sol[sidx] = new_idx;\n                    } else {\n                        apply_op(old_op);\n                    }\n                }\n            }\n            temp *= alpha;\n        }\n        \n        cout << sol.size() << '\\n';\n        for (int idx : sol) {\n            cout << ops[idx].m << ' ' << ops[idx].p << ' ' << ops[idx].q << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) \n        for (int j = 0; j < N; j++) \n            cin >> A[i][j];\n    \n    // Grid state: -1 = empty, else container ID\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // How many containers have been placed at each gate (for receiving logic)\n    vector<int> recv_ptr(N, 0);\n    \n    // Initialize: place first containers at receiving gates (turn 0 receiving step)\n    for (int i = 0; i < N; i++) {\n        grid[i][0] = A[i][0];\n        recv_ptr[i] = 1;\n    }\n    \n    // Crane 0 state (large crane)\n    int cr = 0, cc = 0;  // current position\n    bool holding = false;\n    int held_id = -1;\n    \n    vector<string> ops(N);  // operations for each crane\n    int turn = 0;\n    \n    auto add_op = [&](int crane, char c) {\n        if ((int)ops[crane].size() <= turn) \n            ops[crane].push_back(c);\n        else \n            ops[crane][turn] = c;\n    };\n    \n    // Receiving: happens at start of turn\n    auto do_receiving = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][0] == -1 && recv_ptr[i] < N) {\n                grid[i][0] = A[i][recv_ptr[i]];\n                recv_ptr[i]++;\n            }\n        }\n    };\n    \n    // Dispatch: happens at end of turn\n    auto do_dispatch = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    };\n    \n    auto end_turn = [&]() {\n        do_dispatch();\n        do_receiving();\n        turn++;\n    };\n    \n    // Turn 0: bomb small cranes, large crane waits\n    add_op(0, '.');\n    for (int i = 1; i < N; i++) add_op(i, 'B');\n    end_turn();\n    \n    vector<int> dispatched(N, 0);      // how many dispatched from each row\n    vector<int> taken_from_gate(N, 0); // how many taken from each gate\n    \n    // Check if gate g is exhausted (no more containers will arrive)\n    auto gate_exhausted = [&](int g) -> bool {\n        return recv_ptr[g] >= N && grid[g][0] == -1; \n        // Actually, recv_ptr[g] >= N means all 5 have been placed\n        return recv_ptr[g] >= N;\n    };\n    \n    // Find parking column in row r, avoiding col 0 unless gate exhausted\n    auto find_park_in_row = [&](int r) -> int {\n        // Prefer middle columns, away from gates\n        vector<int> cols = {2, 3, 1};\n        for (int c : cols) {\n            if (grid[r][c] == -1) return c;\n        }\n        // Use col 0 only if gate is exhausted (no more receiving)\n        if (recv_ptr[r] >= N && grid[r][0] == -1) return 0;\n        return -1;\n    };\n    \n    // Find any available parking spot\n    auto find_any_park = [&]() -> pair<int,int> {\n        for (int r = 0; r < N; r++) {\n            int c = find_park_in_row(r);\n            if (c != -1) return {r, c};\n        }\n        return {-1, -1};\n    };\n    \n    // Move crane to target position (Manhattan path)\n    auto move_to = [&](int tr, int tc) {\n        while (cr != tr) {\n            if (cr < tr) { add_op(0, 'D'); cr++; }\n            else { add_op(0, 'U'); cr--; }\n            end_turn();\n        }\n        while (cc != tc) {\n            if (cc < tc) { add_op(0, 'R'); cc++; }\n            else { add_op(0, 'L'); cc--; }\n            end_turn();\n        }\n    };\n    \n    auto pickup = [&]() {\n        add_op(0, 'P');\n        held_id = grid[cr][cc];\n        grid[cr][cc] = -1;\n        holding = true;\n        end_turn();\n    };\n    \n    auto drop = [&]() {\n        add_op(0, 'Q');\n        grid[cr][cc] = held_id;\n        holding = false;\n        held_id = -1;\n        end_turn();\n    };\n    \n    // Process each target row in order\n    for (int target = 0; target < N; target++) {\n        // Try to dispatch currently held container if it's the next needed one\n        auto try_dispatch = [&]() -> bool {\n            if (!holding) return false;\n            int need = target * N + dispatched[target];\n            if (held_id == need) {\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n                return true;\n            }\n            return false;\n        };\n        \n        // 1. Clear own gate first (this exhausts it, freeing column 0 for parking)\n        while (taken_from_gate[target] < N) {\n            int cid = A[target][taken_from_gate[target]];\n            move_to(target, 0);\n            pickup();\n            taken_from_gate[target]++;\n            \n            if (!try_dispatch()) {\n                auto [pr, pc] = find_any_park();\n                // Emergency search: allow col 0 of exhausted gates\n                if (pr == -1) {\n                    for (int r = 0; r < N && pr == -1; r++) {\n                        for (int c = 0; c < N; c++) {\n                            if (grid[r][c] == -1) {\n                                if (c == 0 && recv_ptr[r] < N) continue; // might receive new container\n                                pr = r; pc = c; break;\n                            }\n                        }\n                    }\n                }\n                move_to(pr, pc);\n                drop();\n            }\n        }\n        \n        // 2. Collect containers for target row from other gates\n        for (int g = 0; g < N; g++) {\n            if (g == target) continue;\n            \n            while (taken_from_gate[g] < N) {\n                int cid = A[g][taken_from_gate[g]];\n                if (cid / N != target) break; // not for this target row\n                \n                // Clear blockers (containers before cid at gate g)\n                while (taken_from_gate[g] < N && A[g][taken_from_gate[g]] != cid) {\n                    int blk = A[g][taken_from_gate[g]];\n                    move_to(g, 0);\n                    pickup();\n                    taken_from_gate[g]++;\n                    \n                    int blk_row = blk / N;\n                    auto [pr, pc] = find_any_park();\n                    if (pr == -1) {\n                        for (int r = 0; r < N && pr == -1; r++) {\n                            for (int c = 0; c < N; c++) {\n                                if (grid[r][c] == -1) {\n                                    if (c == 0 && recv_ptr[r] < N) continue;\n                                    pr = r; pc = c; break;\n                                }\n                            }\n                        }\n                    }\n                    move_to(pr, pc);\n                    drop();\n                }\n                \n                // Now pick up the target container\n                move_to(g, 0);\n                pickup();\n                taken_from_gate[g]++;\n                \n                if (!try_dispatch()) {\n                    auto [pr, pc] = find_any_park();\n                    if (pr == -1) {\n                        for (int r = 0; r < N && pr == -1; r++) {\n                            for (int c = 0; c < N; c++) {\n                                if (grid[r][c] == -1) {\n                                    if (c == 0 && recv_ptr[r] < N) continue;\n                                    pr = r; pc = c; break;\n                                }\n                            }\n                        }\n                    }\n                    move_to(pr, pc);\n                    drop();\n                }\n            }\n        }\n        \n        // 3. Dispatch any remaining parked containers in this row\n        while (dispatched[target] < N) {\n            int need = target * N + dispatched[target];\n            int fc = -1;\n            for (int c = 0; c < N-1; c++) { // check cols 0-3 (4 is dispatch)\n                if (grid[target][c] == need) {\n                    fc = c;\n                    break;\n                }\n            }\n            if (fc != -1) {\n                move_to(target, fc);\n                pickup();\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n            } else {\n                // Should not happen if algorithm is correct\n                break;\n            }\n        }\n    }\n    \n    // Pad all strings to same length\n    size_t max_len = 0;\n    for (auto &s : ops) max_len = max(max_len, s.size());\n    for (auto &s : ops) {\n        while (s.size() < max_len) s.push_back('.');\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int r = 0, c = 0;\n    long long load = 0;\n    \n    auto move_to = [&](int nr, int nc) {\n        while (r < nr) {\n            ops.emplace_back(\"D\");\n            ++r;\n        }\n        while (r > nr) {\n            ops.emplace_back(\"U\");\n            --r;\n        }\n        while (c < nc) {\n            ops.emplace_back(\"R\");\n            ++c;\n        }\n        while (c > nc) {\n            ops.emplace_back(\"L\");\n            --c;\n        }\n    };\n    \n    auto find_nearest_sink_dist = [&](int sr, int sc) -> int {\n        int best = 1e9;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (h[i][j] < 0) {\n                    best = min(best, abs(i - sr) + abs(j - sc));\n                }\n            }\n        }\n        return best;\n    };\n    \n    auto find_best_source = [&]() -> pair<int, int> {\n        int best_score = 1e9;\n        pair<int, int> best = {-1, -1};\n        \n        // Find nearest sink for each potential source to compute round-trip cost\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (h[i][j] > 0) {\n                    int d_to_source = abs(i - r) + abs(j - c);\n                    int d_to_sink = find_nearest_sink_dist(i, j);\n                    // Score: distance to get there + distance to deliver (loaded travel is more expensive)\n                    int score = d_to_source * 100 + d_to_sink * (100 + h[i][j]);\n                    if (score < best_score) {\n                        best_score = score;\n                        best = {i, j};\n                    }\n                }\n            }\n        }\n        return best;\n    };\n    \n    auto find_nearest_sink = [&]() -> pair<int, int> {\n        int best_dist = 1e9;\n        pair<int, int> best = {-1, -1};\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (h[i][j] < 0) {\n                    int d = abs(i - r) + abs(j - c);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best = {i, j};\n                    }\n                }\n            }\n        }\n        return best;\n    };\n    \n    while (true) {\n        if (load == 0) {\n            auto [si, sj] = find_best_source();\n            if (si == -1) break;\n            move_to(si, sj);\n            int d = h[r][c];\n            ops.emplace_back(\"+\" + to_string(d));\n            load += d;\n            h[r][c] = 0;\n        } else {\n            auto [ti, tj] = find_nearest_sink();\n            if (ti == -1) break;\n            move_to(ti, tj);\n            int amount = (int)min<long long>(load, -h[r][c]);\n            ops.emplace_back(\"-\" + to_string(amount));\n            load -= amount;\n            h[r][c] += amount;\n        }\n    }\n    \n    for (const auto& s : ops) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Solver {\n    int N, M, T;\n    int SEED_COUNT;\n    struct Seed {\n        vector<int> x;\n        int sum;\n        int mx;\n    };\n    vector<Seed> seeds;\n    mt19937 rng;\n    chrono::steady_clock::time_point start_time;\n\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        start_time = chrono::steady_clock::now();\n    }\n\n    void solveOneTurn(int turn, int total_turns) {\n        // Select top N*N seeds using a score that values both sum and max dimension\n        vector<pair<ll, int>> candidates;\n        for (int i = 0; i < SEED_COUNT; i++) {\n            // Score = sum + 5 * max_dimension (weight 5 tuned for balance)\n            ll score = seeds[i].sum + 5LL * seeds[i].mx;\n            candidates.push_back({score, i});\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        vector<int> selected;\n        for (int i = 0; i < N * N; i++) {\n            selected.push_back(candidates[i].second);\n        }\n\n        // Precompute edge scores for selected seeds\n        int S = N * N;\n        vector<vector<ll>> edgeScore(S, vector<ll>(S));\n        for (int i = 0; i < S; i++) {\n            for (int j = i; j < S; j++) {\n                int a = selected[i];\n                int b = selected[j];\n                ll s = 0;\n                for (int l = 0; l < M; l++) {\n                    s += max(seeds[a].x[l], seeds[b].x[l]);\n                }\n                edgeScore[i][j] = edgeScore[j][i] = s;\n            }\n        }\n\n        // Grid positions sorted by degree (center first)\n        vector<pair<int, pair<int,int>>> positions; // (degree, (i,j))\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int deg = 0;\n                if (i > 0) deg++;\n                if (i < N-1) deg++;\n                if (j > 0) deg++;\n                if (j < N-1) deg++;\n                positions.push_back({deg, {i, j}});\n            }\n        }\n        sort(positions.rbegin(), positions.rend());\n\n        // Map from linear index to (i,j)\n        vector<int> pos2idx(S);\n        vector<pair<int,int>> idx2pos(S);\n        for (int i = 0; i < S; i++) {\n            idx2pos[i] = positions[i].second;\n            pos2idx[positions[i].second.first * N + positions[i].second.second] = i;\n        }\n\n        // Initial placement: best seeds in highest degree positions\n        vector<int> placement(S); // position idx -> seed idx (0..S-1 in selected)\n        iota(placement.begin(), placement.end(), 0);\n\n        // Precompute neighbor list for each position idx\n        vector<vector<int>> neighbors(S);\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    neighbors[idx].push_back(pos2idx[ni * N + nj]);\n                }\n            }\n        }\n\n        auto calcCell = [&](int idx) {\n            ll s = 0;\n            int seed = placement[idx];\n            for (int nb : neighbors[idx]) {\n                s += edgeScore[seed][placement[nb]];\n            }\n            return s;\n        };\n\n        auto totalScore = [&]() {\n            ll s = 0;\n            for (int i = 0; i < S; i++) {\n                s += calcCell(i);\n            }\n            return s / 2; // Each edge counted twice\n        };\n\n        // Simulated Annealing\n        double temp = 1000.0;\n        const double cooling = 0.9998;\n        \n        // Time management\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        double time_limit = 1.9; // Keep some margin\n        double time_per_turn = (time_limit - elapsed) / (total_turns - turn);\n        \n        ll currentScore = 0;\n        for (int i = 0; i < S; i++) currentScore += calcCell(i);\n        currentScore /= 2;\n\n        int iterations = 0;\n        while (true) {\n            now = chrono::steady_clock::now();\n            double time_used = chrono::duration<double>(now - start_time).count();\n            if (time_used > time_limit * (turn + 1) / total_turns) break;\n\n            int idx1 = rng() % S;\n            int idx2 = rng() % S;\n            if (idx1 == idx2) continue;\n\n            // Calculate delta\n            ll oldContrib = calcCell(idx1) + calcCell(idx2);\n            \n            // If adjacent, the edge between them is counted in both calcCell\n            // Since edgeScore is symmetric, swapping doesn't change the shared edge contribution\n            // So we don't need to subtract anything special\n            \n            swap(placement[idx1], placement[idx2]);\n            \n            ll newContrib = calcCell(idx1) + calcCell(idx2);\n            ll delta = newContrib - oldContrib;\n\n            if (delta > 0 || exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore += delta;\n            } else {\n                swap(placement[idx1], placement[idx2]); // Revert\n            }\n\n            temp *= cooling;\n            iterations++;\n            if (iterations > 200000) break; // Safety\n        }\n\n        // Local search refinement (hill climbing)\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int idx1 = 0; idx1 < S && !improved; idx1++) {\n                for (int idx2 = idx1 + 1; idx2 < S && !improved; idx2++) {\n                    ll oldContrib = calcCell(idx1) + calcCell(idx2);\n                    swap(placement[idx1], placement[idx2]);\n                    ll newContrib = calcCell(idx1) + calcCell(idx2);\n                    if (newContrib > oldContrib) {\n                        currentScore += newContrib - oldContrib;\n                        improved = true;\n                    } else {\n                        swap(placement[idx1], placement[idx2]);\n                    }\n                }\n            }\n        }\n\n        // Generate output grid\n        vector<vector<int>> output(N, vector<int>(N));\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            output[i][j] = selected[placement[idx]];\n        }\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j > 0) cout << ' ';\n                cout << output[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n    }\n\n    void solve() {\n        cin >> N >> M >> T;\n        SEED_COUNT = 2 * N * (N - 1);\n        seeds.resize(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].x.resize(M);\n            seeds[i].sum = 0;\n            seeds[i].mx = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].x[j];\n                seeds[i].sum += seeds[i].x[j];\n                seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n            }\n        }\n\n        for (int turn = 0; turn < T; turn++) {\n            solveOneTurn(turn, T);\n\n            // Read next generation\n            for (int i = 0; i < SEED_COUNT; i++) {\n                seeds[i].sum = 0;\n                seeds[i].mx = 0;\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i].x[j];\n                    seeds[i].sum += seeds[i].x[j];\n                    seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V_limit;\nvector<pair<int,int>> sources, targets;\n\n// Hungarian algorithm for minimum cost perfect matching\nvector<int> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i=1; i<=n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INT_MAX);\n        vector<char> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INT_MAX, j1 = 0;\n            for (int j=1; j<=m; j++) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j=0; j<=m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> match(n);\n    for (int j=1; j<=m; j++) {\n        if (p[j] != 0) match[p[j]-1] = j-1;\n    }\n    return match;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> V_limit;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i=0; i<N; i++) cin >> s_grid[i];\n    for (int i=0; i<N; i++) cin >> t_grid[i];\n\n    // Collect positions (x=row, y=col)\n    for (int i=0; i<N; i++) {\n        for (int j=0; j<N; j++) {\n            if (s_grid[i][j] == '1') sources.push_back({i, j});\n            if (t_grid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    // Build cost matrix (Manhattan distance)\n    vector<vector<int>> cost(M, vector<int>(M));\n    for (int i=0; i<M; i++) {\n        for (int j=0; j<M; j++) {\n            cost[i][j] = abs(sources[i].first - targets[j].first) \n                       + abs(sources[i].second - targets[j].second);\n        }\n    }\n    \n    vector<int> match = hungarian(cost);\n    \n    // Create pairs (source, target)\n    vector<pair<pair<int,int>, pair<int,int>>> pairs;\n    for (int i=0; i<M; i++) {\n        pairs.push_back({sources[i], targets[match[i]]});\n    }\n\n    // Build dependency graph: if target of i is source of j, then j must come before i\n    map<pair<int,int>, int> src_to_idx;\n    for (int i=0; i<M; i++) {\n        src_to_idx[pairs[i].first] = i;\n    }\n    \n    vector<vector<int>> adj(M);\n    vector<int> indeg(M, 0);\n    \n    for (int i=0; i<M; i++) {\n        auto it = src_to_idx.find(pairs[i].second);\n        if (it != src_to_idx.end()) {\n            int j = it->second; // pairs[j].first == pairs[i].second\n            if (i != j) {\n                adj[j].push_back(i);\n                indeg[i]++;\n            }\n        }\n    }\n\n    // Topological greedy ordering (no local search to avoid constraint violations)\n    vector<pair<pair<int,int>, pair<int,int>>> ordered;\n    vector<bool> processed(M, false);\n    \n    // Initial position for greedy selection: median of sources\n    int cur_x, cur_y;\n    {\n        vector<int> xs, ys;\n        for (auto& s : sources) {\n            xs.push_back(s.first);\n            ys.push_back(s.second);\n        }\n        sort(xs.begin(), xs.end());\n        sort(ys.begin(), ys.end());\n        cur_x = xs[xs.size()/2];\n        cur_y = ys[ys.size()/2];\n    }\n    \n    for (int iter=0; iter<M; iter++) {\n        int best_i = -1;\n        int best_dist = INT_MAX;\n        \n        for (int i=0; i<M; i++) {\n            if (processed[i] || indeg[i] > 0) continue;\n            int d = abs(cur_x - pairs[i].first.first) \n                  + abs(cur_y - pairs[i].first.second);\n            if (d < best_dist) {\n                best_dist = d;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        processed[best_i] = true;\n        ordered.push_back(pairs[best_i]);\n        cur_x = pairs[best_i].second.first;\n        cur_y = pairs[best_i].second.second;\n        \n        for (int nb : adj[best_i]) {\n            indeg[nb]--;\n        }\n    }\n\n    // Calculate optimal start position: median of first few task sources\n    int start_x, start_y;\n    {\n        vector<int> xs, ys;\n        int sample = min((int)ordered.size(), 10);\n        for (int i=0; i<sample; i++) {\n            xs.push_back(ordered[i].first.first);\n            ys.push_back(ordered[i].first.second);\n        }\n        sort(xs.begin(), xs.end());\n        sort(ys.begin(), ys.end());\n        start_x = xs[xs.size()/2];\n        start_y = ys[ys.size()/2];\n    }\n\n    // Output tree: 2 vertices (root + fingertip), edge length 1\n    cout << 2 << \"\\n\";\n    cout << \"0 1\\n\";\n    cout << start_x << \" \" << start_y << \"\\n\";\n\n    // Simulation\n    const int L = 1;\n    int rx = start_x, ry = start_y;\n    int dir = 0; // 0=right, 1=down, 2=left, 3=up\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    auto move_to = [&](int tx, int ty) {\n        // Find best direction to approach target\n        int best_d = 0;\n        int best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = tx - dx[d] * L;\n            int ny = ty - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manhattan = abs(rx - nx) + abs(ry - ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manhattan, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        \n        int nx = tx - dx[best_d] * L;\n        int ny = ty - dy[best_d] * L;\n        \n        // Move and rotate until positioned\n        while (rx != nx || ry != ny || dir != best_d) {\n            string cmd(4, '.');\n            \n            // Move root toward target\n            if (rx < nx) { cmd[0] = 'D'; rx++; }\n            else if (rx > nx) { cmd[0] = 'U'; rx--; }\n            else if (ry < ny) { cmd[0] = 'R'; ry++; }\n            else if (ry > ny) { cmd[0] = 'L'; ry--; }\n            \n            // Rotate if needed (can combine with move)\n            if (dir != best_d) {\n                int diff = (best_d - dir + 4) % 4;\n                if (diff == 1) {\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                } else if (diff == 3) {\n                    cmd[1] = 'L';\n                    dir = (dir + 3) % 4;\n                } else if (diff == 2) {\n                    // 180 degrees - rotate 90 now\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                }\n            }\n            cout << cmd << \"\\n\";\n        }\n    };\n    \n    auto perform_action = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P'; // fingertip is vertex 1\n        cout << cmd << \"\\n\";\n    };\n\n    // Execute\n    for (auto& [src, dst] : ordered) {\n        // Move to source and pickup\n        move_to(src.first, src.second);\n        perform_action();\n        \n        // Move to destination and drop\n        move_to(dst.first, dst.second);\n        perform_action();\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Node {\n    int sum = 0;\n    int best = 0;        // max subarray sum\n    int left_best = 0;   // max prefix sum\n    int right_best = 0;  // max suffix sum\n    int best_l = 0, best_r = 0; // indices of best subarray\n    int left_pos = 0;    // rightmost index of max prefix (end point)\n    int right_pos = 0;   // leftmost index of max suffix (start point)\n};\n\nclass SegTree {\n    int n;\n    int Y; // actual size\n    vector<Node> tree;\npublic:\n    SegTree(int size) {\n        Y = size;\n        n = 1;\n        while (n < Y) n <<= 1;\n        tree.resize(2 * n);\n        init(1, 0, n - 1);\n    }\n\n    void init(int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].left_pos = l;\n            tree[idx].right_pos = r;\n            tree[idx].best_l = l;\n            tree[idx].best_r = r;\n            // If beyond valid range, set to -INF so never chosen\n            if (l >= Y) {\n                tree[idx].best = -INF;\n                tree[idx].left_best = -INF;\n                tree[idx].right_best = -INF;\n                tree[idx].sum = 0;\n            }\n            return;\n        }\n        int mid = (l + r) >> 1;\n        init(idx << 1, l, mid);\n        init(idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    void pull(int idx, int left, int right) {\n        Node &res = tree[idx];\n        Node &L = tree[left];\n        Node &R = tree[right];\n\n        res.sum = L.sum + R.sum;\n\n        // Left prefix (max sum starting from left boundary)\n        if (L.left_best >= L.sum + R.left_best) {\n            res.left_best = L.left_best;\n            res.left_pos = L.left_pos;\n        } else {\n            res.left_best = L.sum + R.left_best;\n            res.left_pos = R.left_pos; // FIXED: takes end index from right child\n        }\n\n        // Right suffix (max sum ending at right boundary)\n        if (R.right_best >= R.sum + L.right_best) {\n            res.right_best = R.right_best;\n            res.right_pos = R.right_pos;\n        } else {\n            res.right_best = R.sum + L.right_best;\n            res.right_pos = L.right_pos; // FIXED: takes start index from left child\n        }\n\n        // Best subarray\n        res.best = L.best;\n        res.best_l = L.best_l;\n        res.best_r = L.best_r;\n\n        if (R.best > res.best) {\n            res.best = R.best;\n            res.best_l = R.best_l;\n            res.best_r = R.best_r;\n        }\n\n        int cross = L.right_best + R.left_best;\n        if (cross > res.best) {\n            res.best = cross;\n            res.best_l = L.right_pos; // Start of left suffix\n            res.best_r = R.left_pos;  // End of right prefix\n        }\n    }\n\n    void update(int pos, int val) { update(pos, val, 1, 0, n - 1); }\n\n    void update(int pos, int val, int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].sum += val;\n            tree[idx].best += val;\n            tree[idx].left_best += val;\n            tree[idx].right_best += val;\n            return;\n        }\n        int mid = (l + r) >> 1;\n        if (pos <= mid) update(pos, val, idx << 1, l, mid);\n        else update(pos, val, idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    const Node& query() const { return tree[1]; }\n};\n\nstruct Point {\n    int x, y;\n    int type; // +1 for mackerel, -1 for sardine\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    \n    vector<Point> points;\n    points.reserve(2 * N);\n    vector<int> all_x, all_y;\n    all_x.reserve(2 * N);\n    all_y.reserve(2 * N);\n\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Coordinate compression for y\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n    int Y = all_y.size();\n\n    // Group points by x-coordinate\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    \n    map<int, vector<pair<int, int>>> x_to_points; // x -> list of (y_idx, type)\n    for (const auto &p : points) {\n        int y_idx = lower_bound(all_y.begin(), all_y.end(), p.y) - all_y.begin();\n        x_to_points[p.x].push_back({y_idx, p.type});\n    }\n\n    // Select candidate x-coordinates (up to 1000 with highest density)\n    vector<int> x_cands = all_x;\n    if (x_cands.size() > 1000) {\n        vector<pair<int, int>> cnts;\n        for (int x : x_cands) {\n            cnts.push_back({-(int)x_to_points[x].size(), x}); // negative for min-heap simulation\n        }\n        sort(cnts.begin(), cnts.end()); // sort by count descending\n        x_cands.clear();\n        for (int i = 0; i < 1000; ++i) x_cands.push_back(cnts[i].second);\n        sort(x_cands.begin(), x_cands.end());\n    }\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 1, best_y1 = 0, best_y2 = 1;\n\n    // Sweep line\n    for (size_t i = 0; i < x_cands.size(); ++i) {\n        SegTree seg(Y);\n        for (size_t j = i; j < x_cands.size(); ++j) {\n            int x = x_cands[j];\n            auto it = x_to_points.find(x);\n            if (it != x_to_points.end()) {\n                for (const auto &[y_idx, typ] : it->second) {\n                    seg.update(y_idx, typ);\n                }\n            }\n            \n            const Node &res = seg.query();\n            if (res.best > best_score) {\n                // Validate indices are within bounds\n                if (res.best_l >= 0 && res.best_l < Y && res.best_r >= 0 && res.best_r < Y) {\n                    best_score = res.best;\n                    best_x1 = x_cands[i];\n                    best_x2 = x;\n                    best_y1 = all_y[res.best_l];\n                    best_y2 = all_y[res.best_r];\n                    if (best_y1 > best_y2) swap(best_y1, best_y2);\n                }\n            }\n        }\n    }\n\n    // Ensure valid rectangle (distinct vertices, positive area)\n    if (best_x1 == best_x2) {\n        if (best_x2 < 100000) best_x2++;\n        else best_x1--;\n    }\n    if (best_y1 == best_y2) {\n        if (best_y2 < 100000) best_y2++;\n        else best_y1--;\n    }\n\n    // Output rectangle\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        double w, h;\n        cin >> w >> h;\n        w_est[i] = w;\n        h_est[i] = h;\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        vector<double> x(N, 0), y(N, 0);\n        vector<int> rot(N, 0);\n        vector<Placement> ops;\n        ops.reserve(N);\n        \n        double cur_W = 0, cur_H = 0;\n        \n        for (int i = 0; i < N; i++) {\n            double best_score = 1e300;\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            double best_x = 0, best_y = 0;\n            \n            for (int r = 0; r < 2; r++) {\n                double wi = r ? h_est[i] : w_est[i];\n                double hi = r ? w_est[i] : h_est[i];\n                \n                // Try both directions\n                for (char d : {'U', 'L'}) {\n                    // Try all possible bases\n                    for (int b = -1; b < i; b++) {\n                        double xi, yi;\n                        \n                        if (d == 'U') {\n                            // Fix x based on b\n                            if (b == -1) {\n                                xi = 0;\n                            } else {\n                                double wb = rot[b] ? h_est[b] : w_est[b];\n                                xi = x[b] + wb;\n                            }\n                            \n                            // Find y by checking overlaps (skyline)\n                            yi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check x-overlap: [xi, xi+wi) vs [xj, xj+wj)\n                                if (max(xi, xj) < min(xi + wi, xj + wj)) {\n                                    yi = max(yi, yj + hj);\n                                }\n                            }\n                        } else { // 'L'\n                            // Fix y based on b\n                            if (b == -1) {\n                                yi = 0;\n                            } else {\n                                double hb = rot[b] ? w_est[b] : h_est[b];\n                                yi = y[b] + hb;\n                            }\n                            \n                            // Find x by checking overlaps\n                            xi = 0;\n                            for (int j = 0; j < i; j++) {\n                                double xj = x[j];\n                                double wj = rot[j] ? h_est[j] : w_est[j];\n                                double yj = y[j];\n                                double hj = rot[j] ? w_est[j] : h_est[j];\n                                \n                                // Check y-overlap: [yi, yi+hi) vs [yj, yj+hj)\n                                if (max(yi, yj) < min(yi + hi, yj + hj)) {\n                                    xi = max(xi, xj + wj);\n                                }\n                            }\n                        }\n                        \n                        double new_W = max(cur_W, xi + wi);\n                        double new_H = max(cur_H, yi + hi);\n                        double score = new_W + new_H;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            best_x = xi;\n                            best_y = yi;\n                        }\n                    }\n                }\n            }\n            \n            rot[i] = best_r;\n            x[i] = best_x;\n            y[i] = best_y;\n            ops.push_back({i, best_r, best_b, best_d});\n            \n            double wi = best_r ? h_est[i] : w_est[i];\n            double hi = best_r ? w_est[i] : h_est[i];\n            cur_W = max(cur_W, best_x + wi);\n            cur_H = max(cur_H, best_y + hi);\n        }\n        \n        // Output\n        cout << N << \"\\n\";\n        for (const auto& op : ops) {\n            cout << op.p << \" \" << op.r << \" \" << op.d << \" \" << op.b << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read feedback\n        double Wp, Hp;\n        cin >> Wp >> Hp;\n        \n        // Update estimates based on feedback\n        // Compute current max based on estimates\n        double max_right = 0;\n        double max_bottom = 0;\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            max_right = max(max_right, x[i] + wi);\n            max_bottom = max(max_bottom, y[i] + hi);\n        }\n        \n        // Update width estimates for critical rectangles\n        for (int i = 0; i < N; i++) {\n            double wi = rot[i] ? h_est[i] : w_est[i];\n            double hi = rot[i] ? w_est[i] : h_est[i];\n            \n            // Check if this rectangle determines the width boundary\n            if (abs(x[i] + wi - max_right) < 1e-6) {\n                double target = Wp - x[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                } else {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                }\n            }\n            \n            // Check if this rectangle determines the height boundary\n            if (abs(y[i] + hi - max_bottom) < 1e-6) {\n                double target = Hp - y[i];\n                if (target < 1) target = 1;\n                if (rot[i]) {\n                    w_est[i] = 0.5 * w_est[i] + 0.5 * target;\n                } else {\n                    h_est[i] = 0.5 * h_est[i] + 0.5 * target;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> parent;\n    vector<int> depth;\n    vector<long long> sub_sum;\n    vector<int> height;\n    vector<vector<int>> children;\n    \n    void input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; i++) cin >> A[i];\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v; cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // Skip coordinates\n        for (int i = 0; i < N; i++) {\n            int x, y; cin >> x >> y;\n        }\n    }\n    \n    // Compute sub_sum and height for tree rooted at root\n    void dfs_info(int v) {\n        sub_sum[v] = A[v];\n        height[v] = 0;\n        for (int c : children[v]) {\n            dfs_info(c);\n            sub_sum[v] += sub_sum[c];\n            height[v] = max(height[v], height[c] + 1);\n        }\n    }\n    \n    void compute_all_info() {\n        children.assign(N, {});\n        for (int i = 0; i < N; i++) {\n            if (parent[i] != -1) {\n                children[parent[i]].push_back(i);\n            }\n        }\n        sub_sum.assign(N, 0);\n        height.assign(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) {\n                dfs_info(i);\n            }\n        }\n    }\n    \n    long long calc_score() {\n        long long res = 0;\n        for (int i = 0; i < N; i++) {\n            res += (long long)(depth[i] + 1) * A[i];\n        }\n        return res;\n    }\n    \n    bool is_ancestor(int u, int v) {\n        // check if u is ancestor of v\n        int cur = v;\n        while (cur != -1) {\n            if (cur == u) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n    \n    void update_depths(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) {\n            update_depths(c, delta);\n        }\n    }\n    \n    void greedy_construct() {\n        parent.assign(N, -1);\n        depth.assign(N, -1);\n        vector<long long> path_sum(N, 0);\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return A[i] > A[j];\n        });\n        \n        for (int v : order) {\n            int best_parent = -1;\n            int best_depth = -1;\n            long long best_path_sum = -1;\n            \n            for (int u : adj[v]) {\n                if (depth[u] != -1 && depth[u] < H) {\n                    if (depth[u] > best_depth || (depth[u] == best_depth && path_sum[u] > best_path_sum)) {\n                        best_depth = depth[u];\n                        best_parent = u;\n                        best_path_sum = path_sum[u];\n                    }\n                }\n            }\n            \n            if (best_parent == -1) {\n                parent[v] = -1;\n                depth[v] = 0;\n                path_sum[v] = A[v];\n            } else {\n                parent[v] = best_parent;\n                depth[v] = depth[best_parent] + 1;\n                path_sum[v] = path_sum[best_parent] + A[v];\n            }\n        }\n    }\n    \n    void local_search() {\n        // Steepest ascent local search\n        bool improved = true;\n        int max_iter = 50;\n        int iter = 0;\n        \n        while (improved && iter < max_iter) {\n            improved = false;\n            iter++;\n            \n            // Try all possible moves and pick the best\n            long long best_gain = 0;\n            int best_v = -1, best_new_parent = -1;\n            \n            // Randomize order to avoid bias\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            random_shuffle(order.begin(), order.end());\n            \n            for (int v : order) {\n                int cur_depth = depth[v];\n                long long cur_sub = sub_sum[v];\n                int cur_height = height[v];\n                \n                // Try all neighbors as new parent\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (depth[u] == -1) continue; // should not happen after greedy\n                    if (depth[u] >= H) continue; // cannot be parent\n                    \n                    int new_depth = depth[u] + 1;\n                    if (new_depth <= cur_depth) continue; // no improvement in depth\n                    \n                    // Check if u is in subtree of v (would create cycle)\n                    if (is_ancestor(v, u)) continue;\n                    \n                    // Check height constraint: new_depth + height[v] <= H\n                    if (new_depth + cur_height > H) continue;\n                    \n                    long long gain = (long long)(new_depth - cur_depth) * cur_sub;\n                    \n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_v = v;\n                        best_new_parent = u;\n                    }\n                }\n            }\n            \n            if (best_gain > 0) {\n                // Apply the move\n                int v = best_v;\n                int u = best_new_parent;\n                int old_parent = parent[v];\n                \n                // Remove from old parent\n                if (old_parent != -1) {\n                    auto& vec = children[old_parent];\n                    vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n                }\n                \n                // Add to new parent\n                parent[v] = u;\n                children[u].push_back(v);\n                \n                // Update depths for subtree v\n                int delta = depth[u] + 1 - depth[v];\n                update_depths(v, delta);\n                \n                // Recompute all info (sub_sum, height) from roots\n                // This is necessary because sub_sum and height of ancestors changed\n                compute_all_info();\n                \n                improved = true;\n            }\n        }\n    }\n    \n    void solve() {\n        input();\n        greedy_construct();\n        compute_all_info();\n        local_search();\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            if (i) cout << \" \";\n            cout << parent[i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // For local search randomization\n    srand(time(0));\n    \n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<string> C(N);\n    for (int i = 0; i < N; i++) cin >> C[i];\n    \n    vector<vector<bool>> is_oni(N, vector<bool>(N, false));\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (C[i][j] == 'x') {\n                is_oni[i][j] = true;\n            } else if (C[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    // Precompute safe ranges for each column\n    vector<int> max_up(N, -1);    // max row where Up is safe (no fuku in [0, row])\n    vector<int> min_down(N, N);   // min row where Down is safe (no fuku in [row, N-1])\n    \n    for (int j = 0; j < N; j++) {\n        int first_fuku = N;\n        for (int i = 0; i < N; i++) {\n            if (is_fuku[i][j]) {\n                first_fuku = i;\n                break;\n            }\n        }\n        max_up[j] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int i = N-1; i >= 0; i--) {\n            if (is_fuku[i][j]) {\n                last_fuku = i;\n                break;\n            }\n        }\n        min_down[j] = last_fuku + 1;\n    }\n    \n    // Precompute safe ranges for each row\n    vector<int> max_left(N, -1);  // max col where Left is safe\n    vector<int> min_right(N, N);  // min col where Right is safe\n    \n    for (int i = 0; i < N; i++) {\n        int first_fuku = N;\n        for (int j = 0; j < N; j++) {\n            if (is_fuku[i][j]) {\n                first_fuku = j;\n                break;\n            }\n        }\n        max_left[i] = first_fuku - 1;\n        \n        int last_fuku = -1;\n        for (int j = N-1; j >= 0; j--) {\n            if (is_fuku[i][j]) {\n                last_fuku = j;\n                break;\n            }\n        }\n        min_right[i] = last_fuku + 1;\n    }\n    \n    vector<pair<char, int>> ops;\n    \n    while (true) {\n        double best_eff = -1.0;\n        int best_gain = 0;\n        int best_cost = 0;\n        char best_dir = 0;\n        int best_idx = 0;\n        int best_limit = 0; // row for U/D, col for L/R\n        \n        // Check columns for Up\n        for (int j = 0; j < N; j++) {\n            if (max_up[j] < 0) continue;\n            int highest = -1;\n            int count = 0;\n            for (int i = 0; i <= max_up[j]; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    highest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (highest + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost) || best_gain == 0) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'U';\n                best_idx = j;\n                best_limit = highest;\n            }\n        }\n        \n        // Check columns for Down\n        for (int j = 0; j < N; j++) {\n            if (min_down[j] >= N) continue;\n            int lowest = N;\n            int count = 0;\n            for (int i = min_down[j]; i < N; i++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    lowest = i;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - lowest);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'D';\n                best_idx = j;\n                best_limit = lowest;\n            }\n        }\n        \n        // Check rows for Left\n        for (int i = 0; i < N; i++) {\n            if (max_left[i] < 0) continue;\n            int rightmost = -1;\n            int count = 0;\n            for (int j = 0; j <= max_left[i]; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    rightmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (rightmost + 1);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'L';\n                best_idx = i;\n                best_limit = rightmost;\n            }\n        }\n        \n        // Check rows for Right\n        for (int i = 0; i < N; i++) {\n            if (min_right[i] >= N) continue;\n            int leftmost = N;\n            int count = 0;\n            for (int j = min_right[i]; j < N; j++) {\n                if (is_oni[i][j]) {\n                    count++;\n                    leftmost = j;\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - leftmost);\n            double eff = (double)count / cost;\n            if (eff > best_eff || (eff == best_eff && cost < best_cost)) {\n                best_eff = eff;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'R';\n                best_idx = i;\n                best_limit = leftmost;\n            }\n        }\n        \n        if (best_gain == 0) break; // No more Oni\n        \n        // Apply the best operation\n        if (best_dir == 'U') {\n            int j = best_idx;\n            int h = best_limit;\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('U', j);\n            for (int k = 0; k < h + 1; k++) ops.emplace_back('D', j);\n            for (int i = 0; i <= h; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'D') {\n            int j = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('D', j);\n            for (int k = 0; k < times; k++) ops.emplace_back('U', j);\n            for (int i = l; i < N; i++) is_oni[i][j] = false;\n        } else if (best_dir == 'L') {\n            int i = best_idx;\n            int r = best_limit;\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('L', i);\n            for (int k = 0; k < r + 1; k++) ops.emplace_back('R', i);\n            for (int j = 0; j <= r; j++) is_oni[i][j] = false;\n        } else if (best_dir == 'R') {\n            int i = best_idx;\n            int l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) ops.emplace_back('R', i);\n            for (int k = 0; k < times; k++) ops.emplace_back('L', i);\n            for (int j = l; j < N; j++) is_oni[i][j] = false;\n        }\n    }\n    \n    // Output\n    for (auto &[d, p] : ops) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const auto START = chrono::steady_clock::now();\n    const int TL_MS = 1980; // Use almost full time\n    auto elapsed = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n            chrono::steady_clock::now() - START).count();\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_err = (1LL << 60);\n    \n    auto evaluate = [&](const vector<int>& a, const vector<int>& b, vector<int>& cnt) -> long long {\n        fill(cnt.begin(), cnt.end(), 0);\n        int cur = 0;\n        for (int week = 0; week < L; ++week) {\n            cnt[cur]++;\n            if (week == L - 1) break;\n            cur = (cnt[cur] & 1) ? a[cur] : b[cur];\n        }\n        long long err = 0;\n        for (int i = 0; i < N; ++i) err += llabs((long long)cnt[i] - T[i]);\n        return err;\n    };\n    \n    // Greedy init with randomization\n    auto greedy_init = [&](int seed) {\n        mt19937 gen(seed);\n        vector<int> a(N), b(N);\n        vector<long long> rem(N);\n        for (int i = 0; i < N; ++i) rem[i] = T[i];\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), gen);\n        \n        for (int idx : order) {\n            auto get_max = [&]() {\n                long long mx = *max_element(rem.begin(), rem.end());\n                vector<int> cands;\n                for (int j = 0; j < N; ++j) if (rem[j] == mx) cands.push_back(j);\n                return cands[uniform_int_distribution<int>(0, cands.size()-1)(gen)];\n            };\n            \n            int ja = get_max();\n            a[idx] = ja;\n            rem[ja] -= (T[idx] + 1) / 2;\n            \n            int jb = get_max();\n            b[idx] = jb;\n            rem[jb] -= T[idx] / 2;\n        }\n        return make_pair(a, b);\n    };\n    \n    // Local search with various move types\n    auto local_search = [&](vector<int> a, vector<int> b, int seed, bool use_sa) {\n        mt19937 gen(seed);\n        vector<int> cnt(N);\n        long long cur = evaluate(a, b, cnt);\n        \n        if (cur < best_err) {\n            best_err = cur;\n            best_a = a;\n            best_b = b;\n        }\n        \n        double temp = cur / 100.0;\n        const double cooling = 0.99995;\n        \n        while (elapsed() < TL_MS) {\n            vector<int> na = a, nb = b;\n            int move_type = uniform_int_distribution<int>(0, 99)(gen);\n            \n            if (move_type < 60) {\n                // Random change\n                int i = uniform_int_distribution<int>(0, N-1)(gen);\n                int t = uniform_int_distribution<int>(0, 2)(gen);\n                if (t == 0) na[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else if (t == 1) nb[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else swap(na[i], nb[i]);\n            } else if (move_type < 80) {\n                // Swap two edges\n                int i = uniform_int_distribution<int>(0, N-1)(gen);\n                int j = uniform_int_distribution<int>(0, N-1)(gen);\n                if (i == j) continue;\n                int t = uniform_int_distribution<int>(0, 3)(gen);\n                if (t == 0) swap(na[i], na[j]);\n                else if (t == 1) swap(nb[i], nb[j]);\n                else if (t == 2) swap(na[i], nb[j]);\n                else swap(nb[i], na[j]);\n            } else {\n                // Targeted: fix high error nodes\n                int worst = 0;\n                long long worst_err = 0;\n                for (int i = 0; i < N; ++i) {\n                    long long e = llabs((long long)cnt[i] - T[i]);\n                    if (e > worst_err) {\n                        worst_err = e;\n                        worst = i;\n                    }\n                }\n                \n                // If worst is deficit, find someone to point to it\n                // If worst is surplus, redirect away from it\n                if (cnt[worst] < T[worst]) {\n                    // Deficit: need more incoming\n                    vector<pair<int, bool>> edges; // (from, is_a)\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] != worst) edges.push_back({i, true});\n                        if (b[i] != worst) edges.push_back({i, false});\n                    }\n                    if (!edges.empty()) {\n                        auto [from, is_a] = edges[uniform_int_distribution<int>(0, edges.size()-1)(gen)];\n                        if (is_a) na[from] = worst;\n                        else nb[from] = worst;\n                    }\n                } else {\n                    // Surplus: redirect away\n                    vector<pair<int, bool>> edges;\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] == worst) edges.push_back({i, true});\n                        if (b[i] == worst) edges.push_back({i, false});\n                    }\n                    if (!edges.empty()) {\n                        auto [from, is_a] = edges[uniform_int_distribution<int>(0, edges.size()-1)(gen)];\n                        int to = uniform_int_distribution<int>(0, N-1)(gen);\n                        while (to == worst) to = uniform_int_distribution<int>(0, N-1)(gen);\n                        if (is_a) na[from] = to;\n                        else nb[from] = to;\n                    }\n                }\n            }\n            \n            vector<int> ncnt(N);\n            long long nerr = evaluate(na, nb, ncnt);\n            \n            bool accept = false;\n            if (nerr < cur) accept = true;\n            else if (use_sa && temp > 0.1) {\n                // Simulated annealing acceptance\n                double prob = exp((cur - nerr) / temp);\n                if (uniform_real_distribution<double>(0, 1)(gen) < prob) accept = true;\n            }\n            \n            if (accept) {\n                a = na;\n                b = nb;\n                cur = nerr;\n                cnt = ncnt;\n                if (cur < best_err) {\n                    best_err = cur;\n                    best_a = a;\n                    best_b = b;\n                }\n            }\n            \n            if (use_sa) temp *= cooling;\n        }\n    };\n    \n    // Run multiple seeds with hill climbing\n    vector<int> seeds = {42, 123, 456, 789, 1011, 1213, 1415, 1617, 1819, 2021, 2223, 2425};\n    for (int s : seeds) {\n        if (elapsed() >= TL_MS) break;\n        auto [a, b] = greedy_init(s);\n        local_search(a, b, s, false); // Hill climbing only\n    }\n    \n    // Final refinement with SA from best solution\n    if (elapsed() < TL_MS) {\n        auto a = best_a, b = best_b;\n        // Perturb\n        mt19937 perturb_rng(9999);\n        for (int i = 0; i < N/10; ++i) {\n            int idx = uniform_int_distribution<int>(0, N-1)(perturb_rng);\n            if (uniform_int_distribution<int>(0, 1)(perturb_rng) == 0)\n                a[idx] = uniform_int_distribution<int>(0, N-1)(perturb_rng);\n            else\n                b[idx] = uniform_int_distribution<int>(0, N-1)(perturb_rng);\n        }\n        local_search(a, b, 9999, true); // With SA\n    }\n    \n    // Final greedy hill climbing to clean up\n    if (elapsed() < TL_MS) {\n        local_search(best_a, best_b, 7777, false);\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Hilbert curve order for spatial locality\nlong long hilbertOrder(int x, int y, int pow = 16, int rot = 0) {\n    if (pow == 0) return 0;\n    int h = 1 << (pow - 1);\n    int seg = (x < h ? (y < h ? 0 : 3) : (y < h ? 1 : 2));\n    seg = (seg + rot) & 3;\n    static const int rotateDelta[4] = {3, 0, 0, 1};\n    int nx = x & (h - 1), ny = y & (h - 1);\n    int nrot = (rot + rotateDelta[seg]) & 3;\n    long long subSquareSize = 1LL << (2 * pow - 2);\n    long long ord = seg * subSquareSize;\n    long long add = hilbertOrder(nx, ny, pow - 1, nrot);\n    ord += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);\n    return ord;\n}\n\n// DSU for Kruskal\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n) { p.resize(n); r.resize(n); iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Estimated centers\n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n    \n    // Recursive bisection for grouping\n    vector<vector<int>> groups(M);\n    function<void(vector<int>&, int, int, int)> partition = [&](vector<int>& ids, int gl, int gr, int depth) {\n        if (gl + 1 == gr) {\n            for (int id : ids) groups[gl].push_back(id);\n            return;\n        }\n        int gmid = (gl + gr) / 2;\n        int leftSize = 0;\n        for (int i = gl; i < gmid; ++i) leftSize += G[i];\n        \n        if (depth % 2 == 0) {\n            sort(ids.begin(), ids.end(), [&](int a, int b) { return cx[a] < cx[b]; });\n        } else {\n            sort(ids.begin(), ids.end(), [&](int a, int b) { return cy[a] < cy[b]; });\n        }\n        \n        vector<int> left(ids.begin(), ids.begin() + leftSize);\n        vector<int> right(ids.begin() + leftSize, ids.end());\n        partition(left, gl, gmid, depth + 1);\n        partition(right, gmid, gr, depth + 1);\n    };\n    \n    vector<int> allIds(N);\n    iota(allIds.begin(), allIds.end(), 0);\n    partition(allIds, 0, M, 0);\n    \n    // Collect all candidate edges\n    vector<tuple<long long, int, int>> candidateEdges; // (estimatedDist, u, v)\n    // Map to avoid duplicates\n    set<pair<int, int>> edgeSet;\n    \n    int queriesUsed = 0;\n    \n    auto addEdge = [&](int u, int v) {\n        if (u > v) swap(u, v);\n        if (edgeSet.count({u, v})) return;\n        edgeSet.insert({u, v});\n        long long dx = cx[u] - cx[v];\n        long long dy = cy[u] - cy[v];\n        long long d2 = dx * dx + dy * dy;\n        candidateEdges.push_back({d2, u, v});\n    };\n    \n    // Phase 1: Backbone with Hilbert sliding window (ensures connectivity)\n    for (int gi = 0; gi < M && queriesUsed < Q; ++gi) {\n        auto &grp = groups[gi];\n        int gsize = grp.size();\n        if (gsize <= 1) continue;\n        \n        sort(grp.begin(), grp.end(), [&](int a, int b) {\n            return hilbertOrder(cx[a], cy[a]) < hilbertOrder(cx[b], cy[b]);\n        });\n        \n        for (int i = 0; i < gsize - 1 && queriesUsed < Q; i += L - 1) {\n            int batchSize = min(L, gsize - i);\n            vector<int> querySet;\n            for (int j = 0; j < batchSize; ++j) querySet.push_back(grp[i + j]);\n            \n            cout << \"? \" << batchSize;\n            for (int v : querySet) cout << ' ' << v;\n            cout << '\\n';\n            cout.flush();\n            ++queriesUsed;\n            \n            for (int j = 0; j < batchSize - 1; ++j) {\n                int a, b; cin >> a >> b;\n                addEdge(a, b);\n            }\n        }\n    }\n    \n    // Phase 2: Local neighborhood queries (improve edge quality)\n    // For each city, query with its L-1 nearest neighbors\n    // Prioritize cities in larger groups or with fewer edges so far\n    vector<pair<int, int>> cityPriority; // (groupSize, city)\n    for (int gi = 0; gi < M; ++gi) {\n        for (int v : groups[gi]) {\n            cityPriority.push_back({-(int)groups[gi].size(), v}); // negative for larger first\n        }\n    }\n    sort(cityPriority.begin(), cityPriority.end());\n    \n    for (auto &[gsize, v] : cityPriority) {\n        if (queriesUsed >= Q) break;\n        \n        // Find L-1 nearest neighbors in the same group\n        int gi = -1;\n        for (int i = 0; i < M; ++i) {\n            if (find(groups[i].begin(), groups[i].end(), v) != groups[i].end()) {\n                gi = i; break;\n            }\n        }\n        if (gi == -1) continue;\n        \n        auto &grp = groups[gi];\n        vector<pair<long long, int>> neighbors;\n        for (int u : grp) {\n            if (u == v) continue;\n            long long dx = cx[u] - cx[v];\n            long long dy = cy[u] - cy[v];\n            neighbors.push_back({dx*dx + dy*dy, u});\n        }\n        sort(neighbors.begin(), neighbors.end());\n        \n        int k = min(L - 1, (int)neighbors.size());\n        if (k < 1) continue;\n        \n        vector<int> querySet = {v};\n        for (int i = 0; i < k; ++i) querySet.push_back(neighbors[i].second);\n        \n        cout << \"? \" << (int)querySet.size();\n        for (int x : querySet) cout << ' ' << x;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < (int)querySet.size() - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Phase 3: If queries remain, do random local queries within groups\n    mt19937 rng(12345);\n    while (queriesUsed < Q) {\n        // Pick a random group\n        int gi = rng() % M;\n        if (groups[gi].size() < 2) continue;\n        \n        // Pick L random cities from this group\n        vector<int> pool = groups[gi];\n        shuffle(pool.begin(), pool.end(), rng);\n        int sz = min(L, (int)pool.size());\n        vector<int> querySet(pool.begin(), pool.begin() + sz);\n        \n        cout << \"? \" << sz;\n        for (int v : querySet) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < sz - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Build MST using Kruskal on collected edges\n    sort(candidateEdges.begin(), candidateEdges.end());\n    DSU dsu(N);\n    vector<vector<pair<int,int>>> groupEdges(M);\n    vector<int> groupOf(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int v : groups[i]) groupOf[v] = i;\n    }\n    \n    for (auto &[d2, u, v] : candidateEdges) {\n        if (dsu.find(u) != dsu.find(v)) {\n            dsu.unite(u, v);\n            int gi = groupOf[u];\n            groupEdges[gi].push_back({u, v});\n        }\n    }\n    \n    // Output\n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << ' ';\n            cout << grp[i];\n        }\n        cout << '\\n';\n        for (auto [a, b] : groupEdges[gi]) {\n            cout << a << ' ' << b << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.emplace_back(r, c);\n    }\n    \n    vector<pair<char,char>> ans;\n    auto add_move = [&](char d, int cnt) {\n        for (int i = 0; i < cnt; i++) ans.emplace_back('M', d);\n    };\n    auto add_slide = [&](char d) {\n        ans.emplace_back('S', d);\n    };\n    \n    int cr = r0, cc = c0;\n    const int MAXC = N - 1; // 19\n    \n    for (auto [tr, tc] : targets) {\n        int dr = tr - cr;\n        int dc = tc - cc;\n        int abs_dr = abs(dr);\n        int abs_dc = abs(dc);\n        \n        // Direct Manhattan\n        int best_cost = abs_dr + abs_dc;\n        int strategy = 0; // 0=direct, 1=top, 2=bot, 3=left, 4=right, 5=corner\n        \n        // Via Top: slide up to row 0, walk horiz, walk down to tr\n        int cost_top = 1 + abs_dc + tr;\n        if (cost_top < best_cost) {\n            best_cost = cost_top;\n            strategy = 1;\n        }\n        \n        // Via Bottom: slide down to row 19, walk horiz, walk up to tr\n        int cost_bot = 1 + abs_dc + (MAXC - tr);\n        if (cost_bot < best_cost) {\n            best_cost = cost_bot;\n            strategy = 2;\n        }\n        \n        // Via Left: slide left to col 0, walk vert, walk right to tc\n        int cost_left = 1 + abs_dr + tc;\n        if (cost_left < best_cost) {\n            best_cost = cost_left;\n            strategy = 3;\n        }\n        \n        // Via Right: slide right to col 19, walk vert, walk left to tc\n        int cost_right = 1 + abs_dr + (MAXC - tc);\n        if (cost_right < best_cost) {\n            best_cost = cost_right;\n            strategy = 4;\n        }\n        \n        // Via Corner: 2 slides to a corner, then walk\n        int dist_from_corner = min(tr, MAXC - tr) + min(tc, MAXC - tc);\n        int cost_corner = 2 + dist_from_corner;\n        if (cost_corner < best_cost) {\n            best_cost = cost_corner;\n            strategy = 5;\n        }\n        \n        if (strategy == 0) {\n            // Direct: move vertical then horizontal (order doesn't matter)\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n        } else if (strategy == 1) {\n            // Via top\n            add_slide('U');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('D', tr); // down from row 0 to tr\n        } else if (strategy == 2) {\n            // Via bottom\n            add_slide('D');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('U', MAXC - tr); // up from row 19 to tr\n        } else if (strategy == 3) {\n            // Via left\n            add_slide('L');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('R', tc); // right from col 0 to tc\n        } else if (strategy == 4) {\n            // Via right\n            add_slide('R');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('L', MAXC - tc); // left from col 19 to tc\n        } else if (strategy == 5) {\n            // Via best corner\n            // Determine which corner is best (gives min walking distance)\n            int best_corner = 0; // 0:TL, 1:TR, 2:BL, 3:BR\n            int best_corner_cost = 1000;\n            // TL (0,0): walk down tr, right tc. Cost: tr + tc\n            if (tr + tc < best_corner_cost) { best_corner_cost = tr + tc; best_corner = 0; }\n            // TR (0,19): down tr, left (19-tc)\n            if (tr + (MAXC - tc) < best_corner_cost) { best_corner_cost = tr + (MAXC - tc); best_corner = 1; }\n            // BL (19,0): up (19-tr), right tc\n            if ((MAXC - tr) + tc < best_corner_cost) { best_corner_cost = (MAXC - tr) + tc; best_corner = 2; }\n            // BR (19,19): up (19-tr), left (19-tc)\n            if ((MAXC - tr) + (MAXC - tc) < best_corner_cost) { best_corner_cost = (MAXC - tr) + (MAXC - tc); best_corner = 3; }\n            \n            if (best_corner == 0) {\n                add_slide('U');\n                add_slide('L');\n                add_move('D', tr);\n                add_move('R', tc);\n            } else if (best_corner == 1) {\n                add_slide('U');\n                add_slide('R');\n                add_move('D', tr);\n                add_move('L', MAXC - tc);\n            } else if (best_corner == 2) {\n                add_slide('D');\n                add_slide('L');\n                add_move('U', MAXC - tr);\n                add_move('R', tc);\n            } else {\n                add_slide('D');\n                add_slide('R');\n                add_move('U', MAXC - tr);\n                add_move('L', MAXC - tc);\n            }\n        }\n        \n        cr = tr;\n        cc = tc;\n    }\n    \n    for (auto [a, d] : ans) {\n        cout << a << ' ' << d << \"\\n\";\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int l, r, b, t;\n    long long area() const { return 1LL * (r - l) * (t - b); }\n    bool contains(int x, int y) const { return l <= x && x < r && b <= y && y < t; }\n};\n\nint n;\nvector<int> X, Y, R;\nvector<Rect> best_rects;\ndouble best_score = -1.0;\n\n// ---------- Guillotine Tree Structures ----------\nstruct Node {\n    bool leaf = false;\n    int idx = -1;\n    bool vert = false;\n    int child[2] = {-1, -1};\n    int cut = 0;\n    int min_x = 10000, max_x = -1;\n    int min_y = 10000, max_y = -1;\n    long long sum_r = 0;\n};\n\nvector<Node> tree;\nvector<int> cur_x1, cur_y1, cur_x2, cur_y2;\n\nint build(vector<int>& ids, mt19937& rng) {\n    Node node;\n    for (int id : ids) {\n        node.min_x = min(node.min_x, X[id]);\n        node.max_x = max(node.max_x, X[id]);\n        node.min_y = min(node.min_y, Y[id]);\n        node.max_y = max(node.max_y, Y[id]);\n        node.sum_r += R[id];\n    }\n    if ((int)ids.size() == 1) {\n        node.leaf = true;\n        node.idx = ids[0];\n        int id = (int)tree.size();\n        tree.push_back(node);\n        return id;\n    }\n    int dx = node.max_x - node.min_x;\n    int dy = node.max_y - node.min_y;\n    bool vert = (dx >= dy);\n    if (abs(dx - dy) < 2000) vert = (rng() & 1); // diversify\n\n    if (vert) sort(ids.begin(), ids.end(), [&](int a, int b){ return X[a] < X[b]; });\n    else      sort(ids.begin(), ids.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n    long long half = node.sum_r / 2;\n    long long cur = 0;\n    int split_pos = 1;\n    for (int i = 0; i < (int)ids.size(); ++i) {\n        cur += R[ids[i]];\n        if (cur >= half && i + 1 < (int)ids.size()) {\n            split_pos = i + 1;\n            break;\n        }\n    }\n    vector<int> left(ids.begin(), ids.begin() + split_pos);\n    vector<int> right(ids.begin() + split_pos, ids.end());\n\n    node.vert = vert;\n    int nid = (int)tree.size();\n    tree.push_back(node);\n    int lch = build(left, rng);\n    int rch = build(right, rng);\n    tree[nid].child[0] = lch;\n    tree[nid].child[1] = rch;\n    return nid;\n}\n\ndouble recalc(int v, int x1, int y1, int x2, int y2, vector<Rect>& rects) {\n    cur_x1[v] = x1; cur_y1[v] = y1; cur_x2[v] = x2; cur_y2[v] = y2;\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        long long s = rects[node.idx].area();\n        long long r = R[node.idx];\n        double ratio = (s <= r) ? (double)s / r : (double)r / s;\n        double d = 1.0 - ratio;\n        return 1.0 - d * d;\n    }\n    double sum = 0.0;\n    if (node.vert) {\n        sum += recalc(node.child[0], x1, y1, node.cut, y2, rects);\n        sum += recalc(node.child[1], node.cut, y1, x2, y2, rects);\n    } else {\n        sum += recalc(node.child[0], x1, y1, x2, node.cut, rects);\n        sum += recalc(node.child[1], x1, node.cut, x2, y2, rects);\n    }\n    return sum;\n}\n\nvoid init_cuts(int v, int x1, int y1, int x2, int y2, vector<Rect>& rects) {\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        return;\n    }\n    int lch = node.child[0], rch = node.child[1];\n    if (node.vert) {\n        int lo = max(x1, tree[lch].max_x + 1);\n        int hi = min(x2, tree[rch].min_x);\n        if (lo > hi) lo = hi = (x1 + x2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(x1 + (x2 - x1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, node.cut, y2, rects);\n        init_cuts(rch, node.cut, y1, x2, y2, rects);\n    } else {\n        int lo = max(y1, tree[lch].max_y + 1);\n        int hi = min(y2, tree[rch].min_y);\n        if (lo > hi) lo = hi = (y1 + y2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(y1 + (y2 - y1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, x2, node.cut, rects);\n        init_cuts(rch, x1, node.cut, x2, y2, rects);\n    }\n}\n\n// ---------- Phase 1: Guillotine SA ----------\nvoid solve_guillotine(mt19937& rng, double time_limit) {\n    tree.clear();\n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    int root = build(ids, rng);\n\n    vector<Rect> rects(n);\n    init_cuts(root, 0, 0, 10000, 10000, rects);\n    cur_x1.assign(tree.size(), 0);\n    cur_y1.assign(tree.size(), 0);\n    cur_x2.assign(tree.size(), 0);\n    cur_y2.assign(tree.size(), 0);\n\n    double cur_score = recalc(root, 0, 0, 10000, 10000, rects);\n    vector<Rect> local_best_rects = rects;\n    double local_best_score = cur_score;\n\n    vector<int> inodes;\n    for (int i = 0; i < (int)tree.size(); ++i) if (!tree[i].leaf) inodes.push_back(i);\n    if (inodes.empty()) {\n        if (cur_score > best_score) { best_score = cur_score; best_rects = rects; }\n        return;\n    }\n\n    uniform_int_distribution<int> pick_node(0, (int)inodes.size() - 1);\n    uniform_real_distribution<double> uni(0.0, 1.0);\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n\n        double progress = elapsed / time_limit;\n        double T = pow(0.0001, progress);\n\n        int v = inodes[pick_node(rng)];\n        Node& node = tree[v];\n        int x1 = cur_x1[v], y1 = cur_y1[v], x2 = cur_x2[v], y2 = cur_y2[v];\n        int lo, hi;\n        if (node.vert) {\n            lo = max(x1, tree[node.child[0]].max_x + 1);\n            hi = min(x2, tree[node.child[1]].min_x);\n        } else {\n            lo = max(y1, tree[node.child[0]].max_y + 1);\n            hi = min(y2, tree[node.child[1]].min_y);\n        }\n        if (lo >= hi) continue;\n\n        int old = node.cut;\n        int proposal;\n        if (uni(rng) < 0.5) {\n            int range = hi - lo;\n            int max_step = max(1, (int)(range * T * 0.1));\n            uniform_int_distribution<int> d(-max_step, max_step);\n            proposal = old + d(rng);\n        } else {\n            uniform_int_distribution<int> d(lo, hi);\n            proposal = d(rng);\n        }\n        proposal = clamp(proposal, lo, hi);\n        if (proposal == old) continue;\n\n        node.cut = proposal;\n        double new_score = recalc(root, 0, 0, 10000, 10000, rects);\n        double delta = new_score - cur_score;\n\n        if (delta > 0.0 || exp(delta / T) > uni(rng)) {\n            cur_score = new_score;\n            if (cur_score > local_best_score) {\n                local_best_score = cur_score;\n                local_best_rects = rects;\n            }\n        } else {\n            node.cut = old;\n            recalc(root, 0, 0, 10000, 10000, rects);\n        }\n    }\n\n    if (local_best_score > best_score) {\n        best_score = local_best_score;\n        best_rects = local_best_rects;\n    }\n}\n\n// ---------- Phase 2: Edge-based Polish (Non-guillotine) ----------\nbool valid_edge_move(const vector<Rect>& rects, int i, const Rect& nr) {\n    if (nr.l < 0 || nr.r > 10000 || nr.b < 0 || nr.t > 10000) return false;\n    if (!nr.contains(X[i], Y[i])) return false;\n    for (int j = 0; j < n; ++j) if (j != i) {\n        const Rect& o = rects[j];\n        if (max(nr.l, o.l) < min(nr.r, o.r) && max(nr.b, o.b) < min(nr.t, o.t))\n            return false;\n    }\n    return true;\n}\n\ndouble score_rect(int i, const Rect& rc) {\n    long long s = rc.area();\n    long long r = R[i];\n    double ratio = (s <= r) ? (double)s / r : (double)r / s;\n    double d = 1.0 - ratio;\n    return 1.0 - d * d;\n}\n\nvoid polish_edges(mt19937& rng, double time_limit) {\n    if (best_rects.empty()) return;\n    vector<Rect> rects = best_rects;\n    double cur_score = 0;\n    for (int i = 0; i < n; ++i) cur_score += score_rect(i, rects[i]);\n\n    uniform_int_distribution<int> pick_rect(0, n - 1);\n    uniform_int_distribution<int> pick_side(0, 3); // 0:L,1:R,2:B,3:T\n    uniform_int_distribution<int> pick_dir(0, 1);  // 0:+, 1:-\n    uniform_real_distribution<double> uni(0.0, 1.0);\n\n    auto start = chrono::steady_clock::now();\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n\n        double T = 0.01 * (1.0 - elapsed / time_limit); // Linear cool from 0.01 to 0\n\n        int i = pick_rect(rng);\n        int side = pick_side(rng);\n        int delta = (pick_dir(rng) == 0) ? 1 : -1;\n\n        Rect nr = rects[i];\n        if (side == 0) nr.l += delta;\n        else if (side == 1) nr.r += delta;\n        else if (side == 2) nr.b += delta;\n        else nr.t += delta;\n\n        if (!valid_edge_move(rects, i, nr)) continue;\n\n        double old_s = score_rect(i, rects[i]);\n        double new_s = score_rect(i, nr);\n        double delta_sc = new_s - old_s;\n\n        if (delta_sc > 0 || (T > 1e-9 && exp(delta_sc / T) > uni(rng))) {\n            cur_score += delta_sc;\n            rects[i] = nr;\n        }\n    }\n    if (cur_score > best_score) {\n        best_score = cur_score;\n        best_rects = rects;\n    }\n}\n\n// ---------- Main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    const double TOTAL_TL = 4.9;\n    const int ATTEMPTS = 3;\n    const double TIME_GUill = TOTAL_TL * 0.9 / ATTEMPTS; // 1.47s per guillotine\n    const double TIME_POLISH = TOTAL_TL * 0.1;           // 0.49s final polish\n\n    for (int att = 0; att < ATTEMPTS; ++att) {\n        uint64_t seed = 1234567ULL + att * 999983ULL +\n                        chrono::steady_clock::now().time_since_epoch().count();\n        mt19937 rng((unsigned)seed);\n        solve_guillotine(rng, TIME_GUill);\n    }\n\n    // Final non-guillotine refinement on best topology found\n    uint64_t seed = 7777777ULL + chrono::steady_clock::now().time_since_epoch().count();\n    mt19937 rng((unsigned)seed);\n    polish_edges(rng, TIME_POLISH);\n\n    for (int i = 0; i < n; ++i) {\n        cout << best_rects[i].l << ' ' << best_rects[i].b << ' '\n             << best_rects[i].r << ' ' << best_rects[i].t << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 50;\nconstexpr int W = 50;\n\nstruct Solver {\n    static constexpr int DI[4] = {-1, 1, 0, 0};\n    static constexpr int DJ[4] = {0, 0, -1, 1};\n    static constexpr char DC[4] = {'U', 'D', 'L', 'R'};\n    \n    int si, sj;\n    vector<vector<int>> tile;\n    vector<vector<int>> val;\n    int M;\n    \n    uint32_t rng_seed = 123456789;\n    uint32_t rand_u32() {\n        rng_seed ^= rng_seed << 13;\n        rng_seed ^= rng_seed >> 17;\n        rng_seed ^= rng_seed << 5;\n        return rng_seed;\n    }\n    double rand_double() {\n        return (double)rand_u32() / UINT32_MAX;\n    }\n    \n    long long evaluate_path(const string& path) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        long long score = val[i][j];\n        \n        for (char c : path) {\n            int d = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n            int ni = i + DI[d];\n            int nj = j + DJ[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) return -1;\n            int nt = tile[ni][nj];\n            if (vis[nt]) return -1;\n            i = ni; j = nj;\n            vis[nt] = 1;\n            score += val[i][j];\n        }\n        return score;\n    }\n    \n    // Calculate degree of a cell given visited set\n    int get_degree(int i, int j, const vector<char>& vis) {\n        int deg = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + DI[d];\n            int nj = j + DJ[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n            if (!vis[tile[ni][nj]]) deg++;\n        }\n        return deg;\n    }\n    \n    string greedy_walk(double w_val, double w_deg, double dead_penalty, \n                       double w_future, bool use_random_tiebreak, int forced_first_dir = -1) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        string path;\n        path.reserve(M);\n        int steps = 0;\n        \n        while (true) {\n            struct Cand {\n                double score;\n                int dir;\n                int ni, nj;\n                int deg;\n                bool is_leaf;\n            };\n            vector<Cand> cands;\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + DI[d];\n                int nj = j + DJ[d];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n                int nt = tile[ni][nj];\n                if (vis[nt]) continue;\n                \n                // Calculate degree after visiting this tile\n                int deg = 0;\n                int max_next_val = 0;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int ni2 = ni + DI[d2];\n                    int nj2 = nj + DJ[d2];\n                    if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                    int nt2 = tile[ni2][nj2];\n                    if (nt2 == nt) continue;\n                    if (!vis[nt2]) {\n                        deg++;\n                        max_next_val = max(max_next_val, val[ni2][nj2]);\n                    }\n                }\n                \n                bool is_leaf = (deg == 0);\n                \n                // Depth-2 lookahead: find best 2-step continuation\n                double future_val = 0;\n                if (!is_leaf) {\n                    vis[nt] = 1;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int ni2 = ni + DI[d2];\n                        int nj2 = nj + DJ[d2];\n                        if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                        int nt2 = tile[ni2][nj2];\n                        if (nt2 == nt) continue;\n                        if (vis[nt2]) continue;\n                        \n                        double val2 = val[ni2][nj2];\n                        // Look one step further\n                        int max_next2 = 0;\n                        vis[nt2] = 1;\n                        for (int d3 = 0; d3 < 4; ++d3) {\n                            int ni3 = ni2 + DI[d3];\n                            int nj3 = nj2 + DJ[d3];\n                            if (ni3 < 0 || ni3 >= H || nj3 < 0 || nj3 >= W) continue;\n                            int nt3 = tile[ni3][nj3];\n                            if (nt3 == nt || nt3 == nt2) continue;\n                            if (!vis[nt3]) max_next2 = max(max_next2, val[ni3][nj3]);\n                        }\n                        vis[nt2] = 0;\n                        val2 += 0.5 * max_next2;\n                        future_val = max(future_val, val2);\n                    }\n                    vis[nt] = 0;\n                }\n                \n                double base_score = val[ni][nj] * w_val;\n                \n                // Adaptive phase: early = connectivity, late = value\n                double phase = min(1.0, steps / 150.0);\n                base_score += deg * w_deg * (1.0 - phase * 0.7);\n                \n                if (is_leaf) {\n                    base_score -= dead_penalty;\n                }\n                \n                base_score += future_val * w_future;\n                \n                // Critical: if this is a leaf neighbor (deg == 0 after visiting), \n                // and it's not the only option, we might want to penalize heavily\n                // unless it has high value\n                \n                if (use_random_tiebreak) {\n                    base_score += rand_double() * 0.3;\n                }\n                \n                cands.push_back({base_score, d, ni, nj, deg, is_leaf});\n            }\n            \n            if (cands.empty()) break;\n            \n            // Forced first direction\n            if (forced_first_dir >= 0 && steps == 0) {\n                bool found = false;\n                for (auto& c : cands) {\n                    if (c.dir == forced_first_dir) {\n                        cands = {c};\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n            \n            // If there are leaves (dead ends) available, prioritize them only if decent value\n            // Actually, we should visit leaves with ANY value to avoid losing them forever\n            // But only if we can return (if current pos has degree > 1) or if it's the only way\n            \n            auto best = *max_element(cands.begin(), cands.end(),\n                [](const Cand& a, const Cand& b) { return a.score < b.score; });\n            \n            i = best.ni;\n            j = best.nj;\n            vis[tile[i][j]] = 1;\n            path.push_back(DC[best.dir]);\n            steps++;\n        }\n        return path;\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Phase 1: All 4 initial directions with conservative parameters\n        for (int d = 0; d < 4; ++d) {\n            string p = greedy_walk(1.0, 50.0, 20000.0, 0.8, false, d);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 2: Deterministic presets\n        vector<tuple<double, double, double, double>> presets = {\n            {1.0, 30.0, 10000.0, 1.0},   // Balanced\n            {1.0, 60.0, 5000.0, 0.5},    // High connectivity early\n            {1.0, 10.0, 50000.0, 0.3},   // Avoid dead ends strongly\n            {1.0, 0.0, 0.0, 0.0},        // Pure greedy\n            {1.0, 100.0, 1000.0, 0.2},   // Extreme connectivity\n        };\n        \n        for (auto& [wv, wd, dp, wf] : presets) {\n            string p = greedy_walk(wv, wd, dp, wf, false, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 3: Extensive stochastic search\n        for (int iter = 0; iter < 3000; ++iter) {\n            double wv = 1.0;\n            double wd = rand_double() * 100.0;      // 0 to 100\n            double dp = rand_double() * 50000.0;    // 0 to 50000\n            double wf = rand_double() * 1.5;        // 0 to 1.5\n            \n            string p = greedy_walk(wv, wd, dp, wf, true, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        return best_path;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    while (true) {\n        int si, sj;\n        if (!(cin >> si >> sj)) break;\n        \n        vector<vector<int>> t(H, vector<int>(W));\n        vector<vector<int>> p(H, vector<int>(W));\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> p[i][j];\n        \n        Solver solver;\n        solver.si = si;\n        solver.sj = sj;\n        solver.tile = t;\n        solver.val = p;\n        \n        int max_id = 0;\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                max_id = max(max_id, t[i][j]);\n        solver.M = max_id + 1;\n        \n        cout << solver.solve() << \"\\n\";\n    }\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    constexpr int N = 30;\n    constexpr int Q = 1000;\n    constexpr double LR = 0.6;          // stable learning rate\n    constexpr double SIGMA0 = 2000.0;   // exploration prior\n    constexpr double WMIN = 100.0;\n    constexpr double WMAX = 10000.0;\n    constexpr double SMOOTH_ALPHA = 0.04; // base Laplacian strength\n    \n    // estimates and visit counters\n    double H[N][N - 1];\n    double V[N - 1][N];\n    int    CntH[N][N - 1] = {};\n    int    CntV[N - 1][N] = {};\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            H[i][j] = 5000.0;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            V[i][j] = 5000.0;\n    \n    // temporaries for smoothing\n    double tmpH[N][N - 1];\n    double tmpV[N - 1][N];\n    \n    // random generator for Thompson sampling\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    std::normal_distribution<double> gauss(0.0, 1.0);\n    \n    // sampled weights for Dijkstra\n    double sH[N][N - 1];\n    double sV[N - 1][N];\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    for (int q = 0; q < Q; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n        \n        // decay factors: exploration ends at 850, smoothing ends at 980\n        double explore_decay = max(0.0, 1.0 - static_cast<double>(q) / 850.0);\n        double smooth_decay  = max(0.0, 1.0 - static_cast<double>(q) / 980.0);\n        \n        // ---------- 1. Thompson sampling with decaying variance ----------\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                double sigma = SIGMA0 * explore_decay / sqrt((double)CntH[i][j] + 1.0);\n                double w = H[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sH[i][j] = w;\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double sigma = SIGMA0 * explore_decay / sqrt((double)CntV[i][j] + 1.0);\n                double w = V[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sV[i][j] = w;\n            }\n        }\n        \n        // ---------- 2. Dijkstra ----------\n        double dist[N][N];\n        int par_i[N][N];\n        int par_j[N][N];\n        char par_dir[N][N];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = 1e100;\n        \n        using State = tuple<double, int, int>;\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[si][sj] = 0.0;\n        pq.emplace(0.0, si, sj);\n        \n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j] + 1e-9) continue;\n            if (i == ti && j == tj) break;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                double w;\n                if (dir == 0) w = sV[i - 1][j];\n                else if (dir == 1) w = sV[i][j];\n                else if (dir == 2) w = sH[i][j - 1];\n                else               w = sH[i][j];\n                if (dist[ni][nj] > d + w) {\n                    dist[ni][nj] = d + w;\n                    par_i[ni][nj] = i;\n                    par_j[ni][nj] = j;\n                    par_dir[ni][nj] = dc[dir];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n        \n        // reconstruct path\n        string path;\n        int ci = ti, cj = tj;\n        while (ci != si || cj != sj) {\n            path.push_back(par_dir[ci][cj]);\n            int pi = par_i[ci][cj];\n            int pj = par_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << '\\n';\n        cout.flush();\n        \n        // ---------- 3. Observation & Weighted SGD ----------\n        long long obs_in;\n        cin >> obs_in;\n        double obs = static_cast<double>(obs_in);\n        \n        double lenEst = 0.0;\n        ci = si; cj = sj;\n        struct Edge { char type; int i, j; };\n        vector<Edge> edges;\n        edges.reserve(path.size());\n        for (char c : path) {\n            if (c == 'U') {\n                lenEst += V[ci - 1][cj];\n                edges.push_back({'V', ci - 1, cj});\n                --ci;\n            } else if (c == 'D') {\n                lenEst += V[ci][cj];\n                edges.push_back({'V', ci, cj});\n                ++ci;\n            } else if (c == 'L') {\n                lenEst += H[ci][cj - 1];\n                edges.push_back({'H', ci, cj - 1});\n                --cj;\n            } else { // 'R'\n                lenEst += H[ci][cj];\n                edges.push_back({'H', ci, cj});\n                ++cj;\n            }\n        }\n        \n        double err = obs - lenEst;\n        // uncertainty-based weights\n        double sumW = 0.0;\n        vector<double> uweight;\n        uweight.reserve(edges.size());\n        for (auto &e : edges) {\n            int cnt = (e.type == 'H') ? CntH[e.i][e.j] : CntV[e.i][e.j];\n            double uw = 1.0 / sqrt((double)cnt + 1.0);\n            uweight.push_back(uw);\n            sumW += uw;\n        }\n        \n        // apply weighted update\n        for (size_t idx = 0; idx < edges.size(); ++idx) {\n            const auto &e = edges[idx];\n            double delta = LR * err * (uweight[idx] / sumW);\n            if (e.type == 'H') {\n                H[e.i][e.j] += delta;\n                if (H[e.i][e.j] < WMIN) H[e.i][e.j] = WMIN;\n                if (H[e.i][e.j] > WMAX) H[e.i][e.j] = WMAX;\n                ++CntH[e.i][e.j];\n            } else {\n                V[e.i][e.j] += delta;\n                if (V[e.i][e.j] < WMIN) V[e.i][e.j] = WMIN;\n                if (V[e.i][e.j] > WMAX) V[e.i][e.j] = WMAX;\n                ++CntV[e.i][e.j];\n            }\n        }\n        \n        // ---------- 4. Decaying Laplacian smoothing ----------\n        if (smooth_decay > 0.0) {\n            double alpha = SMOOTH_ALPHA * smooth_decay;\n            \n            // Horizontal edges: smooth along rows\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N - 1; ++j) {\n                    double left  = (j > 0)     ? H[i][j - 1] : H[i][j];\n                    double right = (j < N - 2) ? H[i][j + 1] : H[i][j];\n                    double lap = left + right - 2.0 * H[i][j];\n                    tmpH[i][j] = H[i][j] + alpha * lap;\n                    if (tmpH[i][j] < WMIN) tmpH[i][j] = WMIN;\n                    if (tmpH[i][j] > WMAX) tmpH[i][j] = WMAX;\n                }\n            }\n            // Vertical edges: smooth along columns\n            for (int i = 0; i < N - 1; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    double up   = (i > 0)     ? V[i - 1][j] : V[i][j];\n                    double down = (i < N - 2) ? V[i + 1][j] : V[i][j];\n                    double lap = up + down - 2.0 * V[i][j];\n                    tmpV[i][j] = V[i][j] + alpha * lap;\n                    if (tmpV[i][j] < WMIN) tmpV[i][j] = WMIN;\n                    if (tmpV[i][j] > WMAX) tmpV[i][j] = WMAX;\n                }\n            }\n            // copy back\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N - 1; ++j)\n                    H[i][j] = tmpH[i][j];\n            for (int i = 0; i < N - 1; ++i)\n                for (int j = 0; j < N; ++j)\n                    V[i][j] = tmpV[i][j];\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int str_id;\n    uint8_t len;\n};\n\nstruct Ref {\n    int pid;\n    uint8_t req;          // 0 \u2026 7  (A \u2026 H)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;                 // Fixed by problem statement\n    int N_input, M;\n    if (!(cin >> N_input >> M)) return 0;\n    // N_input is guaranteed to be 20, but we use the const N for safety\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) cin >> strs[i];\n\n    auto ch2i = [](char c)->int{ return c - 'A'; };   // 'A'..'H' -> 0..7\n\n    const int C = N * N;                 // number of cells\n    vector<vector<Ref>> cell_refs(C);    // reverse index\n    vector<Placement> plc;               // all placements\n    plc.reserve(M * 2 * N * N);\n\n    /* -----------------------------------------------------------\n       generate all placements\n       ----------------------------------------------------------- */\n    for (int s = 0; s < M; ++s) {\n        const string &st = strs[s];\n        int L = (int)st.size();\n        // horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    int cid = r * N + cc;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n        // vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = (int)plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int rr = (r + p) % N;\n                    int cid = rr * N + c;\n                    cell_refs[cid].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n    }\n\n    const int P = (int)plc.size();\n    vector<uint8_t> counter(P, 0);\n    vector<int> sat_cnt(M, 0);\n    int total_sat = 0;\n\n    /* -----------------------------------------------------------\n       random initial grid (only letters, 0..7)\n       ----------------------------------------------------------- */\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    vector<uint8_t> grid(C);\n    for (int i = 0; i < C; ++i) grid[i] = (uint8_t)(rng() & 7);\n\n    /* initial counting */\n    for (int cid = 0; cid < C; ++cid) {\n        uint8_t v = grid[cid];\n        for (const auto &rf : cell_refs[cid]) {\n            if (rf.req == v) ++counter[rf.pid];\n        }\n    }\n    for (int pid = 0; pid < P; ++pid) {\n        if (counter[pid] == plc[pid].len) {\n            ++sat_cnt[plc[pid].str_id];\n        }\n    }\n    for (int s = 0; s < M; ++s) if (sat_cnt[s] > 0) ++total_sat;\n\n    /* -----------------------------------------------------------\n       helper: apply change of one cell (old_val -> new_val)\n       updates counter[], sat_cnt[] and total_sat\n       ----------------------------------------------------------- */\n    auto apply_change = [&](int cid, uint8_t old_val, uint8_t new_val) {\n        if (old_val == new_val) return;\n        for (const auto &rf : cell_refs[cid]) {\n            bool old_match = (old_val == rf.req);\n            bool new_match = (new_val == rf.req);\n            if (old_match == new_match) continue;   // nothing changes\n\n            uint8_t &cnt = counter[rf.pid];\n            uint8_t len  = plc[rf.pid].len;\n            if (old_match) {                 // we lose one matching cell\n                --cnt;\n                if (cnt == len - 1) {        // was satisfied, now not\n                    int sid = plc[rf.pid].str_id;\n                    if (--sat_cnt[sid] == 0) --total_sat;\n                }\n            } else {                         // we gain one matching cell\n                ++cnt;\n                if (cnt == len) {            // becomes satisfied\n                    int sid = plc[rf.pid].str_id;\n                    if (sat_cnt[sid]++ == 0) ++total_sat;\n                }\n            }\n        }\n    };\n\n    /* -----------------------------------------------------------\n       Simulated Annealing\n       ----------------------------------------------------------- */\n    const double TIME_LIMIT = 2.5;            // seconds\n    auto start = chrono::steady_clock::now();\n    double temp = 0.8;                        // initial temperature\n    int iter = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        ++iter;\n        if ((iter & 127) == 0) temp *= 0.999; // slow cooling\n\n        int cid = (int)(rng() % C);\n        uint8_t oldv = grid[cid];\n        uint8_t newv = (uint8_t)(rng() & 7);\n        if (oldv == newv) continue;\n\n        int before = total_sat;\n        apply_change(cid, oldv, newv);\n        int after = total_sat;\n        int delta = after - before;\n\n        if (delta < 0) {\n            double accept_prob = exp(delta / temp);\n            if (uniform_real_distribution<double>(0.0, 1.0)(rng) > accept_prob) {\n                // reject: revert\n                apply_change(cid, newv, oldv);\n                // grid[cid] stays oldv\n                continue;\n            }\n        }\n        grid[cid] = newv;   // accept\n    }\n\n    /* -----------------------------------------------------------\n       Phase 2: try to turn cells into '.' (value 8) without breaking\n       ----------------------------------------------------------- */\n    if (total_sat == M) {\n        vector<int> order(C);\n        iota(order.begin(), order.end(), 0);\n        for (int rep = 0; rep < 3; ++rep) {\n            shuffle(order.begin(), order.end(), rng);\n            for (int cid : order) {\n                if (grid[cid] == 8) continue;          // already dot\n                uint8_t oldv = grid[cid];\n                apply_change(cid, oldv, 8);\n                if (total_sat == M) {\n                    grid[cid] = 8;                      // keep dot\n                } else {\n                    apply_change(cid, 8, oldv);         // revert\n                }\n            }\n        }\n    }\n\n    /* -----------------------------------------------------------\n       Output\n       ----------------------------------------------------------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        line.reserve(N);\n        for (int c = 0; c < N; ++c) {\n            int v = grid[r * N + c];\n            if (v == 8) line.push_back('.');\n            else        line.push_back(char('A' + v));\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastBitset {\n    static const int MAXR = 5000;\n    static const int WORDS = (MAXR + 63) / 64;\n    uint64_t w[WORDS];\n    FastBitset() { memset(w, 0, sizeof(w)); }\n    void set(int i) { w[i>>6] |= 1ULL << (i&63); }\n    bool test(int i) const { return (w[i>>6] >> (i&63)) & 1ULL; }\n    void clear() { memset(w, 0, sizeof(w)); }\n    int count() const {\n        int s = 0;\n        for (int i = 0; i < WORDS; i++) s += __builtin_popcountll(w[i]);\n        return s;\n    }\n    FastBitset operator|(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] | o.w[i];\n        return r;\n    }\n    FastBitset operator&(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] & o.w[i];\n        return r;\n    }\n    FastBitset operator~() const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = ~w[i];\n        return r;\n    }\n    FastBitset& operator|=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] |= o.w[i];\n        return *this;\n    }\n    FastBitset& operator&=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] &= o.w[i];\n        return *this;\n    }\n    bool any() const {\n        for (int i = 0; i < WORDS; i++) if (w[i]) return true;\n        return false;\n    }\n    bool is_subset_of(const FastBitset& o) const {\n        for (int i = 0; i < WORDS; i++) {\n            if ((w[i] & ~o.w[i]) != 0) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = cells.size();\n                cells.emplace_back(i, j);\n            }\n        }\n    }\n    int R = cells.size();\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // Build horizontal and vertical segments\n    vector<vector<int>> h_id(N, vector<int>(N, -1));\n    vector<vector<int>> v_id(N, vector<int>(N, -1));\n    vector<FastBitset> h_cover, v_cover;\n    \n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != '#') {\n                int l = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int r = j - 1;\n                FastBitset bs;\n                int sid = h_cover.size();\n                for (int k = l; k <= r; k++) {\n                    h_id[i][k] = sid;\n                    bs.set(id[i][k]);\n                }\n                h_cover.push_back(bs);\n            } else {\n                j++;\n            }\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != '#') {\n                int t = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int b = i - 1;\n                FastBitset bs;\n                int sid = v_cover.size();\n                for (int k = t; k <= b; k++) {\n                    v_id[k][j] = sid;\n                    bs.set(id[k][j]);\n                }\n                v_cover.push_back(bs);\n            } else {\n                i++;\n            }\n        }\n    }\n    \n    // Cell coverage\n    vector<FastBitset> cell_cover(R);\n    for (int idx = 0; idx < R; idx++) {\n        auto [i, j] = cells[idx];\n        cell_cover[idx] = h_cover[h_id[i][j]] | v_cover[v_id[i][j]];\n    }\n    \n    int start_idx = id[si][sj];\n    \n    // Greedy set cover with benefit/efficiency\n    FastBitset uncovered;\n    for (int i = 0; i < R; i++) uncovered.set(i);\n    FastBitset start_cover = cell_cover[start_idx];\n    for (int w = 0; w < FastBitset::WORDS; w++) \n        uncovered.w[w] &= ~start_cover.w[w];\n    \n    vector<int> selected;\n    vector<bool> is_selected(R, false);\n    \n    while (uncovered.any()) {\n        int best = -1;\n        int best_cnt = -1;\n        \n        for (int c = 0; c < R; c++) {\n            if (is_selected[c]) continue;\n            bool has_overlap = false;\n            for (int w = 0; w < FastBitset::WORDS; w++) {\n                if (cell_cover[c].w[w] & uncovered.w[w]) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            if (!has_overlap) continue;\n            \n            FastBitset inter;\n            for (int w = 0; w < FastBitset::WORDS; w++) \n                inter.w[w] = cell_cover[c].w[w] & uncovered.w[w];\n            int cnt = inter.count();\n            // Prefer larger coverage\n            if (cnt > best_cnt) {\n                best_cnt = cnt;\n                best = c;\n            }\n        }\n        \n        if (best == -1) break;\n        selected.push_back(best);\n        is_selected[best] = true;\n        for (int w = 0; w < FastBitset::WORDS; w++) \n            uncovered.w[w] &= ~cell_cover[best].w[w];\n    }\n    \n    // Conservative redundancy elimination\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        FastBitset all_cover = start_cover;\n        for (int idx : selected) all_cover |= cell_cover[idx];\n        \n        for (int i = 0; i < (int)selected.size(); i++) {\n            FastBitset without = start_cover;\n            for (int j = 0; j < (int)selected.size(); j++) {\n                if (i != j) without |= cell_cover[selected[j]];\n            }\n            FastBitset loss;\n            for (int w = 0; w < FastBitset::WORDS; w++)\n                loss.w[w] = cell_cover[selected[i]].w[w] & ~without.w[w];\n            if (!loss.any()) {\n                is_selected[selected[i]] = false;\n                selected.erase(selected.begin() + i);\n                changed = true;\n                break;\n            }\n        }\n    }\n    \n    // Build point list\n    vector<int> points;\n    points.reserve(selected.size() + 1);\n    points.push_back(start_idx);\n    for (int idx : selected) points.push_back(idx);\n    int K = points.size();\n    \n    if (K == 1) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    vector<int> node_to_point(R, -1);\n    for (int i = 0; i < K; i++) node_to_point[points[i]] = i;\n    \n    const int INF = 1e9;\n    \n    // Compute distance matrix\n    vector<vector<int>> dmat(K, vector<int>(K, INF));\n    \n    for (int pi = 0; pi < K; pi++) {\n        int src = points[pi];\n        vector<int> dist(R, INF);\n        dist[src] = 0;\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.emplace(0, src);\n        int settled = 0;\n        \n        while (!pq.empty() && settled < K) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (node_to_point[u] != -1) settled++;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        for (int pj = 0; pj < K; pj++) {\n            dmat[pi][pj] = dist[points[pj]];\n        }\n    }\n    \n    // TSP with multiple heuristics and extensive local search\n    vector<int> best_tour;\n    int best_cost = INF;\n    mt19937 rng(42);\n    \n    auto calc_cost = [&](const vector<int>& tour) -> int {\n        int cost = 0;\n        for (int i = 0; i < K; i++) {\n            cost += dmat[tour[i]][tour[(i+1)%K]];\n        }\n        return cost;\n    };\n    \n    auto do_2opt = [&](vector<int>& tour, int max_iter = 1000) -> int {\n        int cost = calc_cost(tour);\n        bool improved = true;\n        int iter = 0;\n        while (improved && iter < max_iter) {\n            improved = false;\n            iter++;\n            for (int i = 0; i < K && !improved; i++) {\n                for (int j = i + 2; j < K && !improved; j++) {\n                    if (j == K-1 && i == 0) continue;\n                    int a = tour[i];\n                    int b = tour[(i+1)%K];\n                    int c = tour[j];\n                    int d = tour[(j+1)%K];\n                    \n                    int cur = dmat[a][b] + dmat[c][d];\n                    int rev = dmat[a][c] + dmat[b][d];\n                    \n                    if (rev < cur) {\n                        reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                        cost += rev - cur;\n                        improved = true;\n                    }\n                }\n            }\n        }\n        return cost;\n    };\n    \n    // Or-opt: relocate sequence of 1-3 nodes\n    auto do_oropt = [&](vector<int>& tour, int max_iter = 500) -> int {\n        int cost = calc_cost(tour);\n        bool improved = true;\n        int iter = 0;\n        while (improved && iter < max_iter) {\n            improved = false;\n            iter++;\n            for (int len = 1; len <= 3 && !improved; len++) {\n                for (int i = 0; i < K && !improved; i++) {\n                    int j = (i + len) % K;\n                    // Extract segment [i+1, j]\n                    for (int pos = 0; pos < K && !improved; pos++) {\n                        if (pos >= i && pos <= j) continue;\n                        int k = pos;\n                        int l = (pos + 1) % K;\n                        \n                        // Current: ...i->seg_start...seg_end->j...  k->l...\n                        // Try: ...i->j...k->seg_start...seg_end->l...\n                        int a = tour[i], b = tour[(i+1)%K];\n                        int c = tour[j], d = tour[(j+1)%K];\n                        int e = tour[k], f = tour[(k+1)%K];\n                        \n                        int cur = dmat[a][b] + dmat[c][d] + dmat[e][f];\n                        int neu = dmat[a][d] + dmat[e][b] + dmat[c][f];\n                        \n                        if (neu < cur) {\n                            // Extract segment and reinsert\n                            vector<int> seg;\n                            for (int x = (i+1)%K; x != (j+1)%K; x = (x+1)%K) {\n                                seg.push_back(tour[x]);\n                                if (x == j) break;\n                            }\n                            // Remove segment\n                            vector<int> new_tour;\n                            new_tour.push_back(tour[0]);\n                            for (int x = 1; x < K; x++) {\n                                int idx = tour[x];\n                                bool in_seg = false;\n                                for (int s : seg) if (s == idx) in_seg = true;\n                                if (!in_seg) new_tour.push_back(idx);\n                            }\n                            // Insert after position k\n                            auto it = find(new_tour.begin(), new_tour.end(), e);\n                            if (it != new_tour.end()) {\n                                new_tour.insert(it + 1, seg.begin(), seg.end());\n                                if (new_tour.size() == K) {\n                                    tour = new_tour;\n                                    cost += neu - cur;\n                                    improved = true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return cost;\n    };\n    \n    // Generate initial tours\n    vector<vector<int>> tours;\n    \n    // Nearest neighbor\n    for (int start = 0; start < min(K, 8); start++) {\n        vector<int> tour;\n        vector<bool> used(K, false);\n        tour.push_back(start);\n        used[start] = true;\n        int cur = start;\n        \n        while ((int)tour.size() < K) {\n            int nxt = -1;\n            int best_d = INF;\n            for (int i = 0; i < K; i++) if (!used[i]) {\n                if (dmat[cur][i] < best_d) {\n                    best_d = dmat[cur][i];\n                    nxt = i;\n                }\n            }\n            if (nxt == -1) break;\n            tour.push_back(nxt);\n            used[nxt] = true;\n            cur = nxt;\n        }\n        \n        auto it = find(tour.begin(), tour.end(), 0);\n        if (it != tour.end()) rotate(tour.begin(), it, tour.end());\n        tours.push_back(tour);\n    }\n    \n    // Farthest insertion\n    for (int attempt = 0; attempt < 8; attempt++) {\n        vector<int> tour;\n        vector<bool> used(K, false);\n        tour.push_back(0);\n        used[0] = true;\n        \n        while ((int)tour.size() < K) {\n            int farthest = -1;\n            int max_mindist = -1;\n            for (int i = 0; i < K; i++) if (!used[i]) {\n                int mindist = INF;\n                for (int j : tour) mindist = min(mindist, dmat[j][i]);\n                if (mindist > max_mindist) {\n                    max_mindist = mindist;\n                    farthest = i;\n                }\n            }\n            if (farthest == -1) break;\n            \n            int best_pos = -1;\n            int best_inc = INF;\n            for (int pos = 0; pos < (int)tour.size(); pos++) {\n                int a = tour[pos];\n                int b = tour[(pos+1)%tour.size()];\n                int inc = dmat[a][farthest] + dmat[farthest][b] - dmat[a][b];\n                if (inc < best_inc) {\n                    best_inc = inc;\n                    best_pos = pos;\n                }\n            }\n            tour.insert(tour.begin() + best_pos + 1, farthest);\n            used[farthest] = true;\n        }\n        tours.push_back(tour);\n    }\n    \n    // Cheapest insertion with randomization\n    for (int attempt = 0; attempt < 8; attempt++) {\n        vector<int> nodes;\n        for (int i = 1; i < K; i++) nodes.push_back(i);\n        shuffle(nodes.begin(), nodes.end(), rng);\n        \n        vector<int> tour = {0};\n        for (int node : nodes) {\n            int best_pos = -1;\n            int best_inc = INF;\n            for (int pos = 0; pos < (int)tour.size(); pos++) {\n                int a = tour[pos];\n                int b = tour[(pos+1)%tour.size()];\n                int inc = dmat[a][node] + dmat[node][b] - dmat[a][b];\n                if (inc < best_inc) {\n                    best_inc = inc;\n                    best_pos = pos;\n                }\n            }\n            tour.insert(tour.begin() + best_pos + 1, node);\n        }\n        tours.push_back(tour);\n    }\n    \n    // Optimize all tours\n    for (auto& tour : tours) {\n        int cost = do_2opt(tour);\n        cost = do_oropt(tour);\n        cost = do_2opt(tour);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_tour = tour;\n        }\n    }\n    \n    // Build route\n    string route;\n    route.reserve(N * N * 4);\n    \n    for (int ii = 0; ii < K; ii++) {\n        int from_idx = points[best_tour[ii]];\n        int to_idx = points[best_tour[(ii+1)%K]];\n        if (from_idx == to_idx) continue;\n        \n        vector<int> dist(R, INF);\n        vector<int> prev(R, -1);\n        vector<int> prev_dir(R, -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[from_idx] = 0;\n        pq.emplace(0, from_idx);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == to_idx) break;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir];\n                int nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_dir[v] = dir;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int cur_node = to_idx;\n        while (cur_node != from_idx) {\n            dirs.push_back(prev_dir[cur_node]);\n            cur_node = prev[cur_node];\n        }\n        reverse(dirs.begin(), dirs.end());\n        for (int d : dirs) {\n            route += \"UDLR\"[d];\n        }\n    }\n    \n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if(!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> sum_d(N, 0);\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<K; j++) {\n            cin >> d[i][j];\n            sum_d[i] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0);\n    for(int i=0; i<R; i++) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    // State\n    vector<vector<double>> est_s(M, vector<double>(K, 30.0));\n    vector<vector<double>> lb(M, vector<double>(K, 0.0));\n    vector<int> total_obs(M, 0);\n    \n    vector<int> indeg_cur = indeg;\n    vector<int> task_state(N, 0);\n    vector<int> member_task(M, -1);\n    vector<int> task_start_day(N, -1);\n    \n    int day = 0;\n    const int MAX_DAY = 2000;\n    \n    while(day < MAX_DAY) {\n        ++day;\n        \n        // Update available tasks\n        vector<int> available;\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 0 && indeg_cur[i] == 0) {\n                task_state[i] = 1;\n            }\n            if(task_state[i] == 1) available.push_back(i);\n        }\n        \n        // Find free members\n        vector<int> free_members;\n        for(int j=0; j<M; j++) if(member_task[j] == -1) free_members.push_back(j);\n        \n        if(!available.empty() && !free_members.empty()) {\n            // Calculate times for all task-member pairs\n            vector<vector<double>> est_time(M, vector<double>(N, 1.0));\n            vector<vector<double>> pessimistic_time(M, vector<double>(N, 1.0));\n            \n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                for(int j=0; j<M; j++) {\n                    // Optimistic estimate\n                    double w_opt = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > est_s[j][k]) w_opt += d[i][k] - est_s[j][k];\n                    est_time[j][i] = (w_opt <= 0) ? 1.0 : max(1.0, w_opt);\n                    \n                    // Pessimistic estimate using lower bounds\n                    double w_pes = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > lb[j][k]) w_pes += d[i][k] - lb[j][k];\n                    pessimistic_time[j][i] = (w_pes <= 0) ? 1.0 : max(1.0, w_pes);\n                }\n            }\n            \n            // Critical path using pessimistic times\n            vector<double> cp(N, -1.0);\n            function<double(int)> solve_cp = [&](int u) -> double {\n                if(task_state[u] == 3) return 0.0;\n                if(cp[u] >= 0) return cp[u];\n                double max_next = 0.0;\n                for(int v : adj[u]) if(task_state[v] != 3) {\n                    max_next = max(max_next, solve_cp(v));\n                }\n                // Use pessimistic average\n                double avg = 0;\n                for(int j=0; j<M; j++) avg += pessimistic_time[j][u];\n                cp[u] = avg / M + max_next;\n                return cp[u];\n            };\n            for(int i : available) solve_cp(i);\n            \n            // Best and second best times for bottleneck detection\n            vector<double> best_time(N, 1e18), second_time(N, 1e18);\n            vector<int> best_member(N, -1);\n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                for(int j=0; j<M; j++) {\n                    if(est_time[j][i] < best_time[i]) {\n                        second_time[i] = best_time[i];\n                        best_time[i] = est_time[j][i];\n                        best_member[i] = j;\n                    } else if(est_time[j][i] < second_time[i]) {\n                        second_time[i] = est_time[j][i];\n                    }\n                }\n            }\n            \n            // Priority: critical path + bottleneck\n            vector<double> priority(N, 0.0);\n            for(int i : available) {\n                double bottleneck = second_time[i] - best_time[i];\n                priority[i] = cp[i] + 1.5 * bottleneck;\n            }\n            \n            sort(available.begin(), available.end(), [&](int a, int b) {\n                return priority[a] > priority[b];\n            });\n            \n            // Greedy assignment with risk awareness\n            vector<bool> used(M, false);\n            vector<pair<int,int>> assignments;\n            \n            for(int task_id : available) {\n                if(assignments.size() >= free_members.size()) break;\n                \n                // Find best free member, penalizing uncertainty\n                int best_j = -1;\n                double best_score = 1e18;\n                \n                for(int j : free_members) {\n                    if(used[j]) continue;\n                    \n                    double time = est_time[j][task_id];\n                    // Risk penalty: unexplored members are risky for critical tasks\n                    double risk = (5.0 / (1.0 + total_obs[j])) * (cp[task_id] / 50.0);\n                    double score = time + risk;\n                    \n                    if(score < best_score) {\n                        best_score = score;\n                        best_j = j;\n                    }\n                }\n                \n                if(best_j != -1) {\n                    assignments.emplace_back(best_j, task_id);\n                    used[best_j] = true;\n                }\n            }\n            \n            cout << assignments.size();\n            for(auto& [j, i] : assignments) {\n                cout << \" \" << j+1 << \" \" << i+1;\n                member_task[j] = i;\n                task_state[i] = 2;\n                task_start_day[i] = day;\n            }\n            cout << endl;\n        } else {\n            cout << 0 << endl;\n        }\n        cout.flush();\n        \n        // Read completions\n        int n_comp;\n        cin >> n_comp;\n        if(n_comp == -1) break;\n        \n        vector<int> completed(n_comp);\n        for(int i=0; i<n_comp; i++) cin >> completed[i], completed[i]--;\n        \n        // Process completions and update skills\n        for(int j : completed) {\n            int task_id = member_task[j];\n            if(task_id == -1) continue;\n            \n            int duration = day - task_start_day[task_id] + 1;\n            double obs_w = max(0, duration - 1);\n            total_obs[j]++;\n            \n            // Calculate predicted deficiency\n            double pred_w = 0;\n            vector<int> active_dims;\n            vector<double> deficits;\n            for(int k=0; k<K; k++) {\n                if(d[task_id][k] > est_s[j][k]) {\n                    double def = (double)d[task_id][k] - est_s[j][k];\n                    pred_w += def;\n                    active_dims.push_back(k);\n                    deficits.push_back(def);\n                }\n            }\n            \n            if(obs_w == 0) {\n                // Skills are at least requirements\n                for(int k=0; k<K; k++) {\n                    lb[j][k] = max(lb[j][k], (double)d[task_id][k]);\n                    est_s[j][k] = max(est_s[j][k], (double)d[task_id][k]);\n                }\n            } else if(active_dims.empty()) {\n                // Severe underestimate: distribute deficiency using squared weights\n                double sum_sq = 0;\n                for(int k=0; k<K; k++) {\n                    sum_sq += (double)d[task_id][k] * d[task_id][k];\n                }\n                \n                if(sum_sq > 0) {\n                    for(int k=0; k<K; k++) {\n                        double reduction = obs_w * (double)d[task_id][k] * d[task_id][k] / sum_sq;\n                        est_s[j][k] = max(0.0, (double)d[task_id][k] - reduction);\n                    }\n                }\n            } else {\n                // Adjust active dimensions proportionally\n                if(pred_w > 0) {\n                    double ratio = obs_w / pred_w;\n                    // Clamp ratio for stability\n                    ratio = min(2.0, max(0.5, ratio));\n                    \n                    for(size_t idx=0; idx<active_dims.size(); idx++) {\n                        int k = active_dims[idx];\n                        double new_def = deficits[idx] * ratio;\n                        est_s[j][k] = (double)d[task_id][k] - new_def;\n                        est_s[j][k] = max(lb[j][k], est_s[j][k]);\n                    }\n                }\n            }\n            \n            task_state[task_id] = 3;\n            member_task[j] = -1;\n            for(int v : adj[task_id]) indeg_cur[v]--;\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double now() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 1000;\n    const int OFFICE = 0;\n    const int OFFICE_X = 400, OFFICE_Y = 400;\n    const int MAX_P = 2 * N + 1; // 0..2000\n    \n    vector<int> a(N), b(N), c(N), d(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> a[i] >> b[i] >> c[i] >> d[i];\n    }\n    \n    // Coordinate compression: 0 = office, 1..N = pickup, N+1..2N = delivery\n    vector<int> xs(MAX_P), ys(MAX_P);\n    xs[OFFICE] = OFFICE_X; ys[OFFICE] = OFFICE_Y;\n    for (int i = 0; i < N; ++i) {\n        xs[1 + i] = a[i]; ys[1 + i] = b[i];\n        xs[1 + N + i] = c[i]; ys[1 + N + i] = d[i];\n    }\n    \n    // Flat distance matrix: dist[i * MAX_P + j]\n    vector<int> dist(MAX_P * MAX_P);\n    auto D = [&](int i, int j) -> int& { return dist[i * MAX_P + j]; };\n    for (int i = 0; i < MAX_P; ++i) {\n        for (int j = 0; j < MAX_P; ++j) {\n            D(i, j) = abs(xs[i] - xs[j]) + abs(ys[i] - ys[j]);\n        }\n    }\n    \n    Timer timer;\n    \n    // ---------- Greedy Insertion ----------\n    vector<int> route;\n    route.reserve(105);\n    route.push_back(OFFICE);\n    route.push_back(OFFICE);\n    vector<int> selected; selected.reserve(50);\n    vector<bool> used(N, false);\n    \n    for (int iter = 0; iter < 50; ++iter) {\n        int m = (int)route.size();\n        int best_o = -1, best_i = -1, best_j = -1;\n        int best_delta = 1e9;\n        \n        for (int o = 0; o < N; ++o) if (!used[o]) {\n            int p = 1 + o;\n            int del = 1 + N + o;\n            for (int i = 0; i < m - 1; ++i) {\n                int ri = route[i];\n                int ri1 = route[i+1];\n                int dpi = -D(ri, ri1);\n                for (int j = i; j < m - 1; ++j) {\n                    int rj = route[j];\n                    int rj1 = route[j+1];\n                    int delta;\n                    if (i == j) {\n                        delta = dpi + D(ri, p) + D(p, del) + D(del, rj1);\n                    } else {\n                        int dpj = -D(rj, rj1);\n                        delta = dpi + dpj + D(ri, p) + D(p, ri1) + D(rj, del) + D(del, rj1);\n                    }\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_o = o;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        int p = 1 + best_o;\n        int del = 1 + N + best_o;\n        if (best_i == best_j) {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_i + 2, del);\n        } else {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_j + 2, del);\n        }\n        selected.push_back(best_o);\n        used[best_o] = true;\n    }\n    \n    // Prepare for SA: cur sequence and position array\n    vector<int> cur = route; // size 102\n    const int LEN = 102;\n    const int MIDDLE = 100; // indices 1..100 are movable\n    \n    array<int, MAX_P> pos;\n    for (int i = 0; i < LEN; ++i) pos[cur[i]] = i;\n    \n    auto calc_full = [&](const vector<int>& seq) {\n        int s = 0;\n        for (int i = 0; i + 1 < LEN; ++i) s += D(seq[i], seq[i+1]);\n        return s;\n    };\n    int cur_cost = calc_full(cur);\n    int best_cost = cur_cost;\n    vector<int> best_seq = cur;\n    \n    // Type: 0 = pickup, 1 = delivery\n    auto is_pickup = [&](int idx)->bool{ return idx >= 1 && idx <= N; };\n    auto is_delivery = [&](int idx)->bool{ return idx > N; };\n    \n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(1, 100); // movable range\n    \n    // Precompute exp table for fast annealing\n    const int EXP_TABLE_SIZE = 1000;\n    vector<double> exp_table(EXP_TABLE_SIZE);\n    for (int i = 0; i < EXP_TABLE_SIZE; ++i) {\n        double t = (double)i / 100.0; // delta / T\n        exp_table[i] = exp(-t);\n    }\n    \n    double T_start = 1000.0;\n    double T_end = 0.1;\n    double time_limit = 1.98 - timer.now(); // remaining time for SA\n    if (time_limit < 0.1) time_limit = 0.1;\n    double start_time = timer.now();\n    \n    long long iter = 0;\n    while (timer.now() - start_time < time_limit) {\n        double elapsed = timer.now() - start_time;\n        double progress = elapsed / time_limit;\n        double T = T_start * pow(T_end / T_start, progress);\n        \n        int type = rng() & 1; // 0 = swap, 1 = 2-opt\n        bool accept = false;\n        int delta = 0;\n        \n        if (type == 0) {\n            // Swap\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l == r) continue;\n            if (l > r) swap(l, r);\n            \n            int u = cur[l];\n            int v = cur[r];\n            \n            // Validity check: O(1)\n            bool ok = true;\n            if (is_pickup(u)) {\n                if (pos[u + N] <= r) ok = false; // delivery must be after new pos r\n            } else {\n                if (pos[u - N] >= r) ok = false; // pickup must be before new pos r\n            }\n            if (ok && is_pickup(v)) {\n                if (pos[v + N] <= l) ok = false;\n            } else if (ok) {\n                if (pos[v - N] >= l) ok = false;\n            }\n            if (!ok) continue;\n            \n            // Delta calculation\n            int ul = cur[l-1];\n            int ur = cur[l+1];\n            int vl = cur[r-1];\n            int vr = cur[r+1];\n            \n            if (r == l + 1) {\n                // Adjacent: ... ul, u, v, vr ...\n                delta = -D(ul, u) - D(u, v) - D(v, vr)\n                        + D(ul, v) + D(v, u) + D(u, vr);\n            } else {\n                delta = -D(ul, u) - D(u, ur) - D(vl, v) - D(v, vr)\n                        + D(ul, v) + D(v, ur) + D(vl, u) + D(u, vr);\n            }\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    if (uniform_real_distribution<double>(0,1)(rng) >= 0) continue; // reject with high probability\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                swap(cur[l], cur[r]);\n                pos[u] = r;\n                pos[v] = l;\n            }\n        } else {\n            // 2-opt reverse [l, r]\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l >= r) continue;\n            \n            // Validity: no order has both ends inside [l, r]\n            bool ok = true;\n            for (int o : selected) {\n                int p = 1 + o;\n                int d = 1 + N + o;\n                if (l <= pos[p] && pos[p] <= r && l <= pos[d] && pos[d] <= r) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            \n            int before = cur[l-1];\n            int after = cur[r+1];\n            int left = cur[l];\n            int right = cur[r];\n            delta = -D(before, left) - D(right, after) + D(before, right) + D(left, after);\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    continue;\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n                for (int i = l; i <= r; ++i) pos[cur[i]] = i;\n            }\n        }\n        \n        if (accept) {\n            cur_cost += delta;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_seq = cur;\n            }\n        }\n        ++iter;\n    }\n    \n    // ---------- Output ----------\n    cout << 50;\n    for (int o : selected) cout << ' ' << (o + 1);\n    cout << '\\n';\n    \n    cout << best_seq.size();\n    for (int idx : best_seq) {\n        cout << ' ' << xs[idx] << ' ' << ys[idx];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        r.assign(n, 0);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        return p[x] == x ? x : p[x] = find(p[x]);\n    }\n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n    void unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> xs[i] >> ys[i];\n    }\n    \n    vector<int> u(M), v(M);\n    vector<long long> d(M);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        long long dx = (long long)xs[u[i]] - xs[v[i]];\n        long long dy = (long long)ys[u[i]] - ys[v[i]];\n        long long dist_sq = dx * dx + dy * dy;\n        long long dist = llround(sqrt((double)dist_sq));\n        d[i] = dist;\n    }\n    \n    // Precompute which edges are bridges in the suffix graph\n    vector<char> is_bridge(M, 0);\n    DSU dsu_back(N);\n    for (int i = M - 1; i >= 0; --i) {\n        if (dsu_back.same(u[i], v[i])) {\n            is_bridge[i] = 0;\n        } else {\n            is_bridge[i] = 1;\n            dsu_back.unite(u[i], v[i]);\n        }\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;\n        cin >> l;\n        \n        if (dsu.same(u[i], v[i])) {\n            cout << 0 << '\\n';\n        } else {\n            int need = components - 1;\n            int remaining = M - i;\n            bool take = false;\n            \n            // Must take if it's a bridge in suffix\n            if (is_bridge[i]) {\n                take = true;\n            } \n            // Must take if we can't afford to skip\n            else if (need >= remaining) {\n                take = true;\n            } \n            else {\n                double ratio = (double)need / (double)remaining;\n                // Base threshold: 1.0 + 2.0 * ratio\n                double base_threshold = 1.0 + 2.0 * ratio;\n                \n                // More aggressive bonus for small edges\n                double bonus;\n                if (d[i] <= 25) {\n                    bonus = 0.8;  // Very aggressive for tiny edges\n                } else if (d[i] <= 60) {\n                    bonus = 0.5;  // Good bonus for small edges\n                } else if (d[i] <= 120) {\n                    bonus = 0.3;  // Small bonus for medium edges\n                } else {\n                    bonus = min(0.15, 18.0 / (double)d[i]);  // Minimal for large\n                }\n                \n                double threshold = min(3.0, base_threshold + bonus);\n                \n                if ((double)l <= threshold * (double)d[i]) {\n                    take = true;\n                } else {\n                    take = false;\n                }\n            }\n            \n            if (take) {\n                cout << 1 << '\\n';\n                dsu.unite(u[i], v[i]);\n                components--;\n            } else {\n                cout << 0 << '\\n';\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool blocked[32][32];\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char wall_cmd[4] = {'u', 'd', 'l', 'r'};\nconst char move_cmd[4] = {'U', 'D', 'L', 'R'};\n\nbool is_passable(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30 && !blocked[x][y];\n}\n\nbool can_place_wall(int x, int y) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) return false;\n    if (blocked[x][y]) return false;\n    \n    for (auto& p : pets) {\n        if (p.x == x && p.y == y) return false;\n    }\n    for (auto& h : humans) {\n        if (h.x == x && h.y == y) return false;\n    }\n    \n    for (auto& p : pets) {\n        for (int d = 0; d < 4; d++) {\n            if (p.x + dx[d] == x && p.y + dy[d] == y) return false;\n        }\n    }\n    return true;\n}\n\nint bfs_area(int sx, int sy) {\n    if (!is_passable(sx, sy)) return 0;\n    bool visited[32][32] = {};\n    queue<pair<int,int>> q;\n    q.push({sx, sy});\n    visited[sx][sy] = true;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (is_passable(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return cnt;\n}\n\nint bfs_next_move(int sx, int sy, int tx, int ty, const vector<pair<int,int>>& obstacles) {\n    if (sx == tx && sy == ty) return -1;\n    \n    queue<pair<int,int>> q;\n    int dist[32][32];\n    memset(dist, -1, sizeof(dist));\n    \n    q.push({sx, sy});\n    dist[sx][sy] = 0;\n    int first_move[32][32];\n    memset(first_move, -1, sizeof(first_move));\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (!is_passable(nx, ny)) continue;\n            if (dist[nx][ny] != -1) continue;\n            \n            bool occupied = false;\n            for (auto& obs : obstacles) {\n                if (obs.first == nx && obs.second == ny) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (occupied) continue;\n            \n            dist[nx][ny] = dist[x][y] + 1;\n            first_move[nx][ny] = (dist[x][y] == 0) ? d : first_move[x][y];\n            \n            if (nx == tx && ny == ty) {\n                return first_move[nx][ny];\n            }\n            q.push({nx, ny});\n        }\n    }\n    return -1;\n}\n\nint nearest_pet_dist(int hx, int hy) {\n    int dist = 1000;\n    for (auto& p : pets) {\n        dist = min(dist, abs(p.x - hx) + abs(p.y - hy));\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    memset(blocked, false, sizeof(blocked));\n    \n    // Calculate initial fortress bounds\n    int min_x = 30, max_x = 1, min_y = 30, max_y = 1;\n    for (auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n    \n    int expand = 2;\n    int f_min_x = max(2, min_x - expand);\n    int f_max_x = min(29, max_x + expand);\n    int f_min_y = max(2, min_y - expand);\n    int f_max_y = min(29, max_y + expand);\n    \n    // Check if pets are initially inside\n    bool individual_mode = false;\n    for (auto& p : pets) {\n        if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n            individual_mode = true;\n            break;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> human_targets(M);\n    \n    if (individual_mode) {\n        // Each human builds their own 3x3 cell\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx + dx[d];\n                int wy = hy + dy[d];\n                if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                    human_targets[i].push_back({wx, wy});\n                }\n            }\n        }\n    } else {\n        // Shared fortress - assign perimeter sections\n        vector<pair<int,int>> all_targets;\n        for (int y = f_min_y; y <= f_max_y; y++) {\n            all_targets.push_back({f_min_x, y});\n            all_targets.push_back({f_max_x, y});\n        }\n        for (int x = f_min_x + 1; x <= f_max_x - 1; x++) {\n            all_targets.push_back({x, f_min_y});\n            all_targets.push_back({x, f_max_y});\n        }\n        \n        // Sort by angle from center to distribute evenly\n        double cx = (min_x + max_x) / 2.0;\n        double cy = (min_y + max_y) / 2.0;\n        sort(all_targets.begin(), all_targets.end(), [&](auto& a, auto& b) {\n            double ang_a = atan2(a.first - cx, a.second - cy);\n            double ang_b = atan2(b.first - cx, b.second - cy);\n            return ang_a < ang_b;\n        });\n        \n        // Round-robin assignment\n        for (int i = 0; i < (int)all_targets.size(); i++) {\n            human_targets[i % M].push_back(all_targets[i]);\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        // Check for invasion (pets inside fortress)\n        if (!individual_mode && turn > 0) {\n            for (auto& p : pets) {\n                if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n                    // Pet invaded! Switch to emergency individual mode\n                    individual_mode = true;\n                    human_targets.assign(M, {});\n                    for (int i = 0; i < M; i++) {\n                        int hx = humans[i].x, hy = humans[i].y;\n                        for (int d = 0; d < 4; d++) {\n                            int wx = hx + dx[d], wy = hy + dy[d];\n                            if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                                human_targets[i].push_back({wx, wy});\n                            }\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n        \n        string actions(M, '.');\n        vector<pair<int,int>> next_pos(M);\n        vector<bool> will_build(M, false);\n        \n        // Process humans in order of threat (most threatened first)\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return nearest_pet_dist(humans[a].x, humans[a].y) < nearest_pet_dist(humans[b].x, humans[b].y);\n        });\n        \n        // Track occupied positions for collision avoidance\n        vector<pair<int,int>> occupied;\n        for (auto& h : humans) occupied.push_back({h.x, h.y});\n        \n        for (int idx : order) {\n            int hx = humans[idx].x, hy = humans[idx].y;\n            bool acted = false;\n            \n            // Remove completed targets\n            human_targets[idx].erase(\n                remove_if(human_targets[idx].begin(), human_targets[idx].end(),\n                    [&](auto& t) { return blocked[t.first][t.second]; }),\n                human_targets[idx].end()\n            );\n            \n            // Try to build adjacent wall\n            for (auto& target : human_targets[idx]) {\n                int tx = target.first, ty = target.second;\n                if (abs(tx - hx) + abs(ty - hy) == 1) {\n                    if (can_place_wall(tx, ty)) {\n                        // Safety check: ensure building this wall doesn't trap us in tiny space\n                        blocked[tx][ty] = true;\n                        int area = bfs_area(hx, hy);\n                        blocked[tx][ty] = false;\n                        \n                        if (area >= 4) { // Ensure at least 4 cells accessible\n                            int d = (tx == hx - 1) ? 0 : (tx == hx + 1) ? 1 : (ty == hy - 1) ? 2 : 3;\n                            actions[idx] = wall_cmd[d];\n                            will_build[idx] = true;\n                            next_pos[idx] = {hx, hy};\n                            acted = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (acted) continue;\n            \n            // Move toward nearest target\n            if (!human_targets[idx].empty()) {\n                // Find nearest reachable target\n                int best_target = -1;\n                int best_dist = 1000;\n                \n                for (int i = 0; i < (int)human_targets[idx].size(); i++) {\n                    int tx = human_targets[idx][i].first;\n                    int ty = human_targets[idx][i].second;\n                    int d = abs(tx - hx) + abs(ty - hy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_target = i;\n                    }\n                }\n                \n                if (best_target != -1) {\n                    int tx = human_targets[idx][best_target].first;\n                    int ty = human_targets[idx][best_target].second;\n                    int d = bfs_next_move(hx, hy, tx, ty, occupied);\n                    \n                    if (d != -1) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        actions[idx] = move_cmd[d];\n                        next_pos[idx] = {nx, ny};\n                        // Update occupied for subsequent humans\n                        for (auto& o : occupied) {\n                            if (o.first == hx && o.second == hy) {\n                                o = {nx, ny};\n                                break;\n                            }\n                        }\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                // Defensive: move away from pets if too close\n                int min_dist = nearest_pet_dist(hx, hy);\n                if (min_dist <= 2) {\n                    int best_d = -1;\n                    int max_new_dist = min_dist;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (!is_passable(nx, ny)) continue;\n                        \n                        bool collides = false;\n                        for (auto& o : occupied) {\n                            if (o.first == nx && o.second == ny && !(o.first == hx && o.second == hy)) {\n                                collides = true;\n                                break;\n                            }\n                        }\n                        if (collides) continue;\n                        \n                        int new_dist = 1000;\n                        for (auto& p : pets) {\n                            new_dist = min(new_dist, abs(p.x - nx) + abs(p.y - ny));\n                        }\n                        if (new_dist > max_new_dist) {\n                            max_new_dist = new_dist;\n                            best_d = d;\n                        }\n                    }\n                    if (best_d != -1) {\n                        actions[idx] = move_cmd[best_d];\n                        next_pos[idx] = {hx + dx[best_d], hy + dy[best_d]};\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                actions[idx] = '.';\n                next_pos[idx] = {hx, hy};\n            }\n        }\n        \n        // Final conflict resolution for moves\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    // Later human stays\n                    actions[j] = '.';\n                    next_pos[j] = {humans[j].x, humans[j].y};\n                }\n            }\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n        \n        // Update state\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u') blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    double score;  // Accumulated expected score from terminated paths\n    double value;  // Upper bound = score + sum(prob[i] * V[step][i])\n    array<double, 400> prob;\n    string s;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    const int N = 20;\n    auto ID = [&](int i, int j) { return i * N + j; };\n    const int target = ID(ti, tj);\n    const int start = ID(si, sj);\n    const double q = 1.0 - p;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    /*------------------------------------------------------------\n        1. Precompute transitions\n      ------------------------------------------------------------*/\n    int nxt[400][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            int id = ID(i, j);\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                bool wall = false;\n                if (dir == 0) wall = (i == 0) ? true : (v[i-1][j] == '1');\n                else if (dir == 1) wall = (i == 19) ? true : (v[i][j] == '1');\n                else if (dir == 2) wall = (j == 0) ? true : (h[i][j-1] == '1');\n                else wall = (j == 19) ? true : (h[i][j] == '1');\n                nxt[id][dir] = wall ? id : ID(ni, nj);\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        2. Compute closed-loop optimal values V[t][i] (corrected)\n           V[t][i] = max expected additional score from step t (0-indexed)\n      ------------------------------------------------------------*/\n    vector<array<double, 400>> V(201);\n    for (int i = 0; i < 400; ++i) V[200][i] = 0.0;\n    \n    for (int t = 199; t >= 0; --t) {\n        double turn_score = 401.0 - (t + 1);\n        for (int i = 0; i < 400; ++i) {\n            if (i == target) {\n                V[t][i] = 0.0; // Already stopped\n                continue;\n            }\n            double best_val = 0.0;\n            for (int dir = 0; dir < 4; ++dir) {\n                int to = nxt[i][dir];\n                double reward = (to == target) ? turn_score : V[t+1][to];\n                double val = p * V[t+1][i] + q * reward;\n                if (val > best_val) best_val = val;\n            }\n            V[t][i] = best_val;\n        }\n    }\n    \n    /*------------------------------------------------------------\n        3. Exact evaluation function\n      ------------------------------------------------------------*/\n    auto evaluate = [&](const string& s) -> double {\n        array<double, 400> cur{}, nxt_arr{};\n        cur.fill(0.0);\n        cur[start] = 1.0;\n        double score = 0.0;\n        for (int step = 0; step < (int)s.size(); ++step) {\n            nxt_arr.fill(0.0);\n            int dir = (s[step] == 'U') ? 0 : (s[step] == 'D') ? 1 : (s[step] == 'L') ? 2 : 3;\n            double ts = 401.0 - (step + 1);\n            for (int i = 0; i < 400; ++i) {\n                double pr = cur[i];\n                if (pr < 1e-15) continue;\n                // Forgot\n                nxt_arr[i] += pr * p;\n                // Move\n                int to = nxt[i][dir];\n                if (to == target) score += pr * q * ts;\n                else nxt_arr[to] += pr * q;\n            }\n            cur.swap(nxt_arr);\n        }\n        return score;\n    };\n    \n    /*------------------------------------------------------------\n        4. Beam Search (width 100)\n      ------------------------------------------------------------*/\n    const int BEAM = 100;\n    vector<State> beam;\n    State init;\n    init.score = 0.0;\n    init.prob.fill(0.0);\n    init.prob[start] = 1.0;\n    init.s.clear();\n    init.value = V[0][start]; // Upper bound for initial state\n    beam.push_back(init);\n    \n    string best_string;\n    double best_score = 0.0;\n    \n    for (int step = 0; step < 200; ++step) {\n        vector<State> cand;\n        cand.reserve(beam.size() * 4);\n        \n        for (const State& st : beam) {\n            // Pruning: if upper bound <= best found, skip\n            if (st.value <= best_score) continue;\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                State ns;\n                ns.score = st.score;\n                ns.prob.fill(0.0);\n                double ts = 401.0 - (step + 1);\n                \n                for (int i = 0; i < 400; ++i) {\n                    double pr = st.prob[i];\n                    if (pr < 1e-15) continue;\n                    // Forgot\n                    ns.prob[i] += pr * p;\n                    // Move\n                    int to = nxt[i][dir];\n                    if (to == target) ns.score += pr * q * ts;\n                    else ns.prob[to] += pr * q;\n                }\n                \n                ns.s = st.s + dc[dir];\n                \n                // Compute heuristic for next step\n                double future = 0.0;\n                if (step + 1 < 200) {\n                    for (int i = 0; i < 400; ++i) future += ns.prob[i] * V[step+1][i];\n                }\n                ns.value = ns.score + future;\n                \n                if (ns.score > best_score) {\n                    best_score = ns.score;\n                    best_string = ns.s;\n                }\n                \n                cand.push_back(ns);\n            }\n        }\n        \n        if (cand.empty()) break;\n        \n        // Keep top BEAM states by value\n        if ((int)cand.size() > BEAM) {\n            nth_element(cand.begin(), cand.begin() + BEAM, cand.end(),\n                [](const State& a, const State& b) { return a.value > b.value; });\n            cand.resize(BEAM);\n        }\n        beam.swap(cand);\n    }\n    \n    // If beam didn't find anything (unlikely), use simple path\n    if (best_string.empty()) {\n        best_string = string(100, 'D'); // Dummy fallback\n        best_score = evaluate(best_string);\n    }\n    \n    /*------------------------------------------------------------\n        5. Hill Climbing with Incremental Evaluation\n      ------------------------------------------------------------*/\n    string cur_s = best_string;\n    double cur_val = evaluate(cur_s);\n    best_score = cur_val;\n    best_string = cur_s;\n    \n    mt19937 rng(12345);\n    const int MAX_EVAL = 3000;\n    int eval_count = 0;\n    bool improved = true;\n    \n    while (improved && eval_count < MAX_EVAL) {\n        improved = false;\n        int L = cur_s.size();\n        vector<array<double, 400>> pref(L + 1);\n        vector<double> pref_score(L + 1);\n        pref[0].fill(0.0);\n        pref[0][start] = 1.0;\n        pref_score[0] = 0.0;\n        \n        // Precompute prefix distributions and scores\n        for (int i = 0; i < L; ++i) {\n            pref[i+1].fill(0.0);\n            int dir = (cur_s[i] == 'U') ? 0 : (cur_s[i] == 'D') ? 1 : (cur_s[i] == 'L') ? 2 : 3;\n            double ts = 401.0 - (i + 1);\n            double sc = 0.0;\n            for (int j = 0; j < 400; ++j) {\n                double pr = pref[i][j];\n                if (pr < 1e-15) continue;\n                // Forgot\n                pref[i+1][j] += pr * p;\n                // Move\n                int to = nxt[j][dir];\n                if (to == target) sc += pr * q * ts;\n                else pref[i+1][to] += pr * q;\n            }\n            pref_score[i+1] = pref_score[i] + sc;\n        }\n        \n        // Try changing each position\n        for (int pos = 0; pos < L && eval_count < MAX_EVAL; ++pos) {\n            char orig = cur_s[pos];\n            for (int nd = 0; nd < 4; ++nd) {\n                char c = dc[nd];\n                if (c == orig) continue;\n                \n                // Evaluate change at pos using prefix[pos] and simulating suffix\n                array<double, 400> dist = pref[pos];\n                double sc = pref_score[pos];\n                \n                // Apply new char at pos\n                {\n                    array<double, 400> ndist{};\n                    ndist.fill(0.0);\n                    int dir = nd;\n                    double ts = 401.0 - (pos + 1);\n                    for (int j = 0; j < 400; ++j) {\n                        double pr = dist[j];\n                        if (pr < 1e-15) continue;\n                        ndist[j] += pr * p;\n                        int to = nxt[j][dir];\n                        if (to == target) sc += pr * q * ts;\n                        else ndist[to] += pr * q;\n                    }\n                    dist = ndist;\n                }\n                \n                // Apply suffix s[pos+1..]\n                for (int k = pos + 1; k < L; ++k) {\n                    array<double, 400> ndist{};\n                    ndist.fill(0.0);\n                    int dir = (cur_s[k] == 'U') ? 0 : (cur_s[k] == 'D') ? 1 : (cur_s[k] == 'L') ? 2 : 3;\n                    double ts = 401.0 - (k + 1);\n                    for (int j = 0; j < 400; ++j) {\n                        double pr = dist[j];\n                        if (pr < 1e-15) continue;\n                        ndist[j] += pr * p;\n                        int to = nxt[j][dir];\n                        if (to == target) sc += pr * q * ts;\n                        else ndist[to] += pr * q;\n                    }\n                    dist = ndist;\n                }\n                \n                ++eval_count;\n                \n                if (sc > cur_val + 1e-9) {\n                    cur_s[pos] = c;\n                    cur_val = sc;\n                    improved = true;\n                    if (sc > best_score) {\n                        best_score = sc;\n                        best_string = cur_s;\n                    }\n                    goto next_iter; // Restart with new string\n                }\n            }\n        }\n        next_iter:;\n    }\n    \n    cout << best_string << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG() { s = chrono::steady_clock::now().time_since_epoch().count(); }\n    inline uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline int rand(int n) { return next() % n; }\n    inline double drand() { return (double)next() / UINT32_MAX; }\n} rng;\n\nconst int rot[8][4] = {\n    {0, 1, 2, 3},\n    {1, 2, 3, 0},\n    {2, 3, 0, 1},\n    {3, 0, 1, 2},\n    {4, 5, 4, 5},\n    {5, 4, 5, 4},\n    {6, 7, 6, 7},\n    {7, 6, 7, 6}\n};\n\nconst int8_t to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nconst int8_t di[4] = {0, -1, 0, 1};\nconst int8_t dj[4] = {-1, 0, 1, 0};\n\nstatic int16_t nxt[3600];\nstatic int16_t dist_arr[3600];\nstatic uint32_t visited[3600];\nstatic uint32_t visit_token = 1;\n\ninline int eval(int& L1, int& L2) {\n    if (++visit_token == 0) {\n        memset(visited, 0, sizeof(visited));\n        visit_token = 1;\n    }\n    \n    L1 = L2 = 0;\n    \n    for (int s = 0; s < 3600; s++) {\n        if (visited[s] == visit_token || nxt[s] < 0) continue;\n        \n        int cur = s;\n        int depth = 0;\n        \n        while (cur >= 0) {\n            if (visited[cur] == visit_token) {\n                if (dist_arr[cur] >= 0) {\n                    int len = depth - dist_arr[cur];\n                    if (len > L1) { L2 = L1; L1 = len; }\n                    else if (len > L2) { L2 = len; }\n                }\n                break;\n            }\n            visited[cur] = visit_token;\n            dist_arr[cur] = depth++;\n            cur = nxt[cur];\n        }\n        \n        cur = s;\n        while (cur >= 0 && visited[cur] == visit_token && dist_arr[cur] >= 0) {\n            dist_arr[cur] = -1;\n            cur = nxt[cur];\n        }\n    }\n    \n    return (L2 > 0) ? L1 * L2 : 0;\n}\n\ninline void build(const array<array<int, 30>, 30>& r, \n                 const array<array<int, 30>, 30>& init) {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = rot[init[i][j]][r[i][j]];\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                int8_t d2 = to[t][d];\n                if (d2 < 0) {\n                    nxt[base + d] = -1;\n                } else {\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) {\n                        nxt[base + d] = -1;\n                    } else {\n                        nxt[base + d] = (ni * 30 + nj) * 4 + ((d2 + 2) & 3);\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Crossover: take random rectangle from a, rest from b\nvoid crossover(array<array<int, 30>, 30>& res,\n               const array<array<int, 30>, 30>& a,\n               const array<array<int, 30>, 30>& b) {\n    int i1 = rng.rand(30), i2 = rng.rand(30);\n    int j1 = rng.rand(30), j2 = rng.rand(30);\n    if (i1 > i2) swap(i1, i2);\n    if (j1 > j2) swap(j1, j2);\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            if (i >= i1 && i <= i2 && j >= j1 && j <= j2) {\n                res[i][j] = a[i][j];\n            } else {\n                res[i][j] = b[i][j];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    array<array<int, 30>, 30> init{};\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) init[i][j] = s[j] - '0';\n    }\n    \n    array<array<int, 30>, 30> best{}, cur{}, tmp{};\n    int best_score = -1;\n    int L1, L2;\n    \n    const double TL = 1.92;\n    clock_t start = clock();\n    \n    // Keep top 3 solutions for crossover\n    vector<pair<int, array<array<int, 30>, 30>>> elite;\n    \n    // Many quick restarts\n    for (int restart = 0; restart < 35; restart++) {\n        double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n        if (elapsed > TL * 0.8) break;\n        \n        // Init: random or crossover from elite\n        if (!elite.empty() && rng.drand() < 0.3 && elite.size() >= 2) {\n            int a = rng.rand(elite.size());\n            int b = rng.rand(elite.size());\n            while (b == a) b = rng.rand(elite.size());\n            crossover(cur, elite[a].second, elite[b].second);\n        } else {\n            for (int i = 0; i < 30; i++)\n                for (int j = 0; j < 30; j++)\n                    cur[i][j] = rng.rand(4);\n        }\n        \n        build(cur, init);\n        int cur_score = eval(L1, L2);\n        \n        // Update elite\n        if (cur_score > 0) {\n            elite.push_back({cur_score, cur});\n            sort(elite.begin(), elite.end(), greater<pair<int, array<array<int, 30>, 30>>>());\n            if (elite.size() > 3) elite.resize(3);\n        }\n        \n        if (cur_score > best_score) {\n            best_score = cur_score;\n            memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n        }\n        \n        // Very short SA\n        double temp = 50.0;\n        int iter = 0;\n        int last_imp = 0;\n        double phase_end = min(elapsed + 0.045, TL * 0.85);\n        \n        while (true) {\n            elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elapsed > phase_end || elapsed > TL * 0.85) break;\n            \n            int i = rng.rand(30);\n            int j = rng.rand(30);\n            int old = cur[i][j];\n            \n            // Try 2 random rotations\n            for (int trial = 0; trial < 2; trial++) {\n                cur[i][j] = rng.rand(4);\n                if (cur[i][j] == old) continue;\n                \n                build(cur, init);\n                int s = eval(L1, L2);\n                \n                if (s >= cur_score || rng.drand() < exp((s - cur_score) / temp)) {\n                    cur_score = s;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                        \n                        // Update elite\n                        elite.push_back({s, cur});\n                        sort(elite.begin(), elite.end(), greater<pair<int, array<array<int, 30>, 30>>>());\n                        if (elite.size() > 3) elite.resize(3);\n                        \n                        last_imp = iter;\n                    }\n                    old = cur[i][j];\n                } else {\n                    cur[i][j] = old;\n                }\n            }\n            \n            temp *= 0.999;\n            iter++;\n            \n            if (iter - last_imp > 1500) {\n                // Perturb\n                for (int k = 0; k < 60; k++) {\n                    cur[rng.rand(30)][rng.rand(30)] = rng.rand(4);\n                }\n                build(cur, init);\n                cur_score = eval(L1, L2);\n                last_imp = iter;\n                temp = 30.0;\n            }\n        }\n    }\n    \n    // Intensive greedy from best\n    memcpy(&cur[0][0], &best[0][0], 900 * sizeof(int));\n    build(cur, init);\n    int cur_score = eval(L1, L2);\n    \n    for (int big_round = 0; big_round < 5; big_round++) {\n        bool any_improve = false;\n        \n        // Random order\n        vector<int> order(900);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), mt19937(rng.next()));\n        \n        for (int idx : order) {\n            double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elapsed > TL) goto output;\n            \n            int i = idx / 30;\n            int j = idx % 30;\n            int old = cur[i][j];\n            \n            for (int r = 0; r < 4; r++) {\n                if (r == old) continue;\n                cur[i][j] = r;\n                build(cur, init);\n                int s = eval(L1, L2);\n                if (s > cur_score) {\n                    cur_score = s;\n                    any_improve = true;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                    }\n                    goto next_tile;\n                }\n            }\n            cur[i][j] = old;\n            next_tile:;\n        }\n        \n        if (!any_improve) break;\n    }\n    \n    // Try 2-swap optimizations\n    memcpy(&cur[0][0], &best[0][0], 900 * sizeof(int));\n    build(cur, init);\n    cur_score = eval(L1, L2);\n    \n    for (int attempt = 0; attempt < 2000; attempt++) {\n        double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n        if (elapsed > TL) break;\n        \n        int i1 = rng.rand(30), j1 = rng.rand(30);\n        int i2 = rng.rand(30), j2 = rng.rand(30);\n        if (abs(i1-i2) + abs(j1-j2) > 3) continue; // nearby tiles only\n        \n        int old1 = cur[i1][j1];\n        int old2 = cur[i2][j2];\n        \n        for (int r1 = 0; r1 < 4; r1++) {\n            for (int r2 = 0; r2 < 4; r2++) {\n                if (r1 == old1 && r2 == old2) continue;\n                cur[i1][j1] = r1;\n                cur[i2][j2] = r2;\n                build(cur, init);\n                int s = eval(L1, L2);\n                if (s > cur_score) {\n                    cur_score = s;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                    }\n                    goto next_swap;\n                }\n            }\n        }\n        cur[i1][j1] = old1;\n        cur[i2][j2] = old2;\n        next_swap:;\n    }\n    \n    output:\n    string out;\n    out.reserve(900);\n    for (int i = 0; i < 30; i++)\n        for (int j = 0; j < 30; j++)\n            out += char('0' + best[i][j]);\n    cout << out << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, TARGET;\nchrono::time_point<chrono::steady_clock> start_time;\nconst double TL = 2.9;\n\ninline bool timeout() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > TL;\n}\n\nstruct State {\n    array<array<uint8_t, 10>, 10> bd;\n    int er, ec;\n    vector<char> moves;\n    int score;\n    \n    void init(const vector<string>& board) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = board[i][j];\n                bd[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n                if (bd[i][j] == 0) {\n                    er = i;\n                    ec = j;\n                }\n            }\n        }\n        moves.clear();\n        score = calc_score();\n    }\n    \n    inline bool in(int r, int c) const {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    inline char rev(char c) const {\n        return c == 'U' ? 'D' : c == 'D' ? 'U' : c == 'L' ? 'R' : 'L';\n    }\n    \n    inline bool can(char c) const {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else nc++;\n        return in(nr, nc);\n    }\n    \n    inline void move(char c) {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else nc++;\n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n        moves.push_back(c);\n    }\n    \n    int calc_score() const {\n        int par[100];\n        iota(par, par + N*N, 0);\n        \n        function<int(int)> find = [&](int x) -> int {\n            return par[x] == x ? x : par[x] = find(par[x]);\n        };\n        \n        auto unite = [&](int x, int y) {\n            x = find(x), y = find(y);\n            if (x != y) par[x] = y;\n        };\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N-1; j++) {\n                if (bd[i][j] && bd[i][j+1] && (bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    unite(i*N + j, i*N + j + 1);\n                }\n            }\n        }\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] && bd[i+1][j] && (bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    unite(i*N + j, (i+1)*N + j);\n                }\n            }\n        }\n        \n        int vert[100] = {}, edge[100] = {};\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j]) vert[find(i*N + j)]++;\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N-1; j++) {\n                if (bd[i][j] && bd[i][j+1] && (bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    edge[find(i*N + j)]++;\n                }\n            }\n        }\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] && bd[i+1][j] && (bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    edge[find(i*N + j)]++;\n                }\n            }\n        }\n        \n        int best = 0;\n        for (int i = 0; i < N*N; i++) {\n            if (vert[i] > 0 && edge[i] == vert[i] - 1) {\n                best = max(best, vert[i]);\n            }\n        }\n        return best;\n    }\n    \n    void copy_from(const State& o) {\n        bd = o.bd;\n        er = o.er;\n        ec = o.ec;\n        moves = o.moves;\n        score = o.score;\n    }\n};\n\n// Run SA with given seed, return best state found\nState run_sa(const vector<string>& board, uint32_t seed, double time_limit) {\n    mt19937 rng(seed);\n    State cur, init;\n    init.init(board);\n    cur.copy_from(init);\n    \n    State best;\n    best.copy_from(cur);\n    \n    const double START_TEMP = 50.0;\n    double temp = START_TEMP;\n    int iter = 0;\n    int no_improve = 0;\n    \n    auto epoch_start = chrono::steady_clock::now();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - epoch_start).count();\n        if (elapsed > time_limit) break;\n        \n        // Reset if path too long or stuck\n        if ((int)cur.moves.size() >= T - 5 || no_improve > 5000) {\n            cur.copy_from(init);\n            temp = START_TEMP;\n            no_improve = 0;\n            continue;\n        }\n        \n        char ban = cur.moves.empty() ? 'X' : cur.rev(cur.moves.back());\n        vector<pair<char, int>> cand;\n        \n        for (char c : {'U', 'D', 'L', 'R'}) {\n            if (c == ban) continue;\n            if (!cur.can(c)) continue;\n            \n            State nxt = cur;\n            nxt.move(c);\n            int sc = nxt.calc_score();\n            cand.push_back({c, sc});\n        }\n        \n        if (cand.empty()) continue;\n        \n        sort(cand.begin(), cand.end(), [](auto& a, auto& b) { return a.second > b.second; });\n        \n        char pick;\n        int new_score;\n        bool accept = false;\n        \n        // Greedy improvement\n        if (cand[0].second > cur.score) {\n            pick = cand[0].first;\n            new_score = cand[0].second;\n            accept = true;\n        }\n        // Equal score - sometimes accept to explore\n        else if (cand[0].second == cur.score && (rng() & 3) == 0) {\n            pick = cand[0].first;\n            new_score = cand[0].second;\n            accept = true;\n        }\n        // SA acceptance\n        else {\n            uniform_int_distribution<int> dist(0, min(2, (int)cand.size()) - 1);\n            int idx = dist(rng);\n            pick = cand[idx].first;\n            new_score = cand[idx].second;\n            \n            if (new_score > cur.score || \n                exp((new_score - cur.score) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            cur.move(pick);\n            cur.score = new_score;\n            \n            if (cur.score > best.score || \n                (cur.score == best.score && cur.score == TARGET && cur.moves.size() < best.moves.size())) {\n                best.copy_from(cur);\n                no_improve = 0;\n            } else {\n                no_improve++;\n            }\n        } else {\n            no_improve++;\n        }\n        \n        temp *= 0.99995;\n        iter++;\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    TARGET = N*N - 1;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    start_time = chrono::steady_clock::now();\n    \n    State global_best;\n    global_best.init(board);\n    \n    int epoch = 0;\n    while (!timeout()) {\n        double remaining = TL - chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (remaining < 0.1) break;\n        \n        // Distribute time: early epochs get more time\n        double epoch_time = min(remaining / 3.0, 0.5);\n        \n        uint32_t seed = chrono::steady_clock::now().time_since_epoch().count() + epoch * 1234567;\n        State result = run_sa(board, seed, epoch_time);\n        \n        if (result.score > global_best.score ||\n            (result.score == global_best.score && result.score == TARGET && result.moves.size() < global_best.moves.size())) {\n            global_best.copy_from(result);\n        }\n        \n        // Early termination if perfect and good length\n        if (global_best.score == TARGET && global_best.moves.size() <= T * 0.5) {\n            break;\n        }\n        \n        epoch++;\n    }\n    \n    // Verify\n    State verify;\n    verify.init(board);\n    for (char c : global_best.moves) {\n        if (!verify.can(c)) {\n            cout << \"\\n\";\n            return 0;\n        }\n        verify.move(c);\n    }\n    \n    string result(global_best.moves.begin(), global_best.moves.end());\n    cout << result << \"\\n\";\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long x1, y1, x2, y2;\n};\n\nint N, K;\nint target[11];\nint cur_cnt[12];\nvector<Point> pts;\nvector<Line> cuts;\nvector<vector<int>> pieces;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint side(const Point& p, const Line& ln) {\n    long long v1x = ln.x2 - ln.x1;\n    long long v1y = ln.y2 - ln.y1;\n    long long v2x = p.x - ln.x1;\n    long long v2y = p.y - ln.y1;\n    __int128 cr = (__int128)v1x * v2y - (__int128)v1y * v2x;\n    if (cr < 0) return -1;\n    if (cr > 0) return 1;\n    return 0;\n}\n\nint calc_delta(int S, int a, int b) {\n    int old_score = 0, new_score = 0;\n    \n    if (S >= 1 && S <= 10) {\n        old_score += min(cur_cnt[S], target[S]);\n        new_score += min(cur_cnt[S] - 1, target[S]);\n    }\n    \n    if (a >= 1 && a <= 10) {\n        old_score += min(cur_cnt[a], target[a]);\n        new_score += min(cur_cnt[a] + 1, target[a]);\n    }\n    \n    if (b >= 1 && b <= 10) {\n        int add_b = (a == b) ? 1 : 0;\n        old_score += min(cur_cnt[b], target[b]);\n        new_score += min(cur_cnt[b] + add_b, target[b]);\n    }\n    \n    return new_score - old_score;\n}\n\nbool valid_line(const Line& ln) {\n    const long long LIM = 1000000000LL;\n    return abs(ln.x1) <= LIM && abs(ln.y1) <= LIM && \n           abs(ln.x2) <= LIM && abs(ln.y2) <= LIM &&\n           !(ln.x1 == ln.x2 && ln.y1 == ln.y2);\n}\n\nbool find_split(const vector<int>& P, int want_left, Line& out_ln, int max_iter = 100) {\n    int n = P.size();\n    if (want_left <= 0 || want_left >= n) return false;\n    \n    uniform_real_distribution<double> ang(0.0, 2.0 * M_PI);\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        double th = ang(rng);\n        double dx = cos(th), dy = sin(th);\n        \n        vector<pair<double, int>> proj;\n        proj.reserve(n);\n        for (int idx : P) {\n            proj.emplace_back(dx * pts[idx].x + dy * pts[idx].y, idx);\n        }\n        \n        nth_element(proj.begin(), proj.begin() + want_left, proj.end());\n        double split_val = proj[want_left].first;\n        \n        double max_l = -1e300, min_r = 1e300;\n        int id_l = -1, id_r = -1;\n        int cnt_l = 0;\n        \n        for (auto& [v, id] : proj) {\n            if (v < split_val - 1e-9) {\n                cnt_l++;\n                if (v > max_l) { max_l = v; id_l = id; }\n            } else if (v > split_val + 1e-9) {\n                if (v < min_r) { min_r = v; id_r = id; }\n            }\n        }\n        \n        // Assign boundary points\n        for (auto& [v, id] : proj) {\n            if (abs(v - split_val) < 1e-9) {\n                if (cnt_l < want_left) {\n                    cnt_l++;\n                    if (v > max_l) { max_l = v; id_l = id; }\n                } else {\n                    if (v < min_r) { min_r = v; id_r = id; }\n                }\n            }\n        }\n        \n        if (cnt_l != want_left || id_l == -1 || id_r == -1) continue;\n        if (max_l >= min_r) continue;\n        \n        double mx = (pts[id_l].x + pts[id_r].x) / 2.0;\n        double my = (pts[id_l].y + pts[id_r].y) / 2.0;\n        double px = -dy, py = dx;\n        \n        Line ln;\n        ln.x1 = (long long)round(mx - px * 1e6);\n        ln.y1 = (long long)round(my - py * 1e6);\n        ln.x2 = (long long)round(mx + px * 1e6);\n        ln.y2 = (long long)round(my + py * 1e6);\n        \n        if (!valid_line(ln)) continue;\n        \n        // Verify clean split\n        int cn = 0, cz = 0;\n        for (int idx : P) {\n            int s = side(pts[idx], ln);\n            if (s < 0) cn++;\n            else if (s == 0) cz++;\n        }\n        \n        if (cz > 0) continue;\n        \n        if (cn == want_left) {\n            out_ln = ln;\n            return true;\n        } else if (cn == n - want_left) {\n            swap(ln.x1, ln.x2);\n            swap(ln.y1, ln.y2);\n            out_ln = ln;\n            return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> target[i];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n    \n    pieces.resize(1);\n    pieces[0].resize(N);\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n    \n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    if (N <= 10) cur_cnt[N] = 1;\n    else cur_cnt[0] = 1;\n    \n    for (int cut_iter = 0; cut_iter < K; cut_iter++) {\n        // Select piece: prioritize by type then size\n        int best_pidx = -1, best_pri = -1;\n        for (int i = 0; i < (int)pieces.size(); i++) {\n            int S = pieces[i].size();\n            if (S <= 1) continue;\n            int pri = S;\n            if (S > 10) pri += 10000;      // Waste - must split\n            else if (cur_cnt[S] > target[S]) pri += 100; // Excess\n            if (pri > best_pri) {\n                best_pri = pri;\n                best_pidx = i;\n            }\n        }\n        \n        if (best_pidx == -1) break;\n        \n        const auto& P = pieces[best_pidx];\n        int S = P.size();\n        \n        // Generate candidate splits\n        vector<pair<int, int>> cands; // (delta, a)\n        \n        // First: try to create two needed pieces\n        for (int a = 1; a < S && a <= 10; a++) {\n            int b = S - a;\n            int delta = calc_delta(S, a, b);\n            if (delta > 0) cands.emplace_back(delta, a);\n        }\n        \n        // If none, try neutral splits (delta == 0)\n        if (cands.empty()) {\n            for (int a = max(1, S/2 - 1); a <= min(S-1, S/2 + 1); a++) {\n                int b = S - a;\n                int delta = calc_delta(S, a, b);\n                cands.emplace_back(delta, a);\n            }\n        }\n        \n        // If still nothing (shouldn't happen for S>1), try any split\n        if (cands.empty()) {\n            cands.emplace_back(-1, S/2);\n        }\n        \n        // Sort by delta descending\n        sort(cands.rbegin(), cands.rend());\n        \n        // Try unique candidates\n        bool found = false;\n        Line best_ln;\n        int best_a = 0, best_b = 0;\n        \n        int prev_a = -1;\n        for (auto& [d, a] : cands) {\n            if (a == prev_a) continue;\n            prev_a = a;\n            \n            Line ln;\n            // More iterations for critical pieces\n            int iters = (S > 10) ? 200 : 80;\n            if (find_split(P, a, ln, iters)) {\n                found = true;\n                best_ln = ln;\n                best_a = a;\n                best_b = S - a;\n                break;\n            }\n        }\n        \n        if (!found) continue; // Skip this cut, try next iteration\n        \n        // Apply cut\n        vector<int> left, right;\n        for (int idx : P) {\n            if (side(pts[idx], best_ln) < 0) left.push_back(idx);\n            else right.push_back(idx);\n        }\n        \n        // Update counts\n        if (S <= 10) cur_cnt[S]--;\n        else cur_cnt[0]--;\n        if (best_a <= 10) cur_cnt[best_a]++;\n        else cur_cnt[0]++;\n        if (best_b <= 10) cur_cnt[best_b]++;\n        else cur_cnt[0]++;\n        \n        pieces[best_pidx] = move(left);\n        pieces.push_back(move(right));\n        cuts.push_back(best_ln);\n    }\n    \n    cout << cuts.size() << \"\\n\";\n    for (auto& ln : cuts) {\n        cout << ln.x1 << \" \" << ln.y1 << \" \" << ln.x2 << \" \" << ln.y2 << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nusing ull = unsigned long long;\nusing ll = long long;\n\nint N, M, C;\nconst double TIME_LIMIT = 4.8;\n\n/* bitset containers */\nvector<ull> dot_row, dot_col;\nvector<ull> dot_diag1, dot_diag2; // diag1: x-y, diag2: x+y\nvector<ull> edge_h, edge_v;\nvector<ull> edge_diag1, edge_diag2;\n\nstruct Operation {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\ninline double get_time() {\n    return chrono::duration<double>(chrono::steady_clock::now().time_since_epoch()).count();\n}\n\n/* ---------- mask helpers ---------- */\ninline ull mask_closed(int l, int r) { // [l, r] inclusive, r>=l, length <= 60\n    return ((1ULL << (r - l + 1)) - 1ULL) << l;\n}\ninline ull mask_open(int l, int r) { // (l, r) exclusive, assumes l<r\n    if (r - l <= 1) return 0ULL;\n    return ((1ULL << (r - l - 1)) - 1ULL) << (l + 1);\n}\n\n/* ---------- adding dots / edges ---------- */\ninline void add_dot(int x, int y) {\n    dot_row[y] |= (1ULL << x);\n    dot_col[x] |= (1ULL << y);\n    dot_diag1[x - y + (N - 1)] |= (1ULL << x);\n    dot_diag2[x + y] |= (1ULL << x);\n}\ninline void add_edge_h(int y, int l, int r) { // [l, r] edges (r>l)\n    edge_h[y] |= mask_closed(l, r - 1);\n}\ninline void add_edge_v(int x, int l, int r) {\n    edge_v[x] |= mask_closed(l, r - 1);\n}\ninline void add_edge_diag1(int d_idx, int l, int r) { // [l, r-1]\n    edge_diag1[d_idx] |= mask_closed(l, r - 1);\n}\ninline void add_edge_diag2(int s, int l, int r) {\n    edge_diag2[s] |= mask_closed(l, r - 1);\n}\n\n/* ---------- axis aligned test & add ---------- */\nbool check_axis(int x1, int y1, int x2, int y2) { // opposite corner (x2,y2)\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    if (xr - xl <= 0 || yr - yl <= 0) return false;\n\n    /* dots on perimeter (excluding the four corners) */\n    if (mask_open(xl, xr) & (dot_row[yl] | dot_row[yr])) return false;\n    if (mask_open(yl, yr) & (dot_col[xl] | dot_col[xr])) return false;\n\n    /* edges must be free */\n    ull hmask = mask_closed(xl, xr - 1);\n    if ((edge_h[yl] & hmask) || (edge_h[yr] & hmask)) return false;\n    ull vmask = mask_closed(yl, yr - 1);\n    if ((edge_v[xl] & vmask) || (edge_v[xr] & vmask)) return false;\n    return true;\n}\nvoid apply_axis(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    add_edge_h(yl, xl, xr);\n    add_edge_h(yr, xl, xr);\n    add_edge_v(xl, yl, yr);\n    add_edge_v(xr, yl, yr);\n}\n\n/* ---------- 45 degree test & add ---------- */\nstruct Cand45 {\n    int x2, y2, x3, y3, x4, y4, perim;\n};\n\nbool check_45(const Cand45 &c, int x1, int y1) {\n    int d1 = x1 - y1 + (N - 1);\n    int s1 = x1 + y1;\n    int s2 = c.x2 + c.y2;          // diagonal of side p2-p3\n    int d3 = c.x3 - c.y3 + (N - 1); // diagonal of side p3-p4\n\n    /* dots on the four sides (open intervals) */\n    if (mask_open(min(x1, c.x2), max(x1, c.x2)) & dot_diag1[d1]) return false;\n    if (mask_open(min(c.x2, c.x3), max(c.x2, c.x3)) & dot_diag2[s2]) return false;\n    if (mask_open(min(c.x3, c.x4), max(c.x3, c.x4)) & dot_diag1[d3]) return false;\n    if (mask_open(min(c.x4, x1), max(c.x4, x1)) & dot_diag2[s1]) return false;\n\n    /* edges must be free */\n    if (mask_closed(min(x1, c.x2), max(x1, c.x2) - 1) & edge_diag1[d1]) return false;\n    if (mask_closed(min(c.x2, c.x3), max(c.x2, c.x3) - 1) & edge_diag2[s2]) return false;\n    if (mask_closed(min(c.x3, c.x4), max(c.x3, c.x4) - 1) & edge_diag1[d3]) return false;\n    if (mask_closed(min(c.x4, x1), max(c.x4, x1) - 1) & edge_diag2[s1]) return false;\n\n    return true;\n}\nvoid apply_45(const Cand45 &c, int x1, int y1) {\n    int d1 = x1 - y1 + (N - 1);\n    int s1 = x1 + y1;\n    int s2 = c.x2 + c.y2;\n    int d3 = c.x3 - c.y3 + (N - 1);\n    add_edge_diag1(d1, min(x1, c.x2), max(x1, c.x2));\n    add_edge_diag2(s2, min(c.x2, c.x3), max(c.x2, c.x3));\n    add_edge_diag1(d3, min(c.x3, c.x4), max(c.x3, c.x4));\n    add_edge_diag2(s1, min(c.x4, x1), max(c.x4, x1));\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    C = (N - 1) / 2;\n\n    vector<pair<int,int>> init_dots;\n    init_dots.reserve(M);\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        init_dots.emplace_back(x, y);\n    }\n\n    /* weights */\n    vector<vector<int>> W(N, vector<int>(N));\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            W[x][y] = (x - C) * (x - C) + (y - C) * (y - C) + 1;\n\n    double start = get_time();\n    vector<Operation> best_ops;\n    ll best_score = -1;\n    unsigned rng_seed = (unsigned)chrono::steady_clock::now().time_since_epoch().count();\n    mt19937 rng(rng_seed);\n\n    /* list of empty cells with weight */\n    vector<tuple<int,int,int>> cells; // (-weight, x, y) for easier sorting if needed, but we shuffle then sort\n    cells.reserve(N * N);\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            cells.emplace_back(W[x][y], x, y);\n\n    /* diagonal containers for existing dots (dynamic) */\n    // We will maintain vectors of x-coordinates for each diagonal.\n    vector<vector<int>> list_diag1(2 * N - 1), list_diag2(2 * N);\n\n    while (get_time() - start < TIME_LIMIT) {\n        /* reset structures */\n        dot_row.assign(N, 0ULL);\n        dot_col.assign(N, 0ULL);\n        dot_diag1.assign(2 * N - 1, 0ULL);\n        dot_diag2.assign(2 * N, 0ULL);\n        edge_h.assign(N, 0ULL);\n        edge_v.assign(N, 0ULL);\n        edge_diag1.assign(2 * N - 1, 0ULL);\n        edge_diag2.assign(2 * N, 0ULL);\n\n        for (auto &p : init_dots) add_dot(p.first, p.second);\n\n        // dynamic lists of dots per diagonal (store x, y can be recovered)\n        for (auto &v : list_diag1) v.clear();\n        for (auto &v : list_diag2) v.clear();\n        for (auto &p : init_dots) {\n            list_diag1[p.first - p.second + (N - 1)].push_back(p.first);\n            list_diag2[p.first + p.second].push_back(p.first);\n        }\n\n        vector<pair<int,int>> dots = init_dots; // list of all dots (grows)\n\n        /* processing order: shuffle among equal weight, then sort by weight desc */\n        vector<tuple<int,int,int>> ord = cells;\n        shuffle(ord.begin(), ord.end(), rng);\n        sort(ord.begin(), ord.end(),\n             [](const auto& a, const auto& b) { return get<0>(a) > get<0>(b); });\n\n        vector<Operation> ops;\n        ll cur_score = 0;\n        for (auto &p : init_dots) cur_score += W[p.first][p.second];\n\n        bool progress = true;\n        while (progress) {\n            progress = false;\n            for (auto &[val, x1, y1] : ord) {\n                if ( (dot_row[y1] >> x1) & 1ULL ) continue; // already placed\n\n                vector<pair<int, Cand45>> cand; // (perimeter, candidate)\n\n                /* ---- axis aligned: iterate dots in same row / col ---- */\n                // p2 on same row y1, p4 on same col x1\n                ull rowbits = dot_row[y1];\n                while (rowbits) {\n                    int x2 = __builtin_ctzll(rowbits);\n                    rowbits &= rowbits - 1;\n                    if (x2 == x1) continue;\n                    // need p4 = (x1, y2) with dot, and p3 = (x2, y2) with dot\n                    ull colbits = dot_col[x1];\n                    while (colbits) {\n                        int y2 = __builtin_ctzll(colbits);\n                        colbits &= colbits - 1;\n                        if (y2 == y1) continue;\n                        if ( (dot_row[y2] >> x2) & 1ULL ) {\n                            int perim = 2 * (abs(x1 - x2) + abs(y1 - y2));\n                            // axis candidate encoded with x3=x2,y3=y2 and axis flag (perim>0)\n                            cand.emplace_back(perim, Cand45{x2, y1, x2, y2, x1, y2, perim});\n                        }\n                    }\n                }\n\n                /* ---- 45 degree: combine dots from the two diagonals through p1 ---- */\n                int d1_idx = x1 - y1 + (N - 1);\n                int s1 = x1 + y1;\n                for (int x2 : list_diag1[d1_idx]) {\n                    if (x2 == x1) continue;\n                    int y2 = x2 - (x1 - y1); // because x2-y2 = x1-y1\n                    // verify dot (paranoia)\n                    if ( ((dot_row[y2] >> x2) & 1ULL) == 0 ) continue;\n                    for (int x4 : list_diag2[s1]) {\n                        if (x4 == x1) continue;\n                        int y4 = s1 - x4;\n                        if ( ((dot_row[y4] >> x4) & 1ULL) == 0 ) continue;\n                        int x3 = x2 + x4 - x1;\n                        int y3 = y2 + y4 - y1;\n                        if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                        if ( ((dot_row[y3] >> x3) & 1ULL) == 0 ) continue;\n                        int a = abs(x2 - x1);\n                        int b = abs(x4 - x1);\n                        int perim = 2 * (a + b); // |a|+|b| is the half-perimeter? Actually side lengths are sqrt(2)*|a| etc.\n                        // perimeter in grid units: each side has |a| steps for one pair, |b| for the other.\n                        // total perimeter = 2*(|a|+|b|) in terms of unit edges.\n                        cand.emplace_back(perim, Cand45{x2, y2, x3, y3, x4, y4, perim});\n                    }\n                }\n\n                if (cand.empty()) continue;\n\n                int strat = uniform_int_distribution<int>(0, 2)(rng);\n                if (strat == 0)\n                    sort(cand.begin(), cand.end(),\n                         [](const auto& a, const auto& b){ return a.first < b.first; });\n                else if (strat == 1)\n                    sort(cand.begin(), cand.end(),\n                         [](const auto& a, const auto& b){ return a.first > b.first; });\n                else\n                    shuffle(cand.begin(), cand.end(), rng);\n\n                bool placed = false;\n                for (auto &[perim, c] : cand) {\n                    bool ok;\n                    if (c.x2 == x1 || c.y2 == y1) { // axis (p2 shares y, p4 shares x)\n                        ok = check_axis(x1, y1, c.x3, c.y3);\n                        if (ok) {\n                            apply_axis(x1, y1, c.x3, c.y3);\n                            ops.push_back({x1, y1, c.x2, c.y2, c.x3, c.y3, c.x4, c.y4});\n                        }\n                    } else {\n                        ok = check_45(c, x1, y1);\n                        if (ok) {\n                            apply_45(c, x1, y1);\n                            ops.push_back({x1, y1, c.x2, c.y2, c.x3, c.y3, c.x4, c.y4});\n                        }\n                    }\n                    if (ok) {\n                        add_dot(x1, y1);\n                        dots.emplace_back(x1, y1);\n                        list_diag1[x1 - y1 + (N - 1)].push_back(x1);\n                        list_diag2[x1 + y1].push_back(x1);\n                        cur_score += val;\n                        placed = true;\n                        progress = true;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            best_ops = ops;\n        }\n    }\n\n    cout << best_ops.size() << '\\n';\n    for (auto &op : best_ops) {\n        cout << op.x1 << ' ' << op.y1 << ' '\n             << op.x2 << ' ' << op.y2 << ' '\n             << op.x3 << ' ' << op.y3 << ' '\n             << op.x4 << ' ' << op.y4 << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed = chrono::steady_clock::now().time_since_epoch().count()) {\n        s = seed;\n    }\n    uint64_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return s;\n    }\n    int randint(int n) {\n        return next() % n;\n    }\n} rng;\n\nstruct Grid {\n    uint8_t a[10][10];\n    \n    Grid() {\n        memset(a, 0, sizeof(a));\n    }\n    \n    void place(int p, int f) {\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void placeRandom(int f, int numEmpty) {\n        int p = rng.randint(numEmpty) + 1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') {\n            for (int j = 0; j < 10; j++) {\n                int write = 0;\n                for (int i = 0; i < 10; i++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write++][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'B') {\n            for (int j = 0; j < 10; j++) {\n                int write = 9;\n                for (int i = 9; i >= 0; i--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write--][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'L') {\n            for (int i = 0; i < 10; i++) {\n                int write = 0;\n                for (int j = 0; j < 10; j++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write++] = val;\n                    }\n                }\n            }\n        } else if (dir == 'R') {\n            for (int i = 0; i < 10; i++) {\n                int write = 9;\n                for (int j = 9; j >= 0; j--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write--] = val;\n                    }\n                }\n            }\n        }\n    }\n    \n    int countEmpty() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++)\n            for (int j = 0; j < 10; j++)\n                if (a[i][j] == 0) cnt++;\n        return cnt;\n    }\n    \n    long long calcScore() const {\n        bool vis[10][10] = {};\n        long long res = 0;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] != 0 && !vis[i][j]) {\n                    uint8_t f = a[i][j];\n                    int sz = 0;\n                    int q[100];\n                    int qe = 0;\n                    q[qe++] = i * 10 + j;\n                    vis[i][j] = true;\n                    \n                    while (qe > 0) {\n                        int cur = q[--qe];\n                        int x = cur / 10, y = cur % 10;\n                        sz++;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !vis[nx][ny] && a[nx][ny] == f) {\n                                vis[nx][ny] = true;\n                                q[qe++] = nx * 10 + ny;\n                            }\n                        }\n                    }\n                    res += 1LL * sz * sz;\n                }\n            }\n        }\n        return res;\n    }\n    \n    // Fast heuristic: count same-flavor adjacent pairs\n    int countEdges() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) continue;\n                if (i < 9 && a[i][j] == a[i+1][j]) cnt++;\n                if (j < 9 && a[i][j] == a[i][j+1]) cnt++;\n            }\n        }\n        return cnt;\n    }\n    \n    // Greedy tilt: choose direction maximizing edges\n    char greedyTilt() {\n        char bestDir = 'F';\n        int bestEdges = -1;\n        char dirs[4] = {'F', 'B', 'L', 'R'};\n        \n        for (int d = 0; d < 4; d++) {\n            Grid tmp = *this;\n            tmp.tilt(dirs[d]);\n            int e = tmp.countEdges();\n            if (e > bestEdges) {\n                bestEdges = e;\n                bestDir = dirs[d];\n            }\n        }\n        return bestDir;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> f[i];\n    }\n    \n    Grid grid;\n    const char dirs[4] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        grid.place(p, f[t]);\n        \n        if (t == 99) {\n            cout << \"F\\n\" << flush;\n            break;\n        }\n        \n        int remaining = 99 - t;\n        // Adaptive samples: more samples early when structure matters\n        int samples = max(15, min(50, 2000 / (remaining + 5)));\n        \n        long long bestTotal = -1;\n        char bestDir = 'F';\n        \n        // Try each direction for the current tilt\n        for (int d = 0; d < 4; d++) {\n            long long totalScore = 0;\n            \n            for (int s = 0; s < samples; s++) {\n                Grid sim = grid;\n                sim.tilt(dirs[d]);\n                int numEmpty = 100 - (t + 1);\n                \n                // Rollout with greedy policy\n                for (int tt = t + 1; tt < 100; tt++) {\n                    sim.placeRandom(f[tt], numEmpty--);\n                    char gdir = sim.greedyTilt();\n                    sim.tilt(gdir);\n                }\n                \n                totalScore += sim.calcScore();\n            }\n            \n            if (totalScore > bestTotal) {\n                bestTotal = totalScore;\n                bestDir = dirs[d];\n            }\n        }\n        \n        cout << bestDir << \"\\n\" << flush;\n        grid.tilt(bestDir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nvector<double> extract_features(const vector<bitset<100>>& adj, int N) {\n    vector<double> features;\n    features.reserve(2 * N + 10);\n    \n    // 1. Sorted degrees\n    vector<int> degs(N);\n    for (int i = 0; i < N; ++i) degs[i] = adj[i].count();\n    sort(degs.begin(), degs.end());\n    for (int d : degs) features.push_back(d);\n    \n    // 2. Laplacian eigenvalues\n    Eigen::MatrixXd L = Eigen::MatrixXd::Zero(N, N);\n    for (int i = 0; i < N; ++i) {\n        L(i, i) = degs[i];\n        for (int j = i + 1; j < N; ++j) {\n            if (adj[i][j]) {\n                L(i, j) = L(j, i) = -1.0;\n            }\n        }\n    }\n    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(L);\n    Eigen::VectorXd eig = solver.eigenvalues();\n    sort(eig.data(), eig.data() + N);\n    for (int i = 0; i < N; ++i) features.push_back(eig[i]);\n    \n    // 3. Number of triangles (normalized)\n    long long triangles = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (!adj[i][j]) continue;\n            for (int k = j + 1; k < N; ++k) {\n                if (adj[i][k] && adj[j][k]) triangles++;\n            }\n        }\n    }\n    features.push_back((double)triangles / (N * (N - 1) * (N - 2) / 6.0));\n    \n    // 4. Clustering coefficient approximation\n    double cc = 0;\n    int valid = 0;\n    for (int i = 0; i < N; ++i) {\n        int d = degs[i];\n        if (d < 2) continue;\n        valid++;\n        long long local_tri = 0;\n        vector<int> neighbors;\n        for (int j = 0; j < N; ++j) if (adj[i][j]) neighbors.push_back(j);\n        for (int u = 0; u < (int)neighbors.size(); ++u) {\n            for (int v = u + 1; v < (int)neighbors.size(); ++v) {\n                if (adj[neighbors[u]][neighbors[v]]) local_tri++;\n            }\n        }\n        cc += (double)local_tri / (d * (d - 1) / 2);\n    }\n    features.push_back(valid > 0 ? cc / valid : 0);\n    \n    return features;\n}\n\ndouble feature_dist(const vector<double>& a, const vector<double>& b, double eps) {\n    // Normalize by expected noise scale\n    double dist = 0;\n    // Degrees: first N features, variance scales with N*eps*(1-eps)\n    double deg_scale = max(1.0, sqrt(a.size() * eps * (1 - eps) * 0.5));\n    // Eigenvalues: scale with N\n    double eig_scale = max(1.0, a.size() * 0.5);\n    \n    int N = (a.size() - 2) / 2;\n    for (int i = 0; i < N; ++i) {\n        double d = (a[i] - b[i]) / deg_scale;\n        dist += d * d;\n    }\n    for (int i = N; i < 2 * N; ++i) {\n        double d = (a[i] - b[i]) / eig_scale;\n        dist += d * d;\n    }\n    // Global features\n    dist += (a[2*N] - b[2*N]) * (a[2*N] - b[2*N]) * 10;\n    dist += (a[2*N+1] - b[2*N+1]) * (a[2*N+1] - b[2*N+1]) * 10;\n    \n    return sqrt(dist);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Adaptive N: larger N for higher epsilon\n    int N;\n    if (eps < 0.10) N = 20;\n    else if (eps < 0.20) N = 30;\n    else if (eps < 0.30) N = 50;\n    else if (eps < 0.35) N = 80;\n    else N = 100;\n    \n    if (N > 100) N = 100;\n    if (N < 4) N = 4;\n    \n    // Generate reference graphs with diverse structure\n    vector<vector<bitset<100>>> refs(M, vector<bitset<100>>(N));\n    vector<vector<double>> ref_features(M);\n    vector<string> ref_strs(M);\n    \n    // Use different graph models for diversity\n    for (int i = 0; i < M; ++i) {\n        mt19937 gen(i * 1234567 + 42);\n        \n        // Mix of random graphs and structured graphs\n        if (i < M / 2) {\n            // G(n,p) with varying p\n            double p = 0.3 + 0.4 * (i % 5) / 4.0;  // 0.3 to 0.7\n            bernoulli_distribution d(p);\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (d(gen)) {\n                        refs[i][u].set(v);\n                        refs[i][v].set(u);\n                    }\n                }\n            }\n        } else {\n            // Random regular-like or stochastic block model\n            bernoulli_distribution d(0.5);\n            int blocks = 2 + (i % 4);\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    bool edge = d(gen);\n                    // Bias based on block membership\n                    if ((u % blocks) == (v % blocks)) {\n                        edge = (edge || d(gen));  // higher intra-block density\n                    }\n                    if (edge) {\n                        refs[i][u].set(v);\n                        refs[i][v].set(u);\n                    }\n                }\n            }\n        }\n        \n        ref_features[i] = extract_features(refs[i], N);\n        \n        string s;\n        s.reserve(N * (N - 1) / 2);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s.push_back(refs[i][u][v] ? '1' : '0');\n            }\n        }\n        ref_strs[i] = s;\n    }\n    \n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << ref_strs[i] << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        vector<bitset<100>> h_adj(N);\n        int pos = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (h_str[pos++] == '1') {\n                    h_adj[u].set(v);\n                    h_adj[v].set(u);\n                }\n            }\n        }\n        \n        auto h_feat = extract_features(h_adj, N);\n        \n        // Find best match\n        int best_idx = 0;\n        double best_dist = 1e300;\n        \n        for (int i = 0; i < M; ++i) {\n            double d = feature_dist(ref_features[i], h_feat, eps);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        \n        cout << best_idx << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    const long long INF = (long long)1e12;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Compute criticality: tree edge frequency in shortest path trees\n    vector<double> crit(M, 0.0);\n    const int SAMPLES = 400;\n    \n    for (int iter = 0; iter < SAMPLES; iter++) {\n        int s = rng() % N;\n        vector<long long> dist(N, INF);\n        vector<int> parent(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            for (auto [v, eid] : adj[u]) {\n                int w = edges[eid].w;\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    parent[v] = eid;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (v != s && parent[v] >= 0) {\n                crit[parent[v]] += 1.0;\n            }\n        }\n    }\n    \n    double max_crit = *max_element(crit.begin(), crit.end());\n    if (max_crit > 0) {\n        for (int i = 0; i < M; i++) crit[i] /= max_crit;\n    }\n    \n    // Build vertex-edge mapping for conflict detection\n    vector<vector<int>> vertex_edges(N);\n    for (int i = 0; i < M; i++) {\n        vertex_edges[edges[i].u].push_back(i);\n        vertex_edges[edges[i].v].push_back(i);\n    }\n    \n    // Get adjacent edges\n    auto get_adjacent = [&](int eid) -> vector<int> {\n        unordered_set<int> res;\n        for (int v : {edges[eid].u, edges[eid].v}) {\n            for (int e : vertex_edges[v]) {\n                if (e != eid) res.insert(e);\n            }\n        }\n        return vector<int>(res.begin(), res.end());\n    };\n    \n    // Precompute adjacency list\n    vector<vector<int>> edge_adj(M);\n    for (int i = 0; i < M; i++) {\n        edge_adj[i] = get_adjacent(i);\n    }\n    \n    // Try multiple initial solutions and pick best\n    vector<int> best_assign;\n    double best_score = 1e300;\n    \n    for (int init_try = 0; init_try < 3; init_try++) {\n        vector<int> assign(M, -1);\n        vector<vector<int>> day_edges(D);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_adj(D, 0);\n        \n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        if (init_try == 0) {\n            sort(order.begin(), order.end(), [&](int a, int b) { return crit[a] > crit[b]; });\n        } else if (init_try == 1) {\n            sort(order.begin(), order.end(), [&](int a, int b) { return crit[a] < crit[b]; });\n        } else {\n            shuffle(order.begin(), order.end(), rng);\n        }\n        \n        // Greedy assignment\n        for (int eid : order) {\n            int best_day = -1;\n            double best_cost = 1e300;\n            for (int d = 0; d < D; d++) {\n                if ((int)day_edges[d].size() >= K) continue;\n                double new_sum = day_sum[d] + crit[eid];\n                int new_adj = day_adj[d];\n                for (int other : edge_adj[eid]) {\n                    if (assign[other] == d) new_adj++;\n                }\n                double cost = new_sum * new_sum + new_adj;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_day = d;\n                }\n            }\n            if (best_day == -1) {\n                for (int d = 0; d < D; d++) {\n                    if ((int)day_edges[d].size() < K) {\n                        best_day = d;\n                        break;\n                    }\n                }\n            }\n            assign[eid] = best_day;\n            day_edges[best_day].push_back(eid);\n            day_sum[best_day] += crit[eid];\n            for (int other : edge_adj[eid]) {\n                if (assign[other] == best_day) day_adj[best_day]++;\n            }\n        }\n        \n        // Evaluate this initial solution\n        double score = 0;\n        for (int d = 0; d < D; d++) score += day_sum[d] * day_sum[d];\n        \n        if (score < best_score) {\n            best_score = score;\n            best_assign = assign;\n        }\n    }\n    \n    // Restore best initial solution\n    vector<int> assign = best_assign;\n    vector<vector<int>> day_edges(D);\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_adj(D, 0);\n    \n    for (int i = 0; i < M; i++) {\n        day_edges[assign[i]].push_back(i);\n        day_sum[assign[i]] += crit[i];\n    }\n    for (int d = 0; d < D; d++) {\n        for (int e : day_edges[d]) {\n            for (int other : edge_adj[e]) {\n                if (assign[other] == d) day_adj[d]++;\n            }\n        }\n    }\n    for (int d = 0; d < D; d++) day_adj[d] /= 2; // Each edge counted twice\n    \n    // Positions for O(1) swap\n    vector<int> pos(M, -1);\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < (int)day_edges[d].size(); i++) {\n            pos[day_edges[d][i]] = i;\n        }\n    }\n    \n    // SA with move operations (not just swap)\n    auto start = chrono::steady_clock::now();\n    const double TL = 5.7;\n    \n    double T = 1.0;\n    const double cooling = 0.999995;\n    int iter = 0;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TL) break;\n        \n        iter++;\n        \n        // 70% swaps, 30% moves\n        if (uniform_real_distribution<double>(0, 1)(rng) < 0.7) {\n            // Swap two edges\n            int e1 = rng() % M;\n            int d1 = assign[e1];\n            int e2, d2;\n            int attempts = 0;\n            do {\n                e2 = rng() % M;\n                d2 = assign[e2];\n                attempts++;\n            } while (d1 == d2 && attempts < 5);\n            if (d1 == d2) continue;\n            \n            double s1 = day_sum[d1], s2 = day_sum[d2];\n            double ns1 = s1 - crit[e1] + crit[e2];\n            double ns2 = s2 - crit[e2] + crit[e1];\n            \n            // Quick conflict estimate\n            int nc1 = day_adj[d1], nc2 = day_adj[d2];\n            for (int other : edge_adj[e1]) {\n                if (other == e2) continue;\n                if (assign[other] == d1) nc1--;\n                if (assign[other] == d2) nc1++;\n            }\n            for (int other : edge_adj[e2]) {\n                if (other == e1) continue;\n                if (assign[other] == d2) nc2--;\n                if (assign[other] == d1) nc2++;\n            }\n            \n            double old_obj = s1*s1 + s2*s2 + 0.5*(day_adj[d1] + day_adj[d2]);\n            double new_obj = ns1*ns1 + ns2*ns2 + 0.5*(nc1 + nc2);\n            double delta = new_obj - old_obj;\n            \n            if (delta < 0 || (T > 0.0001 && uniform_real_distribution<double>(0, 1)(rng) < exp(-delta/T))) {\n                // Execute\n                swap(day_edges[d1][pos[e1]], day_edges[d2][pos[e2]]);\n                swap(pos[e1], pos[e2]);\n                swap(assign[e1], assign[e2]);\n                day_sum[d1] = ns1;\n                day_sum[d2] = ns2;\n                day_adj[d1] = nc1;\n                day_adj[d2] = nc2;\n            }\n        } else {\n            // Move single edge to different day\n            int e = rng() % M;\n            int from = assign[e];\n            if (day_edges[from].size() <= 1) continue;\n            \n            int to = rng() % D;\n            if (to == from || (int)day_edges[to].size() >= K) continue;\n            \n            double s_from = day_sum[from], s_to = day_sum[to];\n            double ns_from = s_from - crit[e];\n            double ns_to = s_to + crit[e];\n            \n            double old_obj = s_from*s_from + s_to*s_to;\n            double new_obj = ns_from*ns_from + ns_to*ns_to;\n            double delta = new_obj - old_obj;\n            \n            if (delta < 0 || (T > 0.0001 && uniform_real_distribution<double>(0, 1)(rng) < exp(-delta/T))) {\n                // Execute move\n                int p = pos[e];\n                day_edges[from][p] = day_edges[from].back();\n                pos[day_edges[from][p]] = p;\n                day_edges[from].pop_back();\n                \n                pos[e] = day_edges[to].size();\n                day_edges[to].push_back(e);\n                assign[e] = to;\n                day_sum[from] = ns_from;\n                day_sum[to] = ns_to;\n                // Adj counts updated lazily or ignored for speed\n            }\n        }\n        \n        T *= cooling;\n    }\n    \n    // Fix constraint violations if any\n    for (int d = 0; d < D; d++) {\n        while ((int)day_edges[d].size() > K) {\n            int e = day_edges[d].back();\n            day_edges[d].pop_back();\n            for (int d2 = 0; d2 < D; d2++) {\n                if ((int)day_edges[d2].size() < K) {\n                    day_edges[d2].push_back(e);\n                    assign[e] = d2;\n                    break;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << assign[i] + 1;\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<array<array<int,3>,3>> rotations;\n\nvoid init_rotations() {\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int parity[6] = {1, -1, -1, 1, 1, -1};\n    for (int p=0; p<6; p++) {\n        for (int sx : {1, -1}) {\n            for (int sy : {1, -1}) {\n                for (int sz : {1, -1}) {\n                    if (sx * sy * sz * parity[p] == 1) {\n                        array<array<int,3>,3> mat = {};\n                        mat[0][perms[p][0]] = sx;\n                        mat[1][perms[p][1]] = sy;\n                        mat[2][perms[p][2]] = sz;\n                        rotations.push_back(mat);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvector<array<int,3>> normalize_shape(vector<array<int,3>> cells) {\n    if (cells.empty()) return cells;\n    int minx = 1e9, miny = 1e9, minz = 1e9;\n    for (auto& c : cells) {\n        minx = min(minx, c[0]);\n        miny = min(miny, c[1]);\n        minz = min(minz, c[2]);\n    }\n    for (auto& c : cells) {\n        c[0] -= minx;\n        c[1] -= miny;\n        c[2] -= minz;\n    }\n    vector<vector<array<int,3>>> candidates;\n    for (auto& rot : rotations) {\n        vector<array<int,3>> cur;\n        for (auto& c : cells) {\n            int x = c[0], y = c[1], z = c[2];\n            int nx = rot[0][0]*x + rot[0][1]*y + rot[0][2]*z;\n            int ny = rot[1][0]*x + rot[1][1]*y + rot[1][2]*z;\n            int nz = rot[2][0]*x + rot[2][1]*y + rot[2][2]*z;\n            cur.push_back({nx, ny, nz});\n        }\n        int mix = 1e9, miy = 1e9, miz = 1e9;\n        for (auto& c : cur) {\n            mix = min(mix, c[0]);\n            miy = min(miy, c[1]);\n            miz = min(miz, c[2]);\n        }\n        for (auto& c : cur) {\n            c[0] -= mix;\n            c[1] -= miy;\n            c[2] -= miz;\n        }\n        sort(cur.begin(), cur.end());\n        candidates.push_back(cur);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\nstruct Component {\n    vector<array<int,3>> cells;\n    vector<array<int,3>> shape;\n    int id;\n};\n\nvector<Component> extract_components(const vector<vector<vector<bool>>>& valid) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<Component> comps;\n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid[x][y][z] && !vis[x][y][z]) {\n                    Component comp;\n                    queue<array<int,3>> q;\n                    q.push({x,y,z});\n                    vis[x][y][z] = true;\n                    while (!q.empty()) {\n                        auto cur = q.front(); q.pop();\n                        comp.cells.push_back(cur);\n                        int cx=cur[0], cy=cur[1], cz=cur[2];\n                        for (int dir=0; dir<6; dir++) {\n                            int nx=cx+dx[dir], ny=cy+dy[dir], nz=cz+dz[dir];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && valid[nx][ny][nz] && !vis[nx][ny][nz]) {\n                                vis[nx][ny][nz] = true;\n                                q.push({nx,ny,nz});\n                            }\n                        }\n                    }\n                    comp.shape = normalize_shape(comp.cells);\n                    comps.push_back(comp);\n                }\n            }\n        }\n    }\n    return comps;\n}\n\n// Improved reduction: prioritize removing leaf nodes to preserve connectivity\nvoid reduce_set_improved(vector<vector<vector<bool>>>& cells, \n                const vector<vector<vector<bool>>>& base,\n                const vector<string>& f, const vector<string>& r) {\n    vector<vector<int>> front(D, vector<int>(D, 0));\n    vector<vector<int>> right(D, vector<int>(D, 0));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (base[x][y][z] || cells[x][y][z]) {\n                    front[z][x]++;\n                    right[z][y]++;\n                }\n            }\n        }\n    }\n    \n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    // Compute initial degrees\n    vector<vector<vector<int>>> degree(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (!cells[x][y][z]) continue;\n                for (int dir=0; dir<6; dir++) {\n                    int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                    if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz])\n                        degree[x][y][z]++;\n                }\n            }\n        }\n    }\n    \n    // Priority: degree (lower first), prefer leaves\n    using T = tuple<int, int, int, int>; // degree, x, y, z\n    priority_queue<T, vector<T>, greater<T>> pq;\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (cells[x][y][z] && front[z][x] > 1 && right[z][y] > 1) {\n                    pq.push({degree[x][y][z], x, y, z});\n                }\n            }\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [d, x, y, z] = pq.top(); pq.pop();\n        if (!cells[x][y][z]) continue;\n        if (front[z][x] <= 1 || right[z][y] <= 1) continue;\n        \n        // Remove the cell\n        cells[x][y][z] = false;\n        front[z][x]--;\n        right[z][y]--;\n        \n        // Update neighbors\n        for (int dir=0; dir<6; dir++) {\n            int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz]) {\n                degree[nx][ny][nz]--;\n                if (front[nz][nx] > 1 && right[nz][ny] > 1) {\n                    pq.push({degree[nx][ny][nz], nx, ny, nz});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotations();\n    \n    cin >> D;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i=0; i<2; i++) {\n        for (int j=0; j<D; j++) cin >> f[i][j];\n        for (int j=0; j<D; j++) cin >> r[i][j];\n    }\n    \n    vector<vector<vector<bool>>> P1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> P2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1') P1[x][y][z] = true;\n                if (f[1][z][x] == '1' && r[1][z][y] == '1') P2[x][y][z] = true;\n            }\n        }\n    }\n    \n    vector<vector<vector<bool>>> C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (P1[x][y][z] && P2[x][y][z]) C[x][y][z] = true;\n                else if (P1[x][y][z]) R1[x][y][z] = true;\n                else if (P2[x][y][z]) R2[x][y][z] = true;\n            }\n        }\n    }\n    \n    reduce_set_improved(R1, C, f[0], r[0]);\n    reduce_set_improved(R2, C, f[1], r[1]);\n    \n    auto compsC = extract_components(C);\n    auto compsR1 = extract_components(R1);\n    auto compsR2 = extract_components(R2);\n    \n    int n = 0;\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto idx = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n    \n    for (auto& comp : compsC) {\n        n++;\n        for (auto& c : comp.cells) {\n            b1[idx(c[0], c[1], c[2])] = n;\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    map<vector<array<int,3>>, vector<Component*>> shape_map;\n    for (auto& comp : compsR1) {\n        shape_map[comp.shape].push_back(&comp);\n    }\n    \n    vector<Component*> unmatched_R2;\n    for (auto& comp : compsR2) {\n        auto& vec = shape_map[comp.shape];\n        if (!vec.empty()) {\n            Component* c1 = vec.back();\n            vec.pop_back();\n            n++;\n            for (auto& c : c1->cells) b1[idx(c[0], c[1], c[2])] = n;\n            for (auto& c : comp.cells) b2[idx(c[0], c[1], c[2])] = n;\n        } else {\n            unmatched_R2.push_back(&comp);\n        }\n    }\n    \n    for (auto& [shape, vec] : shape_map) {\n        for (auto* comp : vec) {\n            n++;\n            for (auto& c : comp->cells) b1[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    for (auto* comp : unmatched_R2) {\n        n++;\n        for (auto& c : comp->cells) b2[idx(c[0], c[1], c[2])] = n;\n    }\n    \n    cout << n << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b2[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {int x, y;};\nstruct Edge{int u, v; int w;};\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    void unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a!=b) p[a]=b;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<Point> V(N);\n    for(int i=0;i<N;i++) cin>>V[i].x>>V[i].y;\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++) {\n        int u,v,w;\n        cin>>u>>v>>w;\n        u--; v--;\n        edges[i] = {u,v,w};\n        adj[u].push_back({v,i});\n        adj[v].push_back({u,i});\n    }\n    vector<Point> R(K);\n    for(int i=0;i<K;i++) cin>>R[i].x>>R[i].y;\n    \n    const int COVER_DIST2 = 5000*5000;\n    const long long INF = (1LL<<60);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Precompute shortest paths\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    vector<vector<int>> parent_edge(N, vector<int>(N, -1));\n    \n    for(int s=0; s<N; s++) {\n        distV[s][s] = 0;\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u] = pq.top(); pq.pop();\n            if(d!=distV[s][u]) continue;\n            for(auto [v,eid]: adj[u]){\n                long long nd = d + edges[eid].w;\n                if(nd < distV[s][v]){\n                    distV[s][v] = nd;\n                    parent_edge[s][v] = eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // Precompute resident-vertex data\n    vector<vector<int>> needP(K, vector<int>(N));\n    vector<vector<int>> sortedVertices(K);\n    vector<vector<int>> coverList(N);\n    vector<vector<long long>> distRtoV(K, vector<long long>(N)); // squared distance\n    \n    for(int i=0;i<K;i++){\n        vector<pair<long long,int>> tmp;\n        for(int j=0;j<N;j++){\n            long long dx = (long long)R[i].x - V[j].x;\n            long long dy = (long long)R[i].y - V[j].y;\n            long long d2 = dx*dx + dy*dy;\n            distRtoV[i][j] = d2;\n            needP[i][j] = (int)ceil(sqrt((double)d2) - 1e-9);\n            if(d2 <= COVER_DIST2) {\n                tmp.push_back({d2, j});\n                coverList[j].push_back(i);\n            }\n        }\n        sort(tmp.begin(), tmp.end());\n        for(auto& p: tmp) sortedVertices[i].push_back(p.second);\n    }\n    \n    // Fast evaluation\n    vector<int> maxP_buf(N);\n    vector<char> inSet_buf(N);\n    \n    auto evaluate = [&](const vector<int>& S)->pair<long long, bool>{\n        int sz = (int)S.size();\n        if(sz==0) return {INF, false};\n        \n        fill(maxP_buf.begin(), maxP_buf.end(), 0);\n        fill(inSet_buf.begin(), inSet_buf.end(), 0);\n        for(int v: S) inSet_buf[v] = 1;\n        \n        for(int r=0;r<K;r++){\n            int bestv = -1;\n            for(int v: sortedVertices[r]){\n                if(inSet_buf[v]){\n                    bestv = v;\n                    break;\n                }\n            }\n            if(bestv==-1) return {INF, false};\n            maxP_buf[bestv] = max(maxP_buf[bestv], needP[r][bestv]);\n        }\n        \n        long long fac_cost = 0;\n        for(int v: S) fac_cost += 1LL*maxP_buf[v]*maxP_buf[v];\n        \n        long long tree_cost = 0;\n        if(sz > 1){\n            static vector<long long> min_dist;\n            static vector<char> used;\n            min_dist.assign(sz, INF);\n            used.assign(sz, 0);\n            min_dist[0] = 0;\n            \n            for(int iter=0; iter<sz; iter++){\n                int v = -1;\n                for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_dist[i]<min_dist[v])) v=i;\n                used[v] = 1;\n                tree_cost += min_dist[v];\n                for(int i=0;i<sz;i++) if(!used[i]){\n                    long long d = distV[S[v]][S[i]];\n                    if(d < min_dist[i]) min_dist[i] = d;\n                }\n            }\n        }\n        return {tree_cost + fac_cost, true};\n    };\n    \n    // Greedy initialization\n    auto greedy_init = [&](bool use_ratio)->vector<int>{\n        vector<int> S;\n        vector<char> inS(N,0);\n        S.push_back(0);\n        inS[0] = 1;\n        vector<char> covered(K,0);\n        \n        while(true){\n            bool all = true;\n            for(int i=0;i<K;i++) if(!covered[i]){all=false; break;}\n            if(all) break;\n            \n            int bestv = -1;\n            double best_score = use_ratio ? -1.0 : (double)INF;\n            \n            for(int v=0; v<N; v++) if(!inS[v]){\n                int newly = 0, max_need = 0;\n                for(int r: coverList[v]) if(!covered[r]){\n                    newly++;\n                    max_need = max(max_need, needP[r][v]);\n                }\n                if(newly==0) continue;\n                long long conn = INF;\n                for(int u: S) conn = min(conn, distV[u][v]);\n                long long total_cost = conn + 1LL*max_need*max_need;\n                \n                if(use_ratio){\n                    double score = (double)newly / sqrt((double)total_cost);\n                    if(score > best_score){\n                        best_score = score;\n                        bestv = v;\n                    }\n                } else {\n                    long long cost_eff = total_cost / max(1, newly);\n                    if(cost_eff < best_score){\n                        best_score = cost_eff;\n                        bestv = v;\n                    }\n                }\n            }\n            \n            if(bestv==-1) break;\n            inS[bestv] = 1;\n            S.push_back(bestv);\n            for(int r: coverList[bestv]) covered[r] = 1;\n        }\n        return S;\n    };\n    \n    // Simulated Annealing with adaptive moves\n    auto simulated_annealing = [&](vector<int> S, int iter_limit)->vector<int>{\n        vector<char> inS(N, 0);\n        for(int v: S) inS[v] = 1;\n        \n        auto [best_cost, ok] = evaluate(S);\n        if(!ok) return S;\n        vector<int> bestS = S;\n        long long cur_cost = best_cost;\n        \n        double T = (double)cur_cost * 0.25;\n        const double T_min = 0.1;\n        const double alpha = 0.9985;\n        \n        // Track \"promising\" vertices for smarter sampling\n        vector<int> recent_adds;\n        \n        for(int iter=0; iter<iter_limit && T > T_min; iter++){\n            vector<int> newS;\n            bool valid = false;\n            \n            // Adaptive: early iterations favor add, later favor swap/remove\n            int op;\n            double progress = (double)iter / iter_limit;\n            double r = uniform_real_distribution<double>(0,1)(rng);\n            \n            if(r < 0.3 - 0.1*progress && S.size() < N) op = 0; // add\n            else if(r < 0.6 && S.size() > 1) op = 1; // remove  \n            else op = 2; // swap\n            \n            if(op == 0 && S.size() < N){\n                // Add: prefer vertices that cover many residents cheaply\n                vector<int> candidates;\n                for(int v=0;v<N;v++) if(!inS[v]) candidates.push_back(v);\n                if(!candidates.empty()){\n                    // Sample 5 and pick best by quick heuristic\n                    int best_cand = candidates[rng()%candidates.size()];\n                    long long best_h = INF;\n                    for(int trial=0; trial<5 && trial<(int)candidates.size(); trial++){\n                        int v = candidates[rng()%candidates.size()];\n                        long long conn = INF;\n                        for(int u: S) conn = min(conn, distV[u][v]);\n                        if(conn < best_h){\n                            best_h = conn;\n                            best_cand = v;\n                        }\n                    }\n                    newS = S;\n                    newS.push_back(best_cand);\n                    valid = true;\n                }\n            } else if(op == 1 && S.size() > 1){\n                int idx = uniform_int_distribution<int>(1, (int)S.size()-1)(rng);\n                newS = S;\n                newS.erase(newS.begin() + idx);\n                valid = true;\n            } else if(S.size() > 1 && S.size() < N){\n                // Smart swap: try to replace a vertex with one that improves coverage\n                int idx = uniform_int_distribution<int>(1, (int)S.size()-1)(rng);\n                int v_out = S[idx];\n                \n                // Find a vertex not in S that might be better\n                vector<int> not_in_S;\n                for(int v=0;v<N;v++) if(!inS[v]) not_in_S.push_back(v);\n                if(!not_in_S.empty()){\n                    int v_in = not_in_S[rng()%not_in_S.size()];\n                    newS = S;\n                    newS.erase(newS.begin() + idx);\n                    newS.push_back(v_in);\n                    valid = true;\n                }\n            }\n            \n            if(!valid) continue;\n            \n            auto [new_cost, feasible] = evaluate(newS);\n            if(!feasible) continue;\n            \n            long long delta = new_cost - cur_cost;\n            bool accept = delta < 0;\n            if(!accept && T > 0.1){\n                accept = exp(-(double)delta / T) > uniform_real_distribution<double>(0,1)(rng);\n            }\n            \n            if(accept){\n                // Update inS\n                fill(inS.begin(), inS.end(), 0);\n                for(int v: newS) inS[v] = 1;\n                S = newS;\n                cur_cost = new_cost;\n                if(cur_cost < best_cost){\n                    best_cost = cur_cost;\n                    bestS = S;\n                }\n            }\n            T *= alpha;\n        }\n        return bestS;\n    };\n    \n    // Intensive local search\n    auto local_search = [&](vector<int> S)->vector<int>{\n        auto [cost, _] = evaluate(S);\n        long long best_cost = cost;\n        vector<int> bestS = S;\n        bool improved = true;\n        int rounds = 0;\n        \n        while(improved && rounds < 150){\n            improved = false;\n            rounds++;\n            vector<char> inS(N, 0);\n            for(int v: S) inS[v] = 1;\n            \n            // Remove moves\n            for(size_t i=1;i<S.size() && !improved;i++){\n                vector<int> testS = S;\n                testS.erase(testS.begin()+i);\n                auto [c, ok] = evaluate(testS);\n                if(ok && c < best_cost){\n                    best_cost = c;\n                    bestS = testS;\n                    improved = true;\n                    S = testS;\n                    break;\n                }\n            }\n            if(improved) continue;\n            \n            // Swap moves - try all combinations\n            vector<int> outside;\n            for(int v=0;v<N;v++) if(!inS[v]) outside.push_back(v);\n            shuffle(outside.begin(), outside.end(), rng);\n            \n            for(size_t i=1;i<S.size() && !improved;i++){\n                for(int v_in: outside){\n                    vector<int> testS = S;\n                    testS.erase(testS.begin()+i);\n                    testS.push_back(v_in);\n                    auto [c, ok] = evaluate(testS);\n                    if(ok && c < best_cost){\n                        best_cost = c;\n                        bestS = testS;\n                        improved = true;\n                        S = testS;\n                        break;\n                    }\n                }\n            }\n        }\n        return bestS;\n    };\n    \n    // Run optimization\n    vector<int> S1 = greedy_init(true);\n    vector<int> S2 = greedy_init(false);\n    \n    S1 = simulated_annealing(S1, 6000);\n    S2 = simulated_annealing(S2, 6000);\n    \n    auto [c1, _1] = evaluate(S1);\n    auto [c2, _2] = evaluate(S2);\n    vector<int> S = (c1 < c2) ? S1 : S2;\n    \n    S = local_search(S);\n    \n    // Build output\n    int sz = S.size();\n    vector<int> P(N, 0);\n    vector<char> inS(N, 0);\n    for(int v: S) inS[v] = 1;\n    \n    for(int r=0;r<K;r++){\n        for(int v: sortedVertices[r]){\n            if(inS[v]){\n                P[v] = max(P[v], needP[r][v]);\n                break;\n            }\n        }\n    }\n    \n    vector<int> B(M, 0);\n    if(sz > 1){\n        vector<long long> min_edge(sz, INF);\n        vector<char> used(sz, 0);\n        vector<int> parent_idx(sz, -1);\n        min_edge[0] = 0;\n        \n        for(int iter=0; iter<sz; iter++){\n            int v = -1;\n            for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_edge[i]<min_edge[v])) v=i;\n            used[v] = 1;\n            for(int i=0;i<sz;i++) if(!used[i]){\n                long long d = distV[S[v]][S[i]];\n                if(d < min_edge[i]){\n                    min_edge[i] = d;\n                    parent_idx[i] = v;\n                }\n            }\n        }\n        \n        vector<char> edge_active(M, 0);\n        for(int i=1;i<sz;i++){\n            int u = S[parent_idx[i]];\n            int v = S[i];\n            int cur = v;\n            while(cur != u){\n                int e = parent_edge[u][cur];\n                if(e==-1) break;\n                edge_active[e] = 1;\n                int pu = edges[e].u == cur ? edges[e].v : edges[e].u;\n                cur = pu;\n            }\n        }\n        \n        vector<pair<int,int>> active_edges;\n        for(int i=0;i<M;i++) if(edge_active[i]) active_edges.push_back({edges[i].w, i});\n        sort(active_edges.begin(), active_edges.end());\n        \n        DSU dsu(N);\n        for(auto& [w, e]: active_edges){\n            int u=edges[e].u, v=edges[e].v;\n            if(dsu.find(u)!=dsu.find(v)){\n                dsu.unite(u,v);\n                B[e]=1;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int i=0;i<M;i++){\n        if(i) cout << ' ';\n        cout << B[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\n// Hungarian algorithm for minimization, n workers, m jobs (n <= m)\n// Returns pair(min_cost, assignment) where assignment[i] = job assigned to worker i\npair<int, vector<int>> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i = 1; i <= n; ++i) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= m; ++j) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j = 0; j <= m; ++j) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        \n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> assignment(n);\n    for (int j = 1; j <= m; ++j) {\n        if (p[j] != 0) {\n            assignment[p[j]-1] = j-1;\n        }\n    }\n    return {-v[0], assignment};\n}\n\nint calc_dist(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    return max({abs(dx), abs(dy), abs(dx - dy)});\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    const int BALLS = N * (N + 1) / 2;\n    \n    vector<vector<int>> init_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> init_pos(BALLS);\n    \n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v; \n            cin >> v;\n            init_grid[x][y] = v;\n            init_pos[v] = {x, y};\n        }\n    }\n    \n    // Determine optimal target assignment using Hungarian per row\n    vector<vector<int>> target_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> target_pos(BALLS); // where each value should go\n    \n    for (int x = 0; x < N; ++x) {\n        int m = x + 1;\n        int start = x * (x + 1) / 2;\n        \n        // Cost matrix: cost[i][j] = distance from initial pos of value (start+i) to cell (x,j)\n        vector<vector<int>> cost(m, vector<int>(m));\n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            auto [vx, vy] = init_pos[v];\n            for (int j = 0; j < m; ++j) {\n                cost[i][j] = calc_dist(vx, vy, x, j);\n            }\n        }\n        \n        auto [min_cost, assignment] = hungarian(cost);\n        // assignment[i] = column j where value (start+i) should go\n        \n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            int y = assignment[i];\n            target_grid[x][y] = v;\n            target_pos[v] = {x, y};\n        }\n    }\n    \n    // Routing phase: bottom-up greedy swapping\n    vector<vector<int>> cur_grid = init_grid;\n    vector<pair<int,int>> cur_pos = init_pos;\n    vector<array<int,4>> ops;\n    \n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = x; y >= 0; --y) {\n            int target_val = target_grid[x][y];\n            auto [cx, cy] = cur_pos[target_val];\n            \n            while (cx != x || cy != y) {\n                int nx, ny;\n                if (cx < x) {\n                    if (cy > y) {\n                        nx = cx; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx + 1; ny = cy + 1;\n                    } else {\n                        nx = cx + 1; ny = cy;\n                    }\n                } else if (cx > x) {\n                    if (cy > y) {\n                        nx = cx - 1; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx - 1; ny = cy;\n                    } else {\n                        nx = cx - 1; ny = cy;\n                    }\n                } else {\n                    if (cy < y) {\n                        nx = cx; ny = cy + 1;\n                    } else {\n                        nx = cx; ny = cy - 1;\n                    }\n                }\n                \n                int v1 = cur_grid[cx][cy];\n                int v2 = cur_grid[nx][ny];\n                \n                swap(cur_grid[cx][cy], cur_grid[nx][ny]);\n                cur_pos[v1] = {nx, ny};\n                cur_pos[v2] = {cx, cy};\n                ops.push_back({cx, cy, nx, ny});\n                \n                cx = nx; cy = ny;\n            }\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto &op : ops) {\n        cout << op[0] << ' ' << op[1] << ' ' << op[2] << ' ' << op[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    \n    const int si = 0, sj = (D - 1) / 2;\n    const int M = D * D - 1 - N;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // BFS to compute distances from entrance (for heuristic)\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (dist[ni][nj] != -1) continue;\n            dist[ni][nj] = dist[i][j] + 1;\n            q.push({ni, nj});\n        }\n    }\n    \n    // Collect valid cells and sort by distance descending\n    // (far cells first, close cells last)\n    vector<pair<int, int>> cells;\n    cells.reserve(M);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == si && j == sj) continue;\n            if (obstacle[i][j]) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](const auto &a, const auto &b) {\n        return dist[a.first][a.second] > dist[b.first][b.second];\n    });\n    \n    // Map from cell to its index in sorted order\n    map<pair<int, int>, int> cell_to_idx;\n    for (int i = 0; i < cells.size(); i++) {\n        cell_to_idx[cells[i]] = i;\n    }\n    \n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    vector<vector<int>> value_at(D, vector<int>(D, -1));\n    \n    // Helper: check if removing cell (ri, rj) keeps all empty cells connected to entrance\n    auto is_safe = [&](int ri, int rj) -> bool {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        vis[si][sj] = true;\n        qq.push({si, sj});\n        int reachable_count = 1;\n        \n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (ni == ri && nj == rj) continue; // Pretend this cell is blocked\n                if (vis[ni][nj]) continue;\n                vis[ni][nj] = true;\n                reachable_count++;\n                qq.push({ni, nj});\n            }\n        }\n        \n        // Count total empty cells (excluding the one we're testing)\n        int total_empty = 1; // entrance\n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == si && j == sj) continue;\n                if (obstacle[i][j]) continue;\n                if (occupied[i][j]) continue;\n                if (i == ri && j == rj) continue;\n                total_empty++;\n            }\n        }\n        \n        return reachable_count == total_empty;\n    };\n    \n    // Placement phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        \n        // Target: small t should be near entrance (end of cells list)\n        // Large t should be far from entrance (beginning of cells list)\n        int target_idx = M - 1 - t;\n        \n        // Compute current reachable cells\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        reachable[si][sj] = true;\n        qq.push({si, sj});\n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (reachable[ni][nj]) continue;\n                reachable[ni][nj] = true;\n                qq.push({ni, nj});\n            }\n        }\n        \n        pair<int, int> chosen = {-1, -1};\n        int best_diff = M + 1;\n        \n        // Find safe reachable cell closest to target position\n        for (int idx = 0; idx < M; idx++) {\n            auto [i, j] = cells[idx];\n            if (occupied[i][j]) continue;\n            if (!reachable[i][j]) continue;\n            \n            // Check safety: removing this cell should not disconnect the graph\n            if (!is_safe(i, j)) continue;\n            \n            int diff = abs(idx - target_idx);\n            if (diff < best_diff) {\n                best_diff = diff;\n                chosen = {i, j};\n            }\n        }\n        \n        // If no safe cell found, try without safety check (should not happen with valid input)\n        if (chosen.first == -1) {\n            for (int idx = 0; idx < M; idx++) {\n                auto [i, j] = cells[idx];\n                if (occupied[i][j]) continue;\n                if (!reachable[i][j]) continue;\n                int diff = abs(idx - target_idx);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    chosen = {i, j};\n                }\n            }\n        }\n        \n        // Last resort: any reachable cell\n        if (chosen.first == -1) {\n            for (auto [i, j] : cells) {\n                if (!occupied[i][j] && reachable[i][j]) {\n                    chosen = {i, j};\n                    break;\n                }\n            }\n        }\n        \n        occupied[chosen.first][chosen.second] = true;\n        value_at[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << \"\\n\";\n        cout.flush();\n    }\n    \n    // Retrieval phase: always take smallest available value\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[si][sj] = true;\n    \n    using P = pair<int, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    \n    // Helper to add neighbors of (i,j) to PQ\n    auto add_neighbors = [&](int i, int j) {\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (is_empty[ni][nj]) continue;\n            if (value_at[ni][nj] == -1) continue; // No container\n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    };\n    \n    // Initialize with cells adjacent to entrance\n    add_neighbors(si, sj);\n    \n    vector<pair<int, int>> retrieval;\n    retrieval.reserve(M);\n    \n    while ((int)retrieval.size() < M) {\n        if (pq.empty()) {\n            // This should not happen if placement was correct\n            break;\n        }\n        auto [val, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (is_empty[i][j]) continue; // Already retrieved\n        \n        is_empty[i][j] = true;\n        retrieval.push_back(pos);\n        add_neighbors(i, j);\n    }\n    \n    for (auto [i, j] : retrieval) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> inp(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> inp[i][j];\n\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    auto inside = [&](int i, int j) {\n        return 0 <= i && i < n && 0 <= j && j < n;\n    };\n\n    // Build adjacency graph from original map\n    vector<set<int>> orig_adj(m + 1);\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = inp[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                int c2 = (inside(ni, nj)) ? inp[ni][nj] : 0;\n                if (c1 != c2) {\n                    orig_adj[c1].insert(c2);\n                    orig_adj[c2].insert(c1);\n                }\n            }\n        }\n    }\n\n    // Working grid\n    vector<vector<int>> grid(n, vector<int>(n, -1));\n    vector<vector<pair<int,int>>> cells(m + 1);\n    \n    auto is_boundary = [&](int i, int j) {\n        return i == 0 || i == n-1 || j == 0 || j == n-1;\n    };\n\n    // Strict validation: can we place color c at (i,j)?\n    auto valid_placement = [&](int c, int i, int j, int target = -1) -> bool {\n        if (!inside(i, j) || grid[i][j] != -1) return false;\n        \n        // Non-0-adjacent colors: strictly no boundary\n        if (!orig_adj[c].count(0) && is_boundary(i, j)) return false;\n        \n        for (int d = 0; d < 4; ++d) {\n            int ni = i + di[d], nj = j + dj[d];\n            int w = inside(ni, nj) ? grid[ni][nj] : 0;\n            if (w == -1 || w == c) continue;\n            if (w == target) continue;\n            if (!orig_adj[c].count(w)) return false;\n        }\n        return true;\n    };\n\n    // Separate colors\n    vector<int> boundary_colors, interior_colors;\n    for (int c = 1; c <= m; ++c) {\n        if (orig_adj[c].count(0)) boundary_colors.push_back(c);\n        else interior_colors.push_back(c);\n    }\n\n    // Place interior colors (strictly interior)\n    for (int col : interior_colors) {\n        bool placed = false;\n        for (int i = 1; i < n-1 && !placed; ++i) {\n            for (int j = 1; j < n-1 && !placed; ++j) {\n                if (valid_placement(col, i, j)) {\n                    grid[i][j] = col;\n                    cells[col].push_back({i, j});\n                    placed = true;\n                }\n            }\n        }\n        // Emergency: any interior cell\n        if (!placed) {\n            for (int i = 1; i < n-1 && !placed; ++i) {\n                for (int j = 1; j < n-1 && !placed; ++j) {\n                    if (grid[i][j] == -1) {\n                        grid[i][j] = col;\n                        cells[col].push_back({i, j});\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Place boundary colors\n    vector<pair<int,int>> bnd;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            if (is_boundary(i, j)) bnd.push_back({i, j});\n    \n    size_t idx = 0;\n    for (int col : boundary_colors) {\n        while (idx < bnd.size()) {\n            auto [i, j] = bnd[idx++];\n            if (grid[i][j] == -1 && valid_placement(col, i, j)) {\n                grid[i][j] = col;\n                cells[col].push_back({i, j});\n                break;\n            }\n        }\n    }\n\n    // Emergency placement for any remaining\n    for (int c = 1; c <= m; ++c) {\n        if (cells[c].empty()) {\n            bool on_bnd = orig_adj[c].count(0);\n            for (int i = 0; i < n; ++i) {\n                for (int j = 0; j < n; ++j) {\n                    if (grid[i][j] != -1) continue;\n                    if (!on_bnd && is_boundary(i, j)) continue;\n                    // Check placement validity\n                    bool ok = true;\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + di[d], nj = j + dj[d];\n                        int w = inside(ni, nj) ? grid[ni][nj] : 0;\n                        if (w != -1 && w != c && !orig_adj[c].count(w)) {\n                            ok = false; break;\n                        }\n                    }\n                    if (!ok) continue;\n                    grid[i][j] = c;\n                    cells[c].push_back({i, j});\n                    i = n; j = n;\n                }\n            }\n        }\n    }\n\n    // Check adjacency\n    auto check_adj = [&](int c1, int c2) {\n        for (auto& [x, y] : cells[c1]) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + di[d], ny = y + dj[d];\n                int w = inside(nx, ny) ? grid[nx][ny] : 0;\n                if (w == c2) return true;\n            }\n        }\n        return false;\n    };\n\n    // Satisfy required adjacencies with strict validation\n    for (int u = 1; u <= m; ++u) {\n        for (int v : orig_adj[u]) {\n            if (v < u) continue;\n            \n            for (int attempt = 0; attempt < 1000 && !check_adj(u, v); ++attempt) {\n                // Find best expansion cell\n                int best = 1e9;\n                pair<int,int> best_cell = {-1,-1};\n                \n                for (auto& [x,y] : cells[u]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int nx = x+di[d], ny = y+dj[d];\n                        if (!valid_placement(u, nx, ny, v)) continue;\n                        \n                        int dist = 0;\n                        for (auto& [vx,vy] : cells[v])\n                            dist = max(dist, abs(nx-vx) + abs(ny-vy));\n                        if (dist < best) {\n                            best = dist;\n                            best_cell = {nx, ny};\n                        }\n                    }\n                }\n                \n                if (best_cell.first == -1) break;\n                \n                grid[best_cell.first][best_cell.second] = u;\n                cells[u].push_back(best_cell);\n            }\n        }\n    }\n\n    // Verify solution\n    bool valid = true;\n    // Check all colors are placed\n    for (int c = 1; c <= m; ++c) {\n        if (cells[c].empty()) valid = false;\n    }\n    // Check adjacencies match\n    for (int c1 = 0; c1 <= m && valid; ++c1) {\n        for (int c2 = c1+1; c2 <= m && valid; ++c2) {\n            bool should = orig_adj[c1].count(c2);\n            bool actual = check_adj(c1, c2);\n            if (should != actual) valid = false;\n        }\n    }\n    // Check connectivity\n    auto check_conn = [&](int c) {\n        if (cells[c].empty()) return false;\n        queue<pair<int,int>> q;\n        vector<vector<bool>> vis(n, vector<bool>(n));\n        for (auto& [x,y] : cells[c]) vis[x][y] = true;\n        q.push(cells[c][0]);\n        int cnt = 1;\n        while (!q.empty()) {\n            auto [x,y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx=x+di[d], ny=y+dj[d];\n                if (inside(nx,ny) && grid[nx][ny]==c && !vis[nx][ny]) {\n                    vis[nx][ny]=true; q.push({nx,ny}); cnt++;\n                }\n            }\n        }\n        return cnt == (int)cells[c].size();\n    };\n    for (int c = 0; c <= m && valid; ++c) {\n        if (!check_conn(c)) valid = false;\n    }\n\n    // Output\n    if (valid) {\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (j) cout << ' ';\n                cout << max(0, grid[i][j]);\n            }\n            cout << '\\n';\n        }\n    } else {\n        // Fallback: output original map (always valid, score 1)\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (j) cout << ' ';\n                cout << inp[i][j];\n            }\n            cout << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    vector<double> w(N, 1.0);\n    \n    // Use all queries to estimate relative weights via pairwise comparisons\n    mt19937 rng(12345);\n    \n    for (int q = 0; q < Q; q++) {\n        // Pick two different random items\n        int a = rng() % N;\n        int b = rng() % N;\n        while (a == b) b = rng() % N;\n        \n        cout << \"1 1 \" << a << \" \" << b << endl;\n        char res;\n        cin >> res;\n        \n        if (res == '>') {\n            w[a] += 0.1;\n            w[b] -= 0.1;\n        } else if (res == '<') {\n            w[a] -= 0.1;\n            w[b] += 0.1;\n        }\n    }\n    \n    // Normalize weights to be positive\n    double min_w = w[0];\n    for (int i = 1; i < N; i++) min_w = min(min_w, w[i]);\n    for (int i = 0; i < N; i++) w[i] = w[i] - min_w + 1.0;\n    \n    // LPT (Longest Processing Time) greedy partition\n    vector<int> belong(N, 0);\n    vector<double> sum(D, 0.0);\n    \n    // Create sorted order by weight\n    vector<pair<double, int>> ord;\n    for (int i = 0; i < N; i++) ord.push_back({w[i], i});\n    sort(ord.rbegin(), ord.rend());\n    \n    // Assign heaviest items to lightest groups\n    for (auto& p : ord) {\n        double weight = p.first;\n        int idx = p.second;\n        \n        int best_g = 0;\n        double min_sum = sum[0];\n        for (int g = 1; g < D; g++) {\n            if (sum[g] < min_sum) {\n                min_sum = sum[g];\n                best_g = g;\n            }\n        }\n        belong[idx] = best_g;\n        sum[best_g] += weight;\n    }\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << belong[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> st(m);\n    vector<int> pos(n + 1);\n    \n    for (int i = 0; i < m; ++i) {\n        int h = n / m;\n        for (int j = 0; j < h; ++j) {\n            int x; \n            cin >> x;\n            st[i].push_back(x);\n            pos[x] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    for (int target = 1; target <= n; ++target) {\n        int s = pos[target];\n        \n        // Find position of target\n        int idx = -1;\n        for (int i = 0; i < (int)st[s].size(); ++i) {\n            if (st[s][i] == target) {\n                idx = i;\n                break;\n            }\n        }\n        \n        // Move boxes above target until it becomes the top\n        while (idx < (int)st[s].size() - 1) {\n            int w = st[s].back(); // top of the suffix to be moved\n            \n            int best_d = -1;\n            \n            // Priority 1: Empty stack (ideal - creates no blocking)\n            for (int d = 0; d < m; ++d) {\n                if (d == s) continue;\n                if (st[d].empty()) {\n                    best_d = d;\n                    break;\n                }\n            }\n            \n            // Priority 2: Among all non-empty stacks, choose one with MAXIMUM top\n            // Rationale: We want to block the box that is least urgent (largest value)\n            // This applies to both valid (t > w) and invalid (t < w) cases\n            if (best_d == -1) {\n                int max_top = -1;\n                for (int d = 0; d < m; ++d) {\n                    if (d == s) continue;\n                    int top_d = st[d].back();\n                    if (top_d > max_top) {\n                        max_top = top_d;\n                        best_d = d;\n                    }\n                }\n            }\n            \n            // The box immediately above target (bottom of moved suffix)\n            int u = st[s][idx + 1];\n            \n            // Perform move: extract suffix starting at idx+1\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            st[s].resize(idx + 1);\n            \n            for (int x : seg) pos[x] = best_d;\n            st[best_d].insert(st[best_d].end(), seg.begin(), seg.end());\n            \n            ops.emplace_back(u, best_d + 1); // convert to 1-indexed\n        }\n        \n        // Remove target (Operation 2)\n        st[s].pop_back();\n        ops.emplace_back(target, 0);\n    }\n    \n    for (auto [v, i] : ops) {\n        cout << v << ' ' << i << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n    \n    auto id = [&](int i, int j){ return i*N + j; };\n    const int V = N*N;\n    const int root = 0;\n    \n    // Build adjacency list\n    vector<vector<pair<int,char>>> adj(V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                bool ok = false;\n                if (dir == 0) ok = h[ni][j] == '0';\n                else if (dir == 1) ok = h[i][j] == '0';\n                else if (dir == 2) ok = v[i][nj] == '0';\n                else ok = v[i][j] == '0';\n                if (ok) adj[id(i,j)].push_back({id(ni,nj), dc[dir]});\n            }\n        }\n    }\n    \n    // Build tree with priority queue (high d first) to keep high-d nodes shallow\n    vector<int> parent(V, -1);\n    vector<vector<int>> children(V);\n    {\n        priority_queue<pair<int,int>> pq;\n        pq.push({d[0][0], root});\n        parent[root] = -1;\n        while (!pq.empty()) {\n            auto [du, u] = pq.top(); pq.pop();\n            for (auto [w, _] : adj[u]) {\n                if (parent[w] == -1 && w != root) {\n                    parent[w] = u;\n                    children[u].push_back(w);\n                    int wi = w / N, wj = w % N;\n                    pq.push({d[wi][wj], w});\n                }\n            }\n        }\n    }\n    \n    // Bottom-up order\n    vector<int> order;\n    order.reserve(V);\n    {\n        queue<int> q;\n        q.push(root);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            order.push_back(u);\n            for (int w : children[u]) q.push(w);\n        }\n    }\n    reverse(order.begin(), order.end()); // leaves first\n    \n    vector<double> dval(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            dval[id(i,j)] = sqrt((double)d[i][j]);\n    \n    const long long LIM = 100000LL;\n    const int B = 3;\n    vector<long long> k(V, 1);\n    \n    // Binary search on multiplier c\n    double lo = 0, hi = 1e6;\n    for (int it = 0; it < 60; ++it) {\n        double mid = (lo + hi) * 0.5;\n        long long L = 0;\n        for (int u : order) {\n            if (u == root) continue;\n            long long sumc = 0;\n            for (int w : children[u]) sumc += k[w];\n            long long constraint = (sumc + B - 1) / B;\n            long long target = (long long)(mid * dval[u]);\n            if (target < 1) target = 1;\n            long long ku = max(constraint, target);\n            k[u] = ku;\n            L += 2 * ku;\n            if (L > LIM) break;\n        }\n        if (L <= LIM) lo = mid;\n        else hi = mid;\n    }\n    \n    // Final evaluation with lo\n    long long Ltot = 0;\n    for (int u : order) {\n        if (u == root) continue;\n        long long sumc = 0;\n        for (int w : children[u]) sumc += k[w];\n        long long constraint = (sumc + B - 1) / B;\n        long long target = (long long)(lo * dval[u]);\n        if (target < 1) target = 1;\n        long long ku = max(constraint, target);\n        k[u] = ku;\n        Ltot += 2 * ku;\n    }\n    \n    // Build schedule (top-down)\n    vector<vector<vector<int>>> sched(V);\n    vector<int> bfs = order;\n    reverse(bfs.begin(), bfs.end()); // root first\n    \n    for (int u : bfs) {\n        if (children[u].empty()) {\n            sched[u].assign((size_t)k[u], {});\n            continue;\n        }\n        vector<int> exc;\n        exc.reserve(10000);\n        for (int w : children[u]) {\n            for (long long i = 0; i < k[w]; ++i) exc.push_back(w);\n        }\n        sched[u].assign((size_t)k[u], {});\n        for (size_t i = 0; i < exc.size(); ++i) {\n            int slot = (int)(i % k[u]);\n            sched[u][slot].push_back(exc[i]);\n        }\n    }\n    \n    // Generate walk\n    string ans;\n    ans.reserve((size_t)LIM);\n    vector<size_t> cur(V, 0);\n    \n    auto getc = [&](int u, int v)->char {\n        for (auto [to, c] : adj[u]) if (to == v) return c;\n        return '?';\n    };\n    \n    function<void(int)> visit = [&](int u) {\n        size_t slot = cur[u]++;\n        for (int w : sched[u][slot]) {\n            ans.push_back(getc(u, w));\n            visit(w);\n            ans.push_back(getc(w, u));\n        }\n    };\n    \n    for (size_t slot = 0; slot < (size_t)k[root]; ++slot) {\n        for (int w : sched[root][slot]) {\n            ans.push_back(getc(root, w));\n            visit(w);\n            ans.push_back(getc(w, root));\n        }\n    }\n    \n    if ((long long)ans.size() > LIM) ans.resize((size_t)LIM);\n    cout << ans << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint calc_overlap(const string& a, const string& b) {\n    int max_k = min((int)a.length(), (int)b.length());\n    for (int k = max_k; k > 0; --k) {\n        if (a.compare(a.length() - k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nbool contains_all(const string& text, const vector<string>& targets) {\n    for (const auto& t : targets) {\n        if (text.find(t) == string::npos) return false;\n    }\n    return true;\n}\n\nstring greedy_scs(vector<string>& strs, mt19937& rng) {\n    if (strs.empty()) return \"\";\n    if (strs.size() == 1) return strs[0];\n    \n    vector<string> pool = strs;\n    shuffle(pool.begin(), pool.end(), rng);\n    \n    while (pool.size() > 1) {\n        int m = pool.size();\n        int best_ov = -1, best_i = -1, best_j = -1;\n        \n        for (int i = 0; i < m; ++i) {\n            for (int j = i + 1; j < m; ++j) {\n                int ov1 = calc_overlap(pool[i], pool[j]);\n                int ov2 = calc_overlap(pool[j], pool[i]);\n                if (ov1 > best_ov) {\n                    best_ov = ov1; best_i = i; best_j = j;\n                }\n                if (ov2 > best_ov) {\n                    best_ov = ov2; best_i = j; best_j = i;\n                }\n            }\n        }\n        \n        string merged = pool[best_i] + pool[best_j].substr(best_ov);\n        if (best_i > best_j) swap(best_i, best_j);\n        pool.erase(pool.begin() + best_j);\n        pool.erase(pool.begin() + best_i);\n        pool.push_back(std::move(merged));\n    }\n    \n    return pool[0];\n}\n\n// Remove redundant characters from superstring\nstring shorten(const string& s, const vector<string>& targets, mt19937& rng) {\n    string best = s;\n    vector<int> indices(best.size());\n    iota(indices.begin(), indices.end(), 0);\n    shuffle(indices.begin(), indices.end(), rng);\n    \n    for (int idx : indices) {\n        if (best.size() <= 5) break;\n        string candidate = best.substr(0, idx) + best.substr(idx + 1);\n        if (contains_all(candidate, targets)) {\n            best = candidate;\n        }\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    int si, sj;\n    cin >> N >> M >> si >> sj;\n    \n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n    \n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) cin >> targets[i];\n    \n    // Remove targets that are substrings of others\n    vector<string> filtered;\n    for (int i = 0; i < M; ++i) {\n        bool is_sub = false;\n        for (int j = 0; j < M; ++j) {\n            if (i != j && targets[j].find(targets[i]) != string::npos) {\n                is_sub = true;\n                break;\n            }\n        }\n        if (!is_sub) filtered.push_back(targets[i]);\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    \n    string best_U;\n    int best_len = INT_MAX;\n    \n    // Multiple attempts with local search\n    for (int iter = 0; iter < 20; ++iter) {\n        string U = greedy_scs(filtered, rng);\n        U = shorten(U, targets, rng);\n        \n        if ((int)U.size() < best_len) {\n            best_len = U.size();\n            best_U = U;\n        }\n    }\n    \n    const string& U = best_U;\n    int L = U.size();\n    \n    // Positions for each character\n    vector<vector<int>> pos(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            pos[grid[i][j] - 'A'].push_back(i * N + j);\n    \n    const int V = N * N;\n    vector<vector<int>> dist(V, vector<int>(V));\n    for (int i = 0; i < V; ++i) {\n        int i1 = i / N, j1 = i % N;\n        for (int j = i; j < V; ++j) {\n            int i2 = j / N, j2 = j % N;\n            int d = abs(i1 - i2) + abs(j1 - j2);\n            dist[i][j] = dist[j][i] = d;\n        }\n    }\n    \n    const int INF = 1e9;\n    vector<int> dp_prev(V, INF), dp_curr(V, INF);\n    vector<vector<short>> parent(L, vector<short>(V, -1));\n    \n    int first_c = U[0] - 'A';\n    int start = si * N + sj;\n    for (int v : pos[first_c])\n        dp_curr[v] = dist[start][v] + 1;\n    \n    for (int step = 1; step < L; ++step) {\n        dp_prev.swap(dp_curr);\n        fill(dp_curr.begin(), dp_curr.end(), INF);\n        \n        int curr_c = U[step] - 'A';\n        int prev_c = U[step - 1] - 'A';\n        \n        for (int v : pos[curr_c]) {\n            int best = INF;\n            short best_u = -1;\n            for (int u : pos[prev_c]) {\n                int c = dp_prev[u] + dist[u][v] + 1;\n                if (c < best) {\n                    best = c;\n                    best_u = u;\n                }\n            }\n            dp_curr[v] = best;\n            parent[step][v] = best_u;\n        }\n    }\n    \n    int best_v = -1, best_cost = INF;\n    for (int v = 0; v < V; ++v) {\n        if (dp_curr[v] < best_cost) {\n            best_cost = dp_curr[v];\n            best_v = v;\n        }\n    }\n    \n    vector<pair<int, int>> path;\n    path.reserve(L);\n    int cur = best_v;\n    for (int step = L - 1; step >= 0; --step) {\n        path.push_back({cur / N, cur % N});\n        if (step > 0) cur = parent[step][cur];\n    }\n    reverse(path.begin(), path.end());\n    \n    for (auto [i, j] : path)\n        cout << i << \" \" << j << \"\\n\";\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ------------------------------------------------------------\n// Problem parameters\nint N, M;\ndouble eps;\nconst int MAX_N2 = 400; // 20*20\n\nstruct Placement {\n    bitset<MAX_N2> cells;\n    int area; // popcount\n};\n\nvector<vector<Placement>> placements; // [field][placement_idx]\nvector<int> num_placements; // [field]\n\n// ------------------------------------------------------------\n// Particle\nstruct Particle {\n    vector<int> pos; // size M, index of placement for each field\n    double weight;\n    Particle(int M_) : pos(M_), weight(1.0) {}\n};\n\nvector<Particle> particles;\nconst int NUM_PARTICLES = 2000;\n\n// ------------------------------------------------------------\n// Utilities\nint flat(int i, int j) { return i * N + j; }\n\n// ------------------------------------------------------------\n// Random generator\nmt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\ndouble rand_double() {\n    return uniform_real_distribution<double>(0.0, 1.0)(rng);\n}\n\n// ------------------------------------------------------------\n// Enumerate all valid placements for each field\nvoid enumerate_placements(const vector<vector<pair<int,int>>>& shapes) {\n    placements.resize(M);\n    num_placements.resize(M);\n    for (int k = 0; k < M; ++k) {\n        const auto& shape = shapes[k];\n        int h = 0, w = 0;\n        for (auto [i, j] : shape) {\n            h = max(h, i);\n            w = max(w, j);\n        }\n        // translations\n        for (int di = 0; di + h < N; ++di) {\n            for (int dj = 0; dj + w < N; ++dj) {\n                Placement p;\n                p.area = (int)shape.size();\n                for (auto [i, j] : shape) {\n                    int ni = di + i;\n                    int nj = dj + j;\n                    p.cells.set(flat(ni, nj));\n                }\n                placements[k].push_back(p);\n            }\n        }\n        num_placements[k] = (int)placements[k].size();\n        if (num_placements[k] == 0) {\n            // should not happen with valid input\n        }\n    }\n}\n\n// ------------------------------------------------------------\n// Initialize particles uniformly at random\nvoid init_particles(const vector<int>& forced_val = {}) {\n    particles.clear();\n    particles.reserve(NUM_PARTICLES);\n    for (int i = 0; i < NUM_PARTICLES; ++i) {\n        Particle p(M);\n        for (int k = 0; k < M; ++k) {\n            p.pos[k] = rand_int(0, num_placements[k] - 1);\n        }\n        p.weight = 1.0;\n        particles.push_back(p);\n    }\n}\n\n// ------------------------------------------------------------\n// Compute cell probabilities from particles\n// Returns vector<double> prob (size N*N), and also fills drilled constraints\nvector<double> compute_cell_probs(const vector<int>& drilled_val) {\n    vector<double> prob(N*N, 0.0);\n    for (const auto& p : particles) {\n        // coverage bitset of this particle\n        bitset<MAX_N2> cov;\n        for (int k = 0; k < M; ++k) {\n            cov |= placements[k][p.pos[k]].cells;\n        }\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (cov[idx]) prob[idx] += 1.0;\n        }\n    }\n    double invP = 1.0 / particles.size();\n    for (int i = 0; i < N*N; ++i) prob[i] *= invP;\n    return prob;\n}\n\n// ------------------------------------------------------------\n// Resample particles according to weights\nvoid resample() {\n    double sumw = 0.0;\n    for (auto& p : particles) sumw += p.weight;\n    if (sumw == 0) {\n        // all weights zero, reinitialize\n        init_particles();\n        return;\n    }\n    for (auto& p : particles) p.weight /= sumw;\n    \n    vector<Particle> new_parts;\n    new_parts.reserve(particles.size());\n    double step = 1.0 / particles.size();\n    double r = rand_double() * step;\n    double csum = 0.0;\n    size_t idx = 0;\n    for (size_t i = 0; i < particles.size(); ++i) {\n        double target = r + i * step;\n        while (idx < particles.size() && csum + particles[idx].weight < target) {\n            csum += particles[idx].weight;\n            ++idx;\n        }\n        if (idx >= particles.size()) idx = particles.size() - 1;\n        new_parts.push_back(particles[idx]);\n        new_parts.back().weight = 1.0;\n    }\n    particles.swap(new_parts);\n}\n\n// ------------------------------------------------------------\n// Filter particles by a drilled cell (exact value v)\nvoid filter_by_drill(int cell, int v) {\n    vector<Particle> filtered;\n    filtered.reserve(particles.size());\n    for (const auto& p : particles) {\n        int cnt = 0;\n        for (int k = 0; k < M; ++k) {\n            if (placements[k][p.pos[k]].cells[cell]) ++cnt;\n        }\n        if (cnt == v) filtered.push_back(p);\n    }\n    if ((int)filtered.size() < 10) {\n        // keep some random ones to avoid collapse, or reinitialize with constraint\n        // For simplicity, if too few, we keep original but this is rare\n        if (filtered.empty()) {\n            // total collapse, reinitialize and hope for the best\n            init_particles();\n            return;\n        }\n    }\n    particles.swap(filtered);\n    // reset weights\n    for (auto& p : particles) p.weight = 1.0;\n}\n\n// ------------------------------------------------------------\n// Main\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // ---- Input ------------------------------------------------\n    if (!(cin >> N >> M >> eps)) return 0;\n    vector<vector<pair<int,int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n    \n    enumerate_placements(shapes);\n    init_particles();\n    \n    vector<char> is_drilled(N*N, 0);\n    vector<int> drilled_val(N*N, -1);\n    \n    const int MAX_Q = 2 * N * N;\n    \n    for (int qcnt = 0; qcnt < MAX_Q - 5; ++qcnt) {\n        // Compute current beliefs\n        vector<double> prob = compute_cell_probs(drilled_val);\n        \n        // Identify uncertain cells\n        vector<int> uncertain;\n        uncertain.reserve(N*N);\n        for (int idx = 0; idx < N*N; ++idx) {\n            if (is_drilled[idx]) continue;\n            if (prob[idx] > 0.1 && prob[idx] < 0.9) {\n                uncertain.push_back(idx);\n            }\n        }\n        \n        // Decide action\n        bool do_answer = false;\n        bool do_drill = false;\n        int drill_cell = -1;\n        vector<int> query_cells; // for divine\n        \n        // If almost all cells are certain, try to answer\n        if ((int)uncertain.size() <= 3 || qcnt > MAX_Q - 10) {\n            do_answer = true;\n        } else if (qcnt < 30) {\n            // Exploration: random large divine query\n            bitset<MAX_N2> mask;\n            for (int i = 0; i < N*N; ++i) {\n                if (rand_int(0,1)) query_cells.push_back(i);\n            }\n            if ((int)query_cells.size() < 2) {\n                query_cells.push_back(0);\n                query_cells.push_back(1);\n            }\n        } else {\n            // Exploitation: divine a batch of uncertain cells\n            // Take up to 25 cells to keep noise moderate (sigma ~ 0.5 for eps=0.01)\n            int take = min((int)uncertain.size(), 25);\n            // Sort by closest to 0.5\n            sort(uncertain.begin(), uncertain.end(), [&](int a, int b){\n                double da = abs(prob[a] - 0.5);\n                double db = abs(prob[b] - 0.5);\n                return da < db;\n            });\n            query_cells.assign(uncertain.begin(), uncertain.begin() + take);\n        }\n        \n        if (do_answer) {\n            vector<int> ans_cells;\n            for (int idx = 0; idx < N*N; ++idx) {\n                if (is_drilled[idx]) {\n                    if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n                } else {\n                    if (prob[idx] > 0.5) ans_cells.push_back(idx);\n                }\n            }\n            // Output answer\n            cout << \"a \" << ans_cells.size();\n            for (int idx : ans_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            int resp; cin >> resp;\n            if (resp == 1) {\n                return 0; // success\n            } else {\n                // Wrong answer, penalized 1 cost, continue\n                continue;\n            }\n        }\n        \n        if (!query_cells.empty() && !do_drill) {\n            // Divine query\n            int k = (int)query_cells.size();\n            cout << \"q \" << k;\n            for (int idx : query_cells) {\n                cout << \" \" << idx / N << \" \" << idx % N;\n            }\n            cout << endl;\n            \n            int obs; cin >> obs;\n            \n            // Prepare query mask\n            bitset<MAX_N2> qmask;\n            for (int idx : query_cells) qmask.set(idx);\n            \n            // Update weights\n            double kdbl = k;\n            double mu0 = kdbl * eps;\n            double sigma2 = kdbl * eps * (1.0 - eps);\n            double sigma = sqrt(sigma2);\n            if (sigma < 1e-9) sigma = 1e-9;\n            \n            for (auto& p : particles) {\n                int v = 0;\n                for (int m = 0; m < M; ++m) {\n                    v += (placements[m][p.pos[m]].cells & qmask).count();\n                }\n                double mu = mu0 + v * (1.0 - 2.0 * eps);\n                // Gaussian likelihood (ignoring round/max)\n                double z = (obs - mu) / sigma;\n                double w = exp(-0.5 * z * z);\n                p.weight = w;\n            }\n            resample();\n        } else if (do_drill && drill_cell >= 0) {\n            // Single drill\n            cout << \"q 1 \" << drill_cell / N << \" \" << drill_cell % N << endl;\n            int val; cin >> val;\n            is_drilled[drill_cell] = 1;\n            drilled_val[drill_cell] = val;\n            filter_by_drill(drill_cell, val);\n        }\n    }\n    \n    // Fallback: if we exit loop without answering, just answer with current belief\n    vector<int> ans_cells;\n    vector<double> prob = compute_cell_probs(drilled_val);\n    for (int idx = 0; idx < N*N; ++idx) {\n        if (is_drilled[idx]) {\n            if (drilled_val[idx] > 0) ans_cells.push_back(idx);\n        } else {\n            if (prob[idx] > 0.5) ans_cells.push_back(idx);\n        }\n    }\n    cout << \"a \" << ans_cells.size();\n    for (int idx : ans_cells) {\n        cout << \" \" << idx / N << \" \" << idx % N;\n    }\n    cout << endl;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> day_dist(0, D-1);\n    uniform_int_distribution<int> strip_dist(0, N-1);\n    \n    // Heights h[d][k]\n    vector<vector<int>> h(D, vector<int>(N, 1));\n    \n    // Greedy initialization\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> needs;\n        for (int k = 0; k < N; k++) {\n            int need = (a[d][k] + W - 1) / W;\n            needs.push_back({need, k});\n        }\n        sort(needs.rbegin(), needs.rend());\n        \n        int remaining = W - N;\n        for (auto &[need, k] : needs) {\n            int give = min(remaining, max(0, need - 1));\n            h[d][k] = 1 + give;\n            remaining -= give;\n        }\n        int idx = 0;\n        while (remaining > 0) {\n            h[d][idx % N]++;\n            remaining--;\n            idx++;\n        }\n    }\n    \n    // Cumulative positions y[d][k]\n    vector<vector<int>> y(D, vector<int>(N+1));\n    for (int d = 0; d < D; d++) {\n        y[d][0] = 0;\n        for (int k = 0; k < N; k++) y[d][k+1] = y[d][k] + h[d][k];\n    }\n    \n    // Precompute area deficits\n    auto area_cost = [&](int d, int k) -> long long {\n        long long area = 1LL * h[d][k] * W;\n        if (area < a[d][k]) return 100LL * (a[d][k] - area);\n        return 0;\n    };\n    \n    long long cur_area_cost = 0, cur_part_cost = 0;\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cur_area_cost += area_cost(d, k);\n    }\n    for (int d = 1; d < D; d++) {\n        for (int k = 1; k < N; k++) {\n            if (y[d][k] != y[d-1][k]) cur_part_cost += 2LL * W;\n        }\n    }\n    \n    long long current_cost = cur_area_cost + cur_part_cost;\n    long long best_cost = current_cost;\n    auto best_h = h;\n    \n    const double TIME_LIMIT = 2.85;\n    clock_t start_time = clock();\n    \n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > TIME_LIMIT) break;\n        \n        double progress = elapsed / TIME_LIMIT;\n        double T = 500000.0 * (1.0 - progress) + 1.0;\n        \n        int d = day_dist(rng);\n        int i = strip_dist(rng);\n        int j = strip_dist(rng);\n        if (i == j) continue;\n        if (h[d][i] <= 1) continue;\n        \n        int l = min(i, j) + 1;\n        int r = max(i, j);\n        int delta = (i < j) ? -1 : +1;\n        \n        // Compute delta cost\n        long long da = 0;\n        \n        // Area changes\n        long long old_i = area_cost(d, i);\n        long long new_i = (1LL * (h[d][i]-1) * W < a[d][i]) ? 100LL * (a[d][i] - 1LL * (h[d][i]-1) * W) : 0;\n        da += new_i - old_i;\n        \n        long long old_j = area_cost(d, j);\n        long long new_j = (1LL * (h[d][j]+1) * W < a[d][j]) ? 100LL * (a[d][j] - 1LL * (h[d][j]+1) * W) : 0;\n        da += new_j - old_j;\n        \n        // Partition changes\n        long long dp = 0;\n        for (int k = l; k <= r; k++) {\n            int old_y = y[d][k];\n            int new_y = old_y + delta;\n            \n            if (d > 0) {\n                bool oeq = (old_y == y[d-1][k]);\n                bool neq = (new_y == y[d-1][k]);\n                if (oeq && !neq) dp += 2LL * W;\n                else if (!oeq && neq) dp -= 2LL * W;\n            }\n            if (d < D - 1) {\n                bool oeq = (old_y == y[d+1][k]);\n                bool neq = (new_y == y[d+1][k]);\n                if (oeq && !neq) dp += 2LL * W;\n                else if (!oeq && neq) dp -= 2LL * W;\n            }\n        }\n        \n        long long delta_cost = da + dp;\n        \n        bool accept = (delta_cost < 0);\n        if (!accept && T > 0.1) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < exp(-(double)delta_cost / T)) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            h[d][i]--;\n            h[d][j]++;\n            for (int k = l; k <= r; k++) y[d][k] += delta;\n            current_cost += delta_cost;\n            \n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_h = h;\n            }\n        }\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        int cur = 0;\n        for (int k = 0; k < N; k++) {\n            int i1 = cur;\n            cur += best_h[d][k];\n            int i2 = cur;\n            cout << i1 << \" 0 \" << i2 << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m, p, q;\n    int pos[9];\n    int val[9];\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int tc = 0; tc < 150; ++tc) {\n        int n, m, k;\n        if (!(cin >> n >> m >> k)) return 0;\n        \n        vector<long long> grid(n * n);\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cin >> grid[i * n + j];\n            }\n        }\n        \n        int stamp_vals[20][3][3];\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                for (int l = 0; l < 3; ++l) {\n                    cin >> stamp_vals[i][j][l];\n                }\n            }\n        }\n        \n        // Precompute all 980 operations\n        vector<Op> ops;\n        ops.reserve(m * (n-2) * (n-2));\n        for (int mi = 0; mi < m; ++mi) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    Op op;\n                    op.m = mi; op.p = p; op.q = q;\n                    int cnt = 0;\n                    for (int i = 0; i < 3; ++i) {\n                        for (int j = 0; j < 3; ++j) {\n                            op.pos[cnt] = (p + i) * n + (q + j);\n                            op.val[cnt] = stamp_vals[mi][i][j];\n                            cnt++;\n                        }\n                    }\n                    ops.push_back(op);\n                }\n            }\n        }\n        \n        const int NUM_OPS = ops.size();\n        vector<int> sol;\n        sol.reserve(k);\n        \n        mt19937 rng(tc + 12345);\n        \n        auto calc_delta = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv + op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto calc_delta_remove = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv - op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto apply_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] += op.val[i];\n        };\n        \n        auto remove_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] -= op.val[i];\n        };\n        \n        // Greedy construction\n        for (int iter = 0; iter < k; ++iter) {\n            long long best_d = 0;\n            int best_idx = -1;\n            \n            // Random shuffle to break ties and add diversity\n            vector<int> order(NUM_OPS);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            \n            for (int idx : order) {\n                long long d = calc_delta(ops[idx]);\n                if (d > best_d) {\n                    best_d = d;\n                    best_idx = idx;\n                }\n            }\n            \n            if (best_idx == -1) break;\n            apply_op(ops[best_idx]);\n            sol.push_back(best_idx);\n        }\n        \n        // Simulated Annealing\n        const int SA_ITER = 30000;\n        double temp = 1e9;\n        double alpha = pow(0.1 / temp, 1.0 / SA_ITER);\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < SA_ITER; ++iter) {\n            if (sol.empty()) {\n                int idx = rng() % NUM_OPS;\n                long long d = calc_delta(ops[idx]);\n                apply_op(ops[idx]);\n                sol.push_back(idx);\n            } else if ((int)sol.size() >= k) {\n                int sidx = rng() % sol.size();\n                const Op& op = ops[sol[sidx]];\n                long long d = calc_delta_remove(op);\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    remove_op(op);\n                    sol[sidx] = sol.back();\n                    sol.pop_back();\n                }\n            } else {\n                int type = rng() % 3;\n                if (type == 0) {\n                    int idx = rng() % NUM_OPS;\n                    long long d = calc_delta(ops[idx]);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        apply_op(ops[idx]);\n                        sol.push_back(idx);\n                    }\n                } else if (type == 1) {\n                    int sidx = rng() % sol.size();\n                    const Op& op = ops[sol[sidx]];\n                    long long d = calc_delta_remove(op);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        remove_op(op);\n                        sol[sidx] = sol.back();\n                        sol.pop_back();\n                    }\n                } else {\n                    // Replace\n                    int sidx = rng() % sol.size();\n                    int new_idx = rng() % NUM_OPS;\n                    const Op& old_op = ops[sol[sidx]];\n                    \n                    long long d_rem = calc_delta_remove(old_op);\n                    remove_op(old_op);\n                    \n                    const Op& new_op = ops[new_idx];\n                    long long d_add = calc_delta(new_op);\n                    \n                    long long total = d_rem + d_add;\n                    if (total > 0 || exp(total / temp) > dist(rng)) {\n                        apply_op(new_op);\n                        sol[sidx] = new_idx;\n                    } else {\n                        apply_op(old_op);\n                    }\n                }\n            }\n            temp *= alpha;\n        }\n        \n        cout << sol.size() << '\\n';\n        for (int idx : sol) {\n            cout << ops[idx].m << ' ' << ops[idx].p << ' ' << ops[idx].q << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) \n        for (int j = 0; j < N; j++) \n            cin >> A[i][j];\n    \n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<int> recv_ptr(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        grid[i][0] = A[i][0];\n        recv_ptr[i] = 1;\n    }\n    \n    int cr = 0, cc = 0;\n    bool holding = false;\n    int held_id = -1;\n    \n    vector<string> ops(N);\n    int turn = 0;\n    \n    auto add_op = [&](int crane, char c) {\n        if ((int)ops[crane].size() <= turn) \n            ops[crane].push_back(c);\n        else \n            ops[crane][turn] = c;\n    };\n    \n    auto do_receiving = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][0] == -1 && recv_ptr[i] < N) {\n                grid[i][0] = A[i][recv_ptr[i]];\n                recv_ptr[i]++;\n            }\n        }\n    };\n    \n    auto do_dispatch = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    };\n    \n    auto end_turn = [&]() {\n        do_dispatch();\n        do_receiving();\n        turn++;\n    };\n    \n    add_op(0, '.');\n    for (int i = 1; i < N; i++) add_op(i, 'B');\n    end_turn();\n    \n    vector<int> dispatched(N, 0);\n    vector<int> taken_from_gate(N, 0);\n    \n    auto move_to = [&](int tr, int tc) {\n        while (cr != tr) {\n            add_op(0, cr < tr ? 'D' : 'U');\n            cr += (cr < tr) ? 1 : -1;\n            end_turn();\n        }\n        while (cc != tc) {\n            add_op(0, cc < tc ? 'R' : 'L');\n            cc += (cc < tc) ? 1 : -1;\n            end_turn();\n        }\n    };\n    \n    auto pickup = [&]() {\n        add_op(0, 'P');\n        held_id = grid[cr][cc];\n        grid[cr][cc] = -1;\n        holding = true;\n        end_turn();\n    };\n    \n    auto drop = [&]() {\n        add_op(0, 'Q');\n        grid[cr][cc] = held_id;\n        holding = false;\n        held_id = -1;\n        end_turn();\n    };\n    \n    auto find_any_parking = [&]() -> pair<int, int> {\n        // Prefer target row, then any row, cols 2,3,1 first, then 0\n        for (int r = 0; r < N; r++) {\n            for (int c : {2, 3, 1}) {\n                if (grid[r][c] == -1) return {r, c};\n            }\n        }\n        for (int r = 0; r < N; r++) {\n            if (grid[r][0] == -1) return {r, 0};\n        }\n        return {-1, -1};\n    };\n    \n    auto park_container = [&](int container_id, int current_row) {\n        int target_row = container_id / N;\n        \n        // Try target row first\n        for (int c : {2, 3, 1, 0}) {\n            if (grid[target_row][c] == -1) {\n                move_to(target_row, c);\n                drop();\n                return;\n            }\n        }\n        \n        // Try alternative row\n        for (int c : {2, 3, 1, 0}) {\n            if (grid[current_row][c] == -1) {\n                move_to(current_row, c);\n                drop();\n                return;\n            }\n        }\n        \n        // Emergency: any row\n        auto [pr, pc] = find_any_parking();\n        if (pc != -1) {\n            move_to(pr, pc);\n            drop();\n        } else {\n            // Should never happen, but dispatch at target row gate to avoid crash\n            // This is wrong but prevents crash\n            move_to(target_row, N-1);\n            drop();\n        }\n    };\n    \n    for (int target = 0; target < N; target++) {\n        auto try_dispatch = [&]() -> bool {\n            if (!holding) return false;\n            int need = target * N + dispatched[target];\n            if (held_id == need) {\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n                return true;\n            }\n            return false;\n        };\n        \n        while (taken_from_gate[target] < N) {\n            int cid = A[target][taken_from_gate[target]];\n            move_to(target, 0);\n            pickup();\n            taken_from_gate[target]++;\n            \n            if (!try_dispatch()) {\n                park_container(cid, target);\n            }\n        }\n        \n        for (int g = 0; g < N; g++) {\n            if (g == target) continue;\n            \n            while (taken_from_gate[g] < N) {\n                int cid = A[g][taken_from_gate[g]];\n                if (cid / N != target) break;\n                \n                while (taken_from_gate[g] < N && A[g][taken_from_gate[g]] != cid) {\n                    int blk = A[g][taken_from_gate[g]];\n                    move_to(g, 0);\n                    pickup();\n                    taken_from_gate[g]++;\n                    park_container(blk, target);\n                }\n                \n                move_to(g, 0);\n                pickup();\n                taken_from_gate[g]++;\n                \n                if (!try_dispatch()) {\n                    park_container(cid, target);\n                }\n            }\n        }\n        \n        while (dispatched[target] < N) {\n            int need = target * N + dispatched[target];\n            int fc = -1;\n            for (int c = 0; c < N-1; c++) {\n                if (grid[target][c] == need) {\n                    fc = c;\n                    break;\n                }\n            }\n            if (fc != -1) {\n                move_to(target, fc);\n                pickup();\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    size_t max_len = 0;\n    for (auto &s : ops) max_len = max(max_len, s.size());\n    for (auto &s : ops) {\n        while (s.size() < max_len) s.push_back('.');\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int r = 0, c = 0;\n    long long load = 0;\n    \n    auto move_to = [&](int nr, int nc) {\n        while (r < nr) { ops.emplace_back(\"D\"); ++r; }\n        while (r > nr) { ops.emplace_back(\"U\"); --r; }\n        while (c < nc) { ops.emplace_back(\"R\"); ++c; }\n        while (c > nc) { ops.emplace_back(\"L\"); --c; }\n    };\n    \n    auto dist = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n    \n    while (true) {\n        bool any_pos = false, any_neg = false;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (h[i][j] > 0) any_pos = true;\n                if (h[i][j] < 0) any_neg = true;\n            }\n        }\n        if (!any_pos && !any_neg) break;\n        \n        if (load == 0) {\n            if (!any_pos) break;\n            \n            // BFS for sink distances from each cell\n            vector<vector<int>> sink_dist(N, vector<int>(N, 1e9));\n            queue<pair<int,int>> q;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] < 0) {\n                        sink_dist[i][j] = 0;\n                        q.push({i, j});\n                    }\n                }\n            }\n            const int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k], nc = cc + dc[k];\n                    if (nr>=0 && nr<N && nc>=0 && nc<N && sink_dist[nr][nc]==1e9) {\n                        sink_dist[nr][nc] = sink_dist[cr][cc] + 1;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n            \n            // Find source minimizing: empty travel + loaded travel to sink\n            long long best_cost = (1LL<<60);\n            int best_amount = -1;\n            pair<int,int> target = {-1,-1};\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] > 0) {\n                        int d_empty = dist(r,c,i,j);\n                        int d_sink = sink_dist[i][j];\n                        if (d_sink == 1e9) d_sink = 0;\n                        long long cost = 100LL*d_empty + (100LL+h[i][j])*d_sink;\n                        // Tie-break by larger amount (fewer trips)\n                        if (cost < best_cost || (cost == best_cost && h[i][j] > best_amount)) {\n                            best_cost = cost;\n                            best_amount = h[i][j];\n                            target = {i,j};\n                        }\n                    }\n                }\n            }\n            \n            move_to(target.first, target.second);\n            ops.push_back(\"+\" + to_string(h[r][c]));\n            load += h[r][c];\n            h[r][c] = 0;\n            \n        } else {\n            if (!any_neg) break;\n            \n            // Pure nearest neighbor for sinks\n            int best_dist = 1e9;\n            pair<int,int> target = {-1,-1};\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] < 0) {\n                        int d = dist(r,c,i,j);\n                        if (d < best_dist) {\n                            best_dist = d;\n                            target = {i,j};\n                        }\n                    }\n                }\n            }\n            \n            move_to(target.first, target.second);\n            int amt = (int)min(load, (long long)(-h[r][c]));\n            ops.push_back(\"-\" + to_string(amt));\n            load -= amt;\n            h[r][c] += amt;\n        }\n    }\n    \n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Solver {\n    int N, M, T;\n    int SEED_COUNT;\n    struct Seed {\n        vector<int> x;\n        int sum;\n        int mx;\n    };\n    vector<Seed> seeds;\n    mt19937 rng;\n    chrono::steady_clock::time_point start_time;\n    const double TIME_LIMIT = 1.95;\n\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        start_time = chrono::steady_clock::now();\n    }\n\n    double getTime() {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - start_time).count();\n    }\n\n    void solveOneTurn(int turn, int total_turns) {\n        double turn_start = getTime();\n        double time_per_turn = (TIME_LIMIT - turn_start) / (total_turns - turn);\n        double turn_end = turn_start + time_per_turn * 0.98;\n\n        // Select seeds: score = sum + 5*max (restored from best version)\n        vector<pair<ll, int>> candidates;\n        for (int i = 0; i < SEED_COUNT; i++) {\n            ll score = seeds[i].sum + 5LL * seeds[i].mx;\n            candidates.push_back({score, i});\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        vector<int> selected;\n        for (int i = 0; i < N * N; i++) {\n            selected.push_back(candidates[i].second);\n        }\n\n        int S = N * N;\n        \n        // Precompute edge scores\n        vector<vector<ll>> edgeScore(S, vector<ll>(S));\n        for (int i = 0; i < S; i++) {\n            for (int j = i; j < S; j++) {\n                int a = selected[i];\n                int b = selected[j];\n                ll s = 0;\n                for (int l = 0; l < M; l++) {\n                    s += max(seeds[a].x[l], seeds[b].x[l]);\n                }\n                edgeScore[i][j] = edgeScore[j][i] = s;\n            }\n        }\n\n        // Position info\n        vector<pair<int,int>> idx2pos(S);\n        vector<int> pos2idx(N*N, -1);\n        vector<vector<int>> neighbors(S);\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        \n        // Sort positions by degree (center first)\n        vector<pair<int, pair<int,int>>> posList;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int deg = (i>0) + (i<N-1) + (j>0) + (j<N-1);\n                posList.push_back({deg, {i, j}});\n            }\n        }\n        sort(posList.rbegin(), posList.rend());\n        \n        for (int i = 0; i < S; i++) {\n            idx2pos[i] = posList[i].second;\n            pos2idx[posList[i].second.first * N + posList[i].second.second] = i;\n        }\n        \n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    neighbors[idx].push_back(pos2idx[ni * N + nj]);\n                }\n            }\n        }\n\n        // Fast greedy initialization with adaptive window\n        vector<int> placement(S, -1);\n        vector<bool> used(S, false);\n        \n        for (int posIdx = 0; posIdx < S; posIdx++) {\n            ll bestGain = -1;\n            int bestSeed = -1;\n            \n            // Adaptive window: look at top candidates and some ahead\n            int window_start = min(posIdx, S - 1);\n            int window_end = min(S, posIdx + 20); // Small window\n            \n            for (int attempt = 0; attempt < 2; attempt++) {\n                for (int s = window_start; s < window_end && s < S; s++) {\n                    if (used[s]) continue;\n                    ll gain = 0;\n                    for (int nb : neighbors[posIdx]) {\n                        if (placement[nb] != -1) {\n                            gain += edgeScore[s][placement[nb]];\n                        }\n                    }\n                    if (posIdx < S/3) gain += candidates[s].first / 5;\n                    \n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestSeed = s;\n                    }\n                }\n                if (bestSeed != -1) break;\n                // Expand to full search if not found\n                window_start = 0;\n                window_end = S;\n            }\n            \n            // Final fallback\n            if (bestSeed == -1) {\n                for (int s = 0; s < S; s++) {\n                    if (!used[s]) {\n                        bestSeed = s;\n                        break;\n                    }\n                }\n            }\n            \n            placement[posIdx] = bestSeed;\n            used[bestSeed] = true;\n        }\n\n        auto calcCell = [&](int idx, const vector<int>& p) -> ll {\n            ll s = 0;\n            for (int nb : neighbors[idx]) {\n                s += edgeScore[p[idx]][p[nb]];\n            }\n            return s;\n        };\n\n        // Simulated Annealing with reheating\n        vector<int> bestPlacement = placement;\n        ll currentScore = 0;\n        for (int i = 0; i < S; i++) currentScore += calcCell(i, placement);\n        currentScore /= 2;\n        ll bestScore = currentScore;\n        \n        double temp = 500.0;\n        const double cooling = 0.9999;\n        const double reheat_temp = 200.0;\n        \n        int iter = 0;\n        int lastImprove = 0;\n        int reheatCount = 0;\n        \n        while (getTime() < turn_end) {\n            if (iter - lastImprove > 8000 && reheatCount < 3) {\n                temp = reheat_temp;\n                lastImprove = iter;\n                reheatCount++;\n                placement = bestPlacement;\n                currentScore = bestScore;\n            }\n\n            int idx1 = rng() % S;\n            int idx2 = rng() % S;\n            if (idx1 == idx2) continue;\n\n            ll oldVal = calcCell(idx1, placement) + calcCell(idx2, placement);\n            swap(placement[idx1], placement[idx2]);\n            ll newVal = calcCell(idx1, placement) + calcCell(idx2, placement);\n            ll delta = newVal - oldVal;\n\n            if (delta > 0) {\n                currentScore += delta;\n                lastImprove = iter;\n                if (currentScore > bestScore) {\n                    bestScore = currentScore;\n                    bestPlacement = placement;\n                }\n            } else if (exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore += delta;\n            } else {\n                swap(placement[idx1], placement[idx2]);\n            }\n\n            temp *= cooling;\n            if (temp < 0.0001) temp = 0.0001;\n            iter++;\n        }\n\n        placement = bestPlacement;\n\n        // Intensive local search\n        bool improved = true;\n        int rounds = 0;\n        while (improved && rounds < 5 && getTime() < turn_end) {\n            improved = false;\n            rounds++;\n            for (int i = 0; i < S && getTime() < turn_end; i++) {\n                for (int j = i + 1; j < S; j++) {\n                    ll oldVal = calcCell(i, placement) + calcCell(j, placement);\n                    swap(placement[i], placement[j]);\n                    ll newVal = calcCell(i, placement) + calcCell(j, placement);\n                    if (newVal > oldVal) {\n                        improved = true;\n                    } else {\n                        swap(placement[i], placement[j]);\n                    }\n                }\n            }\n        }\n\n        // Output\n        vector<vector<int>> output(N, vector<int>(N));\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            output[i][j] = selected[placement[idx]];\n        }\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j > 0) cout << ' ';\n                cout << output[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n    }\n\n    void solve() {\n        cin >> N >> M >> T;\n        SEED_COUNT = 2 * N * (N - 1);\n        seeds.resize(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].x.resize(M);\n            seeds[i].sum = 0;\n            seeds[i].mx = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].x[j];\n                seeds[i].sum += seeds[i].x[j];\n                seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n            }\n        }\n\n        for (int turn = 0; turn < T; turn++) {\n            solveOneTurn(turn, T);\n\n            for (int i = 0; i < SEED_COUNT; i++) {\n                seeds[i].sum = 0;\n                seeds[i].mx = 0;\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i].x[j];\n                    seeds[i].sum += seeds[i].x[j];\n                    seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V_limit;\nvector<pair<int,int>> sources, targets;\n\n// Hungarian algorithm for minimum cost perfect matching\nvector<int> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i=1; i<=n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INT_MAX);\n        vector<char> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INT_MAX, j1 = 0;\n            for (int j=1; j<=m; j++) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j=0; j<=m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> match(n);\n    for (int j=1; j<=m; j++) {\n        if (p[j] != 0) match[p[j]-1] = j-1;\n    }\n    return match;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> V_limit;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i=0; i<N; i++) cin >> s_grid[i];\n    for (int i=0; i<N; i++) cin >> t_grid[i];\n\n    // Collect positions (x=row, y=col)\n    for (int i=0; i<N; i++) {\n        for (int j=0; j<N; j++) {\n            if (s_grid[i][j] == '1') sources.push_back({i, j});\n            if (t_grid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    // Build cost matrix (Manhattan distance)\n    vector<vector<int>> cost(M, vector<int>(M));\n    for (int i=0; i<M; i++) {\n        for (int j=0; j<M; j++) {\n            cost[i][j] = abs(sources[i].first - targets[j].first) \n                       + abs(sources[i].second - targets[j].second);\n        }\n    }\n    \n    vector<int> match = hungarian(cost);\n    \n    // Create pairs (source, target)\n    vector<pair<pair<int,int>, pair<int,int>>> pairs;\n    for (int i=0; i<M; i++) {\n        pairs.push_back({sources[i], targets[match[i]]});\n    }\n\n    // Build dependency graph: if target of i is source of j, then j must come before i\n    map<pair<int,int>, int> src_to_idx;\n    for (int i=0; i<M; i++) {\n        src_to_idx[pairs[i].first] = i;\n    }\n    \n    vector<vector<int>> adj(M);\n    vector<int> indeg(M, 0);\n    \n    for (int i=0; i<M; i++) {\n        auto it = src_to_idx.find(pairs[i].second);\n        if (it != src_to_idx.end()) {\n            int j = it->second; // pairs[j].first == pairs[i].second\n            if (i != j) {\n                adj[j].push_back(i);\n                indeg[i]++;\n            }\n        }\n    }\n\n    // Topological greedy ordering (no local search to avoid constraint violations)\n    vector<pair<pair<int,int>, pair<int,int>>> ordered;\n    vector<bool> processed(M, false);\n    \n    // Initial position for greedy selection: median of sources\n    int cur_x, cur_y;\n    {\n        vector<int> xs, ys;\n        for (auto& s : sources) {\n            xs.push_back(s.first);\n            ys.push_back(s.second);\n        }\n        sort(xs.begin(), xs.end());\n        sort(ys.begin(), ys.end());\n        cur_x = xs[xs.size()/2];\n        cur_y = ys[ys.size()/2];\n    }\n    \n    for (int iter=0; iter<M; iter++) {\n        int best_i = -1;\n        int best_dist = INT_MAX;\n        \n        for (int i=0; i<M; i++) {\n            if (processed[i] || indeg[i] > 0) continue;\n            int d = abs(cur_x - pairs[i].first.first) \n                  + abs(cur_y - pairs[i].first.second);\n            if (d < best_dist) {\n                best_dist = d;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        processed[best_i] = true;\n        ordered.push_back(pairs[best_i]);\n        cur_x = pairs[best_i].second.first;\n        cur_y = pairs[best_i].second.second;\n        \n        for (int nb : adj[best_i]) {\n            indeg[nb]--;\n        }\n    }\n\n    // Calculate optimal start position: median of first few task sources\n    int start_x, start_y;\n    {\n        vector<int> xs, ys;\n        int sample = min((int)ordered.size(), 10);\n        for (int i=0; i<sample; i++) {\n            xs.push_back(ordered[i].first.first);\n            ys.push_back(ordered[i].first.second);\n        }\n        sort(xs.begin(), xs.end());\n        sort(ys.begin(), ys.end());\n        start_x = xs[xs.size()/2];\n        start_y = ys[ys.size()/2];\n    }\n\n    // Output tree: 2 vertices (root + fingertip), edge length 1\n    cout << 2 << \"\\n\";\n    cout << \"0 1\\n\";\n    cout << start_x << \" \" << start_y << \"\\n\";\n\n    // Simulation\n    const int L = 1;\n    int rx = start_x, ry = start_y;\n    int dir = 0; // 0=right, 1=down, 2=left, 3=up\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    auto move_to = [&](int tx, int ty) {\n        // Find best direction to approach target\n        int best_d = 0;\n        int best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = tx - dx[d] * L;\n            int ny = ty - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manhattan = abs(rx - nx) + abs(ry - ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manhattan, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        \n        int nx = tx - dx[best_d] * L;\n        int ny = ty - dy[best_d] * L;\n        \n        // Move and rotate until positioned\n        while (rx != nx || ry != ny || dir != best_d) {\n            string cmd(4, '.');\n            \n            // Move root toward target\n            if (rx < nx) { cmd[0] = 'D'; rx++; }\n            else if (rx > nx) { cmd[0] = 'U'; rx--; }\n            else if (ry < ny) { cmd[0] = 'R'; ry++; }\n            else if (ry > ny) { cmd[0] = 'L'; ry--; }\n            \n            // Rotate if needed (can combine with move)\n            if (dir != best_d) {\n                int diff = (best_d - dir + 4) % 4;\n                if (diff == 1) {\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                } else if (diff == 3) {\n                    cmd[1] = 'L';\n                    dir = (dir + 3) % 4;\n                } else if (diff == 2) {\n                    // 180 degrees - rotate 90 now\n                    cmd[1] = 'R';\n                    dir = (dir + 1) % 4;\n                }\n            }\n            cout << cmd << \"\\n\";\n        }\n    };\n    \n    auto perform_action = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P'; // fingertip is vertex 1\n        cout << cmd << \"\\n\";\n    };\n\n    // Execute\n    for (auto& [src, dst] : ordered) {\n        // Move to source and pickup\n        move_to(src.first, src.second);\n        perform_action();\n        \n        // Move to destination and drop\n        move_to(dst.first, dst.second);\n        perform_action();\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Node {\n    int sum = 0;\n    int best = 0;        // max subarray sum\n    int left_best = 0;   // max prefix sum\n    int right_best = 0;  // max suffix sum\n    int best_l = 0, best_r = 0; // indices of best subarray\n    int left_pos = 0;    // rightmost index of max prefix (end point)\n    int right_pos = 0;   // leftmost index of max suffix (start point)\n};\n\nclass SegTree {\n    int n;\n    int Y; // actual size\n    vector<Node> tree;\npublic:\n    SegTree(int size) {\n        Y = size;\n        n = 1;\n        while (n < Y) n <<= 1;\n        tree.resize(2 * n);\n        init(1, 0, n - 1);\n    }\n\n    void init(int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].left_pos = l;\n            tree[idx].right_pos = r;\n            tree[idx].best_l = l;\n            tree[idx].best_r = r;\n            // If beyond valid range, set to -INF so never chosen\n            if (l >= Y) {\n                tree[idx].best = -INF;\n                tree[idx].left_best = -INF;\n                tree[idx].right_best = -INF;\n                tree[idx].sum = 0;\n            }\n            return;\n        }\n        int mid = (l + r) >> 1;\n        init(idx << 1, l, mid);\n        init(idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    void pull(int idx, int left, int right) {\n        Node &res = tree[idx];\n        Node &L = tree[left];\n        Node &R = tree[right];\n\n        res.sum = L.sum + R.sum;\n\n        // Left prefix (max sum starting from left boundary)\n        if (L.left_best >= L.sum + R.left_best) {\n            res.left_best = L.left_best;\n            res.left_pos = L.left_pos;\n        } else {\n            res.left_best = L.sum + R.left_best;\n            res.left_pos = R.left_pos; // FIXED: takes end index from right child\n        }\n\n        // Right suffix (max sum ending at right boundary)\n        if (R.right_best >= R.sum + L.right_best) {\n            res.right_best = R.right_best;\n            res.right_pos = R.right_pos;\n        } else {\n            res.right_best = R.sum + L.right_best;\n            res.right_pos = L.right_pos; // FIXED: takes start index from left child\n        }\n\n        // Best subarray\n        res.best = L.best;\n        res.best_l = L.best_l;\n        res.best_r = L.best_r;\n\n        if (R.best > res.best) {\n            res.best = R.best;\n            res.best_l = R.best_l;\n            res.best_r = R.best_r;\n        }\n\n        int cross = L.right_best + R.left_best;\n        if (cross > res.best) {\n            res.best = cross;\n            res.best_l = L.right_pos; // Start of left suffix\n            res.best_r = R.left_pos;  // End of right prefix\n        }\n    }\n\n    void update(int pos, int val) { update(pos, val, 1, 0, n - 1); }\n\n    void update(int pos, int val, int idx, int l, int r) {\n        if (l == r) {\n            tree[idx].sum += val;\n            tree[idx].best += val;\n            tree[idx].left_best += val;\n            tree[idx].right_best += val;\n            return;\n        }\n        int mid = (l + r) >> 1;\n        if (pos <= mid) update(pos, val, idx << 1, l, mid);\n        else update(pos, val, idx << 1 | 1, mid + 1, r);\n        pull(idx, idx << 1, idx << 1 | 1);\n    }\n\n    const Node& query() const { return tree[1]; }\n};\n\nstruct Point {\n    int x, y;\n    int type; // +1 for mackerel, -1 for sardine\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    \n    vector<Point> points;\n    points.reserve(2 * N);\n    vector<int> all_x, all_y;\n    all_x.reserve(2 * N);\n    all_y.reserve(2 * N);\n\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Coordinate compression for y\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n    int Y = all_y.size();\n\n    // Group points by x-coordinate\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    \n    map<int, vector<pair<int, int>>> x_to_points; // x -> list of (y_idx, type)\n    for (const auto &p : points) {\n        int y_idx = lower_bound(all_y.begin(), all_y.end(), p.y) - all_y.begin();\n        x_to_points[p.x].push_back({y_idx, p.type});\n    }\n\n    // Select candidate x-coordinates (up to 1000 with highest density)\n    vector<int> x_cands = all_x;\n    if (x_cands.size() > 1000) {\n        vector<pair<int, int>> cnts;\n        for (int x : x_cands) {\n            cnts.push_back({-(int)x_to_points[x].size(), x}); // negative for min-heap simulation\n        }\n        sort(cnts.begin(), cnts.end()); // sort by count descending\n        x_cands.clear();\n        for (int i = 0; i < 1000; ++i) x_cands.push_back(cnts[i].second);\n        sort(x_cands.begin(), x_cands.end());\n    }\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 1, best_y1 = 0, best_y2 = 1;\n\n    // Sweep line\n    for (size_t i = 0; i < x_cands.size(); ++i) {\n        SegTree seg(Y);\n        for (size_t j = i; j < x_cands.size(); ++j) {\n            int x = x_cands[j];\n            auto it = x_to_points.find(x);\n            if (it != x_to_points.end()) {\n                for (const auto &[y_idx, typ] : it->second) {\n                    seg.update(y_idx, typ);\n                }\n            }\n            \n            const Node &res = seg.query();\n            if (res.best > best_score) {\n                // Validate indices are within bounds\n                if (res.best_l >= 0 && res.best_l < Y && res.best_r >= 0 && res.best_r < Y) {\n                    best_score = res.best;\n                    best_x1 = x_cands[i];\n                    best_x2 = x;\n                    best_y1 = all_y[res.best_l];\n                    best_y2 = all_y[res.best_r];\n                    if (best_y1 > best_y2) swap(best_y1, best_y2);\n                }\n            }\n        }\n    }\n\n    // Ensure valid rectangle (distinct vertices, positive area)\n    if (best_x1 == best_x2) {\n        if (best_x2 < 100000) best_x2++;\n        else best_x1--;\n    }\n    if (best_y1 == best_y2) {\n        if (best_y2 < 100000) best_y2++;\n        else best_y1--;\n    }\n\n    // Output rectangle\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    const double LR = 0.3;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    normal_distribution<double> noise(0, sigma / 3.0);\n    \n    // Working buffers\n    vector<double> x(N), y(N), cw(N), ch(N);\n    vector<double> xs(N), ys(N), cws(N), chs(N);\n    vector<int> cand_r(N), cand_d(N), cand_b(N);\n    \n    // Best sequence found\n    vector<int> best_r, best_d, best_b;\n    double best_score = 1e300;\n    \n    auto run_greedy = [&](vector<double>& w_in, vector<double>& h_in, \n                          bool record, double& outW, double& outH) -> double {\n        double curW = 0, curH = 0;\n        for (int i = 0; i < N; i++) {\n            double bestSc = 1e300;\n            int bestR = 0, bestD = 0, bestB = -1;\n            double bestX = 0, bestY = 0;\n            double wi0 = w_in[i], hi0 = h_in[i];\n            \n            for (int r = 0; r < 2; r++) {\n                double wi = r ? hi0 : wi0;\n                double hi = r ? wi0 : hi0;\n                for (int d = 0; d < 2; d++) {\n                    for (int b = -1; b < i; b++) {\n                        double xi, yi;\n                        if (d == 0) { // U\n                            xi = (b == -1) ? 0 : (x[b] + cw[b]);\n                            yi = 0;\n                            for (int j = 0; j < i; j++) {\n                                if (xi < x[j] + cw[j] && xi + wi > x[j]) {\n                                    yi = max(yi, y[j] + ch[j]);\n                                }\n                            }\n                        } else { // L\n                            yi = (b == -1) ? 0 : (y[b] + ch[b]);\n                            xi = 0;\n                            for (int j = 0; j < i; j++) {\n                                if (yi < y[j] + ch[j] && yi + hi > y[j]) {\n                                    xi = max(xi, x[j] + cw[j]);\n                                }\n                            }\n                        }\n                        double nW = max(curW, xi + wi);\n                        double nH = max(curH, yi + hi);\n                        double sc = nW + nH;\n                        if (sc < bestSc) {\n                            bestSc = sc;\n                            bestR = r; bestD = d; bestB = b;\n                            bestX = xi; bestY = yi;\n                        }\n                    }\n                }\n            }\n            \n            if (record) {\n                cand_r[i] = bestR;\n                cand_d[i] = bestD;\n                cand_b[i] = bestB;\n            }\n            x[i] = bestX; y[i] = bestY;\n            cw[i] = bestR ? hi0 : wi0;\n            ch[i] = bestR ? wi0 : hi0;\n            curW = max(curW, bestX + cw[i]);\n            curH = max(curH, bestY + ch[i]);\n        }\n        outW = curW; outH = curH;\n        return curW + curH;\n    };\n    \n    auto simulate_sequence = [&](vector<int>& seq_r, vector<int>& seq_d, vector<int>& seq_b,\n                                double& outW, double& outH) -> double {\n        double curW = 0, curH = 0;\n        for (int i = 0; i < N; i++) {\n            int r = seq_r[i];\n            double wi = r ? h[i] : w[i];\n            double hi = r ? w[i] : h[i];\n            int b = seq_b[i];\n            \n            if (seq_d[i] == 0) { // U\n                xs[i] = (b == -1) ? 0 : (xs[b] + cws[b]);\n                ys[i] = 0;\n                for (int j = 0; j < i; j++) {\n                    if (xs[i] < xs[j] + cws[j] && xs[i] + wi > xs[j]) {\n                        ys[i] = max(ys[i], ys[j] + chs[j]);\n                    }\n                }\n            } else { // L\n                ys[i] = (b == -1) ? 0 : (ys[b] + chs[b]);\n                xs[i] = 0;\n                for (int j = 0; j < i; j++) {\n                    if (ys[i] < ys[j] + chs[j] && ys[i] + hi > ys[j]) {\n                        xs[i] = max(xs[i], xs[j] + cws[j]);\n                    }\n                }\n            }\n            cws[i] = wi; chs[i] = hi;\n            curW = max(curW, xs[i] + wi);\n            curH = max(curH, ys[i] + hi);\n        }\n        outW = curW; outH = curH;\n        return curW + curH;\n    };\n    \n    for (int turn = 0; turn < T; turn++) {\n        double bestW = 0, bestH = 0;\n        int choice = 0; // 0=greedy, 1=best_seq, 2=perturbed\n        \n        // Candidate 1: Greedy with current estimates\n        double g1W, g1H;\n        double s1 = run_greedy(w, h, true, g1W, g1H);\n        bestW = g1W; bestH = g1H;\n        \n        // Save greedy result\n        vector<int> gr_r = cand_r, gr_d = cand_d, gr_b = cand_b;\n        vector<double> gr_x = x, gr_y = y, gr_cw = cw, gr_ch = ch;\n        \n        // Candidate 2: Simulate stored best sequence\n        if (!best_r.empty()) {\n            double s2W, s2H;\n            double s2 = simulate_sequence(best_r, best_d, best_b, s2W, s2H);\n            if (s2 < s1) {\n                s1 = s2;\n                choice = 1;\n                bestW = s2W; bestH = s2H;\n                // Copy simulation results to output buffers\n                x = xs; y = ys;\n                cw = cws; ch = chs;\n                cand_r = best_r; cand_d = best_d; cand_b = best_b;\n            }\n        }\n        \n        // Candidate 3: Greedy with perturbed estimates (exploration)\n        if (turn < T - 1) { // Don't explore on last turn\n            vector<double> wp = w, hp = h;\n            for (int i = 0; i < N; i++) {\n                wp[i] += noise(rng);\n                hp[i] += noise(rng);\n                if (wp[i] < 1) wp[i] = 1;\n                if (hp[i] < 1) hp[i] = 1;\n            }\n            double g3W, g3H;\n            double s3 = run_greedy(wp, hp, true, g3W, g3H);\n            if (s3 < s1) {\n                choice = 2;\n                bestW = g3W; bestH = g3H;\n                // The perturbed greedy used perturbed sizes for decisions,\n                // but we need to re-simulate with true sizes to get valid positions\n                // Actually, run_greedy used wp/hp for decisions, but we need\n                // to re-run with w,h to get correct positions... \n                // For simplicity, just use the sequence, re-simulate with true sizes\n                simulate_sequence(cand_r, cand_d, cand_b, bestW, bestH);\n                x = xs; y = ys;\n                cw = cws; ch = chs;\n            }\n        }\n        \n        // Update best sequence if improved\n        double cur_score = bestW + bestH;\n        if (cur_score < best_score) {\n            best_score = cur_score;\n            if (choice == 0) {\n                best_r = gr_r; best_d = gr_d; best_b = gr_b;\n            } else if (choice == 2) {\n                best_r = cand_r; best_d = cand_d; best_b = cand_b;\n            }\n            // choice == 1: already stored\n        }\n        \n        // Output\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++) {\n            cout << i << \" \" << cand_r[i] << \" \" << (cand_d[i] == 0 ? 'U' : 'L') << \" \" << cand_b[i] << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read feedback and update estimates\n        double Wp, Hp;\n        cin >> Wp >> Hp;\n        \n        for (int i = 0; i < N; i++) {\n            double right_edge = x[i] + cw[i];\n            double bottom_edge = y[i] + ch[i];\n            int r = cand_r[i];\n            \n            if (right_edge >= bestW - 1e-6) {\n                double target = max(1.0, Wp - x[i]);\n                if (r) h[i] = (1.0 - LR) * h[i] + LR * target;\n                else w[i] = (1.0 - LR) * w[i] + LR * target;\n            }\n            if (bottom_edge >= bestH - 1e-6) {\n                double target = max(1.0, Hp - y[i]);\n                if (r) w[i] = (1.0 - LR) * w[i] + LR * target;\n                else h[i] = (1.0 - LR) * h[i] + LR * target;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> parent;\n    vector<int> depth;\n    vector<long long> sub_sum;\n    vector<int> height;\n    vector<vector<int>> children;\n    vector<char> attached;\n    \n    void input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; i++) cin >> A[i];\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v; cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        for (int i = 0; i < N; i++) {\n            int x, y; cin >> x >> y;\n        }\n    }\n    \n    // Fast ancestry check - walk up at most H steps (H <= 10)\n    bool is_ancestor_fast(int u, int v) {\n        int steps = 0;\n        while (v != -1 && steps <= H) {\n            if (v == u) return true;\n            v = parent[v];\n            steps++;\n        }\n        return false;\n    }\n    \n    long long compute_score() {\n        long long res = 0;\n        for (int i = 0; i < N; i++) {\n            res += (long long)(depth[i] + 1) * A[i];\n        }\n        return res;\n    }\n    \n    void update_depths_bfs(int root) {\n        queue<int> q;\n        q.push(root);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int c : children[v]) {\n                depth[c] = depth[v] + 1;\n                q.push(c);\n            }\n        }\n    }\n    \n    void update_heights_up(int start) {\n        int x = start;\n        while (x != -1) {\n            int new_h = 0;\n            for (int c : children[x]) {\n                new_h = max(new_h, height[c] + 1);\n            }\n            if (new_h == height[x]) break;\n            height[x] = new_h;\n            x = parent[x];\n        }\n    }\n    \n    void solve_once(mt19937& rng, vector<int>& best_parent, long long& best_score) {\n        parent.assign(N, -1);\n        depth.assign(N, -1);\n        sub_sum.resize(N);\n        height.resize(N);\n        children.assign(N, {});\n        attached.assign(N, 0);\n        \n        for (int i = 0; i < N; i++) {\n            sub_sum[i] = A[i];\n            height[i] = 0;\n        }\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        \n        int attached_count = 0;\n        \n        while (attached_count < N) {\n            long long best_gain = -1;\n            int best_r = -1, best_u = -1;\n            \n            for (int r : order) {\n                if (attached[r]) continue;\n                \n                for (int u : adj[r]) {\n                    if (!attached[u]) continue;\n                    if (depth[u] + 1 + height[r] > H) continue;\n                    \n                    long long gain = (long long)(depth[u] + 1) * sub_sum[r];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_r = r;\n                        best_u = u;\n                    }\n                }\n            }\n            \n            if (best_gain < 0) {\n                for (int v : order) {\n                    if (!attached[v]) {\n                        parent[v] = -1;\n                        depth[v] = 0;\n                        attached[v] = 1;\n                        attached_count++;\n                        break;\n                    }\n                }\n            } else {\n                parent[best_r] = best_u;\n                children[best_u].push_back(best_r);\n                depth[best_r] = depth[best_u] + 1;\n                attached[best_r] = 1;\n                attached_count++;\n                \n                update_depths_bfs(best_r);\n                \n                int x = best_u;\n                while (x != -1) {\n                    sub_sum[x] += sub_sum[best_r];\n                    int new_h = 0;\n                    for (int c : children[x]) {\n                        new_h = max(new_h, height[c] + 1);\n                    }\n                    height[x] = new_h;\n                    x = parent[x];\n                }\n            }\n        }\n        \n        // Local search with steepest ascent\n        for (int iter = 0; iter < 50; iter++) {\n            vector<int> check_order(N);\n            iota(check_order.begin(), check_order.end(), 0);\n            shuffle(check_order.begin(), check_order.end(), rng);\n            \n            long long best_move_gain = 0;\n            int best_v = -1, best_new_parent = -1;\n            int best_old_parent = -1;\n            \n            for (int v : check_order) {\n                if (parent[v] == -1) continue;\n                \n                int cur_p = parent[v];\n                int cur_d = depth[v];\n                long long cur_sub = sub_sum[v];\n                \n                for (int u : adj[v]) {\n                    if (u == cur_p) continue;\n                    if (is_ancestor_fast(v, u)) continue;\n                    \n                    if (depth[u] + 1 <= cur_d) continue;\n                    if (depth[u] + 1 + height[v] > H) continue;\n                    \n                    long long gain = (long long)(depth[u] + 1 - cur_d) * cur_sub;\n                    if (gain > best_move_gain) {\n                        best_move_gain = gain;\n                        best_v = v;\n                        best_new_parent = u;\n                        best_old_parent = cur_p;\n                    }\n                }\n            }\n            \n            if (best_v == -1) break;\n            \n            // Apply move\n            int v = best_v, u = best_new_parent, old_p = best_old_parent;\n            \n            // Detach\n            auto& vec = children[old_p];\n            vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n            update_heights_up(old_p);\n            \n            // Attach\n            parent[v] = u;\n            children[u].push_back(v);\n            depth[v] = depth[u] + 1;\n            update_depths_bfs(v);\n            \n            // Update sub_sum and height\n            long long sub_v = sub_sum[v];\n            int x = u;\n            while (x != -1) {\n                sub_sum[x] += sub_v;\n                int new_h = 0;\n                for (int c : children[x]) {\n                    new_h = max(new_h, height[c] + 1);\n                }\n                height[x] = new_h;\n                x = parent[x];\n            }\n        }\n        \n        long long score = compute_score();\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n    \n    void solve() {\n        input();\n        \n        vector<int> best_parent;\n        long long best_score = -1;\n        \n        for (int attempt = 0; attempt < 5; attempt++) {\n            mt19937 rng(chrono::steady_clock::now().time_since_epoch().count() + attempt * 10007);\n            solve_once(rng, best_parent, best_score);\n        }\n        \n        parent = best_parent;\n        \n        for (int i = 0; i < N; i++) {\n            if (i) cout << \" \";\n            cout << parent[i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    vector<vector<bool>> is_oni;\n    vector<pair<char, int>> ops;\n    int cost;\n};\n\nint N;\nvector<vector<bool>> initial_oni;\nvector<vector<bool>> is_fuku;\nvector<int> max_up, min_down, max_left, min_right;\nvector<vector<array<bool, 4>>> valid_dirs;\n\nState solve(double urgency_weight) {\n    State s;\n    s.is_oni = initial_oni;\n    s.cost = 0;\n    \n    while (true) {\n        vector<vector<int>> num_dirs(N, vector<int>(N, 0));\n        int remaining = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (s.is_oni[i][j]) {\n                    remaining++;\n                    for (int d = 0; d < 4; d++) if (valid_dirs[i][j][d]) num_dirs[i][j]++;\n                }\n            }\n        }\n        if (remaining == 0) break;\n        \n        double best_score = -1e300;\n        int best_gain = 0, best_cost = 0;\n        char best_dir = 0;\n        int best_idx = 0, best_limit = 0;\n        \n        // Up\n        for (int j = 0; j < N; j++) {\n            if (max_up[j] < 0) continue;\n            int highest = -1, count = 0;\n            double urgency = 0;\n            for (int i = 0; i <= max_up[j]; i++) {\n                if (s.is_oni[i][j]) {\n                    count++;\n                    highest = i;\n                    urgency += 1.0 / max(1, num_dirs[i][j]);\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (highest + 1);\n            double eff = (double)count / cost;\n            double score = eff + urgency_weight * urgency / cost;\n            if (score > best_score) {\n                best_score = score;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'U';\n                best_idx = j;\n                best_limit = highest;\n            }\n        }\n        \n        // Down\n        for (int j = 0; j < N; j++) {\n            if (min_down[j] >= N) continue;\n            int lowest = N, count = 0;\n            double urgency = 0;\n            for (int i = min_down[j]; i < N; i++) {\n                if (s.is_oni[i][j]) {\n                    count++;\n                    lowest = i;\n                    urgency += 1.0 / max(1, num_dirs[i][j]);\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - lowest);\n            double eff = (double)count / cost;\n            double score = eff + urgency_weight * urgency / cost;\n            if (score > best_score) {\n                best_score = score;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'D';\n                best_idx = j;\n                best_limit = lowest;\n            }\n        }\n        \n        // Left\n        for (int i = 0; i < N; i++) {\n            if (max_left[i] < 0) continue;\n            int rightmost = -1, count = 0;\n            double urgency = 0;\n            for (int j = 0; j <= max_left[i]; j++) {\n                if (s.is_oni[i][j]) {\n                    count++;\n                    rightmost = j;\n                    urgency += 1.0 / max(1, num_dirs[i][j]);\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (rightmost + 1);\n            double eff = (double)count / cost;\n            double score = eff + urgency_weight * urgency / cost;\n            if (score > best_score) {\n                best_score = score;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'L';\n                best_idx = i;\n                best_limit = rightmost;\n            }\n        }\n        \n        // Right\n        for (int i = 0; i < N; i++) {\n            if (min_right[i] >= N) continue;\n            int leftmost = N, count = 0;\n            double urgency = 0;\n            for (int j = min_right[i]; j < N; j++) {\n                if (s.is_oni[i][j]) {\n                    count++;\n                    leftmost = j;\n                    urgency += 1.0 / max(1, num_dirs[i][j]);\n                }\n            }\n            if (count == 0) continue;\n            int cost = 2 * (N - leftmost);\n            double eff = (double)count / cost;\n            double score = eff + urgency_weight * urgency / cost;\n            if (score > best_score) {\n                best_score = score;\n                best_gain = count;\n                best_cost = cost;\n                best_dir = 'R';\n                best_idx = i;\n                best_limit = leftmost;\n            }\n        }\n        \n        if (best_gain == 0) break;\n        \n        // Apply operation\n        if (best_dir == 'U') {\n            int j = best_idx, h = best_limit;\n            for (int k = 0; k < h + 1; k++) s.ops.emplace_back('U', j);\n            for (int k = 0; k < h + 1; k++) s.ops.emplace_back('D', j);\n            for (int i = 0; i <= h; i++) s.is_oni[i][j] = false;\n            s.cost += 2 * (h + 1);\n        } else if (best_dir == 'D') {\n            int j = best_idx, l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) s.ops.emplace_back('D', j);\n            for (int k = 0; k < times; k++) s.ops.emplace_back('U', j);\n            for (int i = l; i < N; i++) s.is_oni[i][j] = false;\n            s.cost += 2 * times;\n        } else if (best_dir == 'L') {\n            int i = best_idx, r = best_limit;\n            for (int k = 0; k < r + 1; k++) s.ops.emplace_back('L', i);\n            for (int k = 0; k < r + 1; k++) s.ops.emplace_back('R', i);\n            for (int j = 0; j <= r; j++) s.is_oni[i][j] = false;\n            s.cost += 2 * (r + 1);\n        } else if (best_dir == 'R') {\n            int i = best_idx, l = best_limit;\n            int times = N - l;\n            for (int k = 0; k < times; k++) s.ops.emplace_back('R', i);\n            for (int k = 0; k < times; k++) s.ops.emplace_back('L', i);\n            for (int j = l; j < N; j++) s.is_oni[i][j] = false;\n            s.cost += 2 * times;\n        }\n    }\n    \n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    vector<string> C(N);\n    for (int i = 0; i < N; i++) cin >> C[i];\n    \n    initial_oni = vector<vector<bool>>(N, vector<bool>(N, false));\n    is_fuku = vector<vector<bool>>(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (C[i][j] == 'x') initial_oni[i][j] = true;\n            else if (C[i][j] == 'o') is_fuku[i][j] = true;\n        }\n    }\n    \n    // Precompute safe ranges\n    max_up = vector<int>(N, N-1);\n    min_down = vector<int>(N, 0);\n    max_left = vector<int>(N, N-1);\n    min_right = vector<int>(N, 0);\n    \n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) if (is_fuku[i][j]) { max_up[j] = i - 1; break; }\n        for (int i = N - 1; i >= 0; i--) if (is_fuku[i][j]) { min_down[j] = i + 1; break; }\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) if (is_fuku[i][j]) { max_left[i] = j - 1; break; }\n        for (int j = N - 1; j >= 0; j--) if (is_fuku[i][j]) { min_right[i] = j + 1; break; }\n    }\n    \n    valid_dirs = vector<vector<array<bool, 4>>>(N, vector<array<bool, 4>>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            valid_dirs[i][j] = {i <= max_up[j], i >= min_down[j], j <= max_left[i], j >= min_right[i]};\n        }\n    }\n    \n    // Try different urgency weights and pick the best\n    vector<double> weights = {0.0, 0.5, 1.0, 2.0, 5.0};\n    State best_state;\n    best_state.cost = 1e9;\n    \n    for (double w : weights) {\n        State s = solve(w);\n        if (s.cost < best_state.cost) {\n            best_state = std::move(s);\n        }\n    }\n    \n    for (auto &[d, p] : best_state.ops) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const auto START = chrono::steady_clock::now();\n    const int TL_MS = 1990;\n    auto elapsed = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n            chrono::steady_clock::now() - START).count();\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_err = (1LL << 60);\n    \n    auto evaluate = [&](const vector<int>& a, const vector<int>& b, vector<int>& cnt) -> long long {\n        fill(cnt.begin(), cnt.end(), 0);\n        int cur = 0;\n        for (int week = 0; week < L; ++week) {\n            cnt[cur]++;\n            if (week == L - 1) break;\n            cur = (cnt[cur] & 1) ? a[cur] : b[cur];\n        }\n        long long err = 0;\n        for (int i = 0; i < N; ++i) err += llabs((long long)cnt[i] - T[i]);\n        return err;\n    };\n    \n    // Greedy init\n    auto greedy_init = [&](int seed) {\n        mt19937 gen(seed);\n        vector<int> a(N), b(N);\n        vector<long long> rem(N);\n        for (int i = 0; i < N; ++i) rem[i] = T[i];\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), gen);\n        \n        for (int idx : order) {\n            auto get_best = [&]() {\n                long long mx = *max_element(rem.begin(), rem.end());\n                vector<int> cands;\n                for (int j = 0; j < N; ++j) \n                    if (rem[j] == mx) cands.push_back(j);\n                return cands[uniform_int_distribution<int>(0, cands.size()-1)(gen)];\n            };\n            \n            int ja = get_best();\n            a[idx] = ja;\n            rem[ja] -= (T[idx] + 1) / 2;\n            \n            int jb = get_best();\n            b[idx] = jb;\n            rem[jb] -= T[idx] / 2;\n        }\n        return make_pair(a, b);\n    };\n    \n    // Improved flow init with balancing\n    auto flow_init = [&](int seed) {\n        mt19937 gen(seed);\n        vector<int> a(N), b(N);\n        vector<long long> load(N, 0);\n        \n        // Process in order of largest contribution first\n        vector<tuple<int, int, bool>> items; // (weight, from, is_a)\n        for (int i = 0; i < N; ++i) {\n            items.push_back({(T[i] + 1) / 2, i, true});\n            items.push_back({T[i] / 2, i, false});\n        }\n        sort(items.rbegin(), items.rend());\n        \n        // Shuffle items with equal weight\n        for (int i = 0; i < (int)items.size(); ) {\n            int j = i;\n            while (j < (int)items.size() && get<0>(items[j]) == get<0>(items[i])) j++;\n            shuffle(items.begin() + i, items.begin() + j, gen);\n            i = j;\n        }\n        \n        for (auto& [w, from, is_a] : items) {\n            // Find node with largest deficit, with some randomness for ties\n            vector<pair<long long, int>> deficits;\n            for (int j = 0; j < N; ++j) {\n                deficits.push_back({(long long)T[j] - load[j], j});\n            }\n            sort(deficits.rbegin(), deficits.rend());\n            \n            // Pick from top 3 with preference for larger deficit\n            int pick = 0;\n            if (deficits.size() >= 3 && uniform_int_distribution<int>(0, 2)(gen) > 0) {\n                pick = uniform_int_distribution<int>(0, min(2, (int)deficits.size()-1))(gen);\n            }\n            int to = deficits[pick].second;\n            \n            if (is_a) a[from] = to;\n            else b[from] = to;\n            load[to] += w;\n        }\n        return make_pair(a, b);\n    };\n    \n    // Hill climbing with simulated annealing option\n    auto local_search = [&](vector<int> a, vector<int> b, int seed, int deadline, bool use_sa) {\n        mt19937 gen(seed);\n        vector<int> cnt(N);\n        long long cur = evaluate(a, b, cnt);\n        \n        auto upd_best = [&]() {\n            if (cur < best_err) {\n                best_err = cur;\n                best_a = a;\n                best_b = b;\n            }\n        };\n        upd_best();\n        \n        double temp = max(cur / 30.0, 50.0);\n        const double cooling = 0.99995;\n        int iter = 0, last_improve = 0;\n        \n        while (elapsed() < deadline) {\n            ++iter;\n            \n            // Restart if stuck\n            if (!use_sa && iter - last_improve > 4000) {\n                a = best_a;\n                b = best_b;\n                cur = evaluate(a, b, cnt);\n                // Perturb\n                for (int k = 0; k < 2 + iter/10000; ++k) {\n                    int i = uniform_int_distribution<int>(0, N-1)(gen);\n                    if (uniform_int_distribution<int>(0, 1)(gen) == 0)\n                        a[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                    else\n                        b[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                }\n                cur = evaluate(a, b, cnt);\n                last_improve = iter;\n                continue;\n            }\n            \n            vector<int> na = a, nb = b;\n            \n            // Compute errors\n            vector<pair<int, long long>> errs;\n            for (int i = 0; i < N; ++i)\n                errs.push_back({i, llabs((long long)cnt[i] - T[i])});\n            sort(errs.begin(), errs.end(),\n                 [](auto& x, auto& y) { return x.second > y.second; });\n            \n            int move_type = uniform_int_distribution<int>(0, 99)(gen);\n            \n            if (move_type < 45) {\n                // Random single change\n                int i = uniform_int_distribution<int>(0, N-1)(gen);\n                int t = uniform_int_distribution<int>(0, 2)(gen);\n                if (t == 0) na[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else if (t == 1) nb[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else swap(na[i], nb[i]);\n            } else if (move_type < 70) {\n                // Swap\n                int i = errs[uniform_int_distribution<int>(0, min(4, N-1))(gen)].first;\n                int j = uniform_int_distribution<int>(0, N-1)(gen);\n                int t = uniform_int_distribution<int>(0, 3)(gen);\n                if (t == 0) swap(na[i], na[j]);\n                else if (t == 1) swap(nb[i], nb[j]);\n                else if (t == 2) swap(na[i], nb[j]);\n                else swap(nb[i], na[j]);\n            } else {\n                // Targeted\n                int worst = errs[0].first;\n                long long diff = (long long)cnt[worst] - T[worst];\n                \n                if (diff > 0) {\n                    vector<pair<int, bool>> inc;\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] == worst) inc.push_back({i, true});\n                        if (b[i] == worst) inc.push_back({i, false});\n                    }\n                    if (!inc.empty()) {\n                        auto [from, is_a] = inc[uniform_int_distribution<int>(0, inc.size()-1)(gen)];\n                        int to = errs[uniform_int_distribution<int>(0, min(4, N-1))(gen)].first;\n                        if (cnt[to] >= T[to]) to = uniform_int_distribution<int>(0, N-1)(gen);\n                        if (is_a) na[from] = to;\n                        else nb[from] = to;\n                    }\n                } else if (diff < 0) {\n                    vector<pair<int, bool>> non_inc;\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] != worst) non_inc.push_back({i, true});\n                        if (b[i] != worst) non_inc.push_back({i, false});\n                    }\n                    if (!non_inc.empty()) {\n                        auto [from, is_a] = non_inc[uniform_int_distribution<int>(0, non_inc.size()-1)(gen)];\n                        if (is_a) na[from] = worst;\n                        else nb[from] = worst;\n                    }\n                } else {\n                    int i = uniform_int_distribution<int>(0, N-1)(gen);\n                    swap(na[i], nb[i]);\n                }\n            }\n            \n            vector<int> ncnt(N);\n            long long nerr = evaluate(na, nb, ncnt);\n            \n            bool accept = false;\n            if (nerr < cur) {\n                accept = true;\n            } else if (use_sa) {\n                double prob = exp((cur - nerr) / temp);\n                if (uniform_real_distribution<double>(0, 1)(gen) < prob) accept = true;\n            }\n            \n            if (accept) {\n                if (nerr < cur) last_improve = iter;\n                a = na; b = nb; cur = nerr; cnt = ncnt;\n                upd_best();\n            }\n            \n            if (use_sa) temp = max(0.001, temp * cooling);\n        }\n    };\n    \n    // Main execution\n    vector<int> seeds = {42, 123, 456, 789, 1011, 1213, 1415, 1617, 1819, 2021, 2223, 2425, 2627, 2829};\n    \n    // Phase 1: Greedy with hill climbing\n    for (int s : seeds) {\n        if (elapsed() > TL_MS * 0.6) break;\n        auto [a, b] = greedy_init(s);\n        local_search(a, b, s, elapsed() + 100, false);\n    }\n    \n    // Phase 2: Flow with hill climbing\n    for (int s : seeds) {\n        if (elapsed() > TL_MS * 0.75) break;\n        auto [a, b] = flow_init(s);\n        local_search(a, b, s + 500, elapsed() + 80, false);\n    }\n    \n    // Phase 3: SA refinement from best\n    while (elapsed() < TL_MS - 100) {\n        auto a = best_a, b = best_b;\n        mt19937 pgen(99999 + elapsed());\n        // Moderate perturbation\n        for (int i = 0; i < N/12; ++i) {\n            int idx = uniform_int_distribution<int>(0, N-1)(pgen);\n            if (uniform_int_distribution<int>(0, 1)(pgen) == 0)\n                a[idx] = uniform_int_distribution<int>(0, N-1)(pgen);\n            else\n                b[idx] = uniform_int_distribution<int>(0, N-1)(pgen);\n        }\n        int end_time = min(TL_MS - 10, (int)(elapsed() + 120));\n        local_search(a, b, 88888 + elapsed(), end_time, true);\n    }\n    \n    // Final hill climbing cleanup\n    if (elapsed() < TL_MS) {\n        local_search(best_a, best_b, 77777, TL_MS, false);\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Hilbert curve order for spatial locality\nlong long hilbertOrder(int x, int y, int pow = 16, int rot = 0) {\n    if (pow == 0) return 0;\n    int h = 1 << (pow - 1);\n    int seg = (x < h ? (y < h ? 0 : 3) : (y < h ? 1 : 2));\n    seg = (seg + rot) & 3;\n    static const int rotateDelta[4] = {3, 0, 0, 1};\n    int nx = x & (h - 1), ny = y & (h - 1);\n    int nrot = (rot + rotateDelta[seg]) & 3;\n    long long subSquareSize = 1LL << (2 * pow - 2);\n    long long ord = seg * subSquareSize;\n    long long add = hilbertOrder(nx, ny, pow - 1, nrot);\n    ord += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);\n    return ord;\n}\n\n// DSU for Kruskal\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n) { p.resize(n); r.resize(n); iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Estimated centers\n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n    \n    // Recursive bisection for grouping\n    vector<vector<int>> groups(M);\n    function<void(vector<int>&, int, int, int)> partition = [&](vector<int>& ids, int gl, int gr, int depth) {\n        if (gl + 1 == gr) {\n            for (int id : ids) groups[gl].push_back(id);\n            return;\n        }\n        int gmid = (gl + gr) / 2;\n        int leftSize = 0;\n        for (int i = gl; i < gmid; ++i) leftSize += G[i];\n        \n        if (depth % 2 == 0) {\n            sort(ids.begin(), ids.end(), [&](int a, int b) { return cx[a] < cx[b]; });\n        } else {\n            sort(ids.begin(), ids.end(), [&](int a, int b) { return cy[a] < cy[b]; });\n        }\n        \n        vector<int> left(ids.begin(), ids.begin() + leftSize);\n        vector<int> right(ids.begin() + leftSize, ids.end());\n        partition(left, gl, gmid, depth + 1);\n        partition(right, gmid, gr, depth + 1);\n    };\n    \n    vector<int> allIds(N);\n    iota(allIds.begin(), allIds.end(), 0);\n    partition(allIds, 0, M, 0);\n    \n    // Collect all candidate edges\n    vector<tuple<long long, int, int>> candidateEdges; // (estimatedDist, u, v)\n    // Map to avoid duplicates\n    set<pair<int, int>> edgeSet;\n    \n    int queriesUsed = 0;\n    \n    auto addEdge = [&](int u, int v) {\n        if (u > v) swap(u, v);\n        if (edgeSet.count({u, v})) return;\n        edgeSet.insert({u, v});\n        long long dx = cx[u] - cx[v];\n        long long dy = cy[u] - cy[v];\n        long long d2 = dx * dx + dy * dy;\n        candidateEdges.push_back({d2, u, v});\n    };\n    \n    // Phase 1: Backbone with Hilbert sliding window (ensures connectivity)\n    for (int gi = 0; gi < M && queriesUsed < Q; ++gi) {\n        auto &grp = groups[gi];\n        int gsize = grp.size();\n        if (gsize <= 1) continue;\n        \n        sort(grp.begin(), grp.end(), [&](int a, int b) {\n            return hilbertOrder(cx[a], cy[a]) < hilbertOrder(cx[b], cy[b]);\n        });\n        \n        for (int i = 0; i < gsize - 1 && queriesUsed < Q; i += L - 1) {\n            int batchSize = min(L, gsize - i);\n            vector<int> querySet;\n            for (int j = 0; j < batchSize; ++j) querySet.push_back(grp[i + j]);\n            \n            cout << \"? \" << batchSize;\n            for (int v : querySet) cout << ' ' << v;\n            cout << '\\n';\n            cout.flush();\n            ++queriesUsed;\n            \n            for (int j = 0; j < batchSize - 1; ++j) {\n                int a, b; cin >> a >> b;\n                addEdge(a, b);\n            }\n        }\n    }\n    \n    // Phase 2: Local neighborhood queries (improve edge quality)\n    // For each city, query with its L-1 nearest neighbors\n    // Prioritize cities in larger groups or with fewer edges so far\n    vector<pair<int, int>> cityPriority; // (groupSize, city)\n    for (int gi = 0; gi < M; ++gi) {\n        for (int v : groups[gi]) {\n            cityPriority.push_back({-(int)groups[gi].size(), v}); // negative for larger first\n        }\n    }\n    sort(cityPriority.begin(), cityPriority.end());\n    \n    for (auto &[gsize, v] : cityPriority) {\n        if (queriesUsed >= Q) break;\n        \n        // Find L-1 nearest neighbors in the same group\n        int gi = -1;\n        for (int i = 0; i < M; ++i) {\n            if (find(groups[i].begin(), groups[i].end(), v) != groups[i].end()) {\n                gi = i; break;\n            }\n        }\n        if (gi == -1) continue;\n        \n        auto &grp = groups[gi];\n        vector<pair<long long, int>> neighbors;\n        for (int u : grp) {\n            if (u == v) continue;\n            long long dx = cx[u] - cx[v];\n            long long dy = cy[u] - cy[v];\n            neighbors.push_back({dx*dx + dy*dy, u});\n        }\n        sort(neighbors.begin(), neighbors.end());\n        \n        int k = min(L - 1, (int)neighbors.size());\n        if (k < 1) continue;\n        \n        vector<int> querySet = {v};\n        for (int i = 0; i < k; ++i) querySet.push_back(neighbors[i].second);\n        \n        cout << \"? \" << (int)querySet.size();\n        for (int x : querySet) cout << ' ' << x;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < (int)querySet.size() - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Phase 3: If queries remain, do random local queries within groups\n    mt19937 rng(12345);\n    while (queriesUsed < Q) {\n        // Pick a random group\n        int gi = rng() % M;\n        if (groups[gi].size() < 2) continue;\n        \n        // Pick L random cities from this group\n        vector<int> pool = groups[gi];\n        shuffle(pool.begin(), pool.end(), rng);\n        int sz = min(L, (int)pool.size());\n        vector<int> querySet(pool.begin(), pool.begin() + sz);\n        \n        cout << \"? \" << sz;\n        for (int v : querySet) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < sz - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Build MST using Kruskal on collected edges\n    sort(candidateEdges.begin(), candidateEdges.end());\n    DSU dsu(N);\n    vector<vector<pair<int,int>>> groupEdges(M);\n    vector<int> groupOf(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int v : groups[i]) groupOf[v] = i;\n    }\n    \n    for (auto &[d2, u, v] : candidateEdges) {\n        if (dsu.find(u) != dsu.find(v)) {\n            dsu.unite(u, v);\n            int gi = groupOf[u];\n            groupEdges[gi].push_back({u, v});\n        }\n    }\n    \n    // Output\n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << ' ';\n            cout << grp[i];\n        }\n        cout << '\\n';\n        for (auto [a, b] : groupEdges[gi]) {\n            cout << a << ' ' << b << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.emplace_back(r, c);\n    }\n    \n    vector<pair<char,char>> ans;\n    auto add_move = [&](char d, int cnt) {\n        for (int i = 0; i < cnt; i++) ans.emplace_back('M', d);\n    };\n    auto add_slide = [&](char d) {\n        ans.emplace_back('S', d);\n    };\n    \n    int cr = r0, cc = c0;\n    const int MAXC = N - 1; // 19\n    \n    for (auto [tr, tc] : targets) {\n        int dr = tr - cr;\n        int dc = tc - cc;\n        int abs_dr = abs(dr);\n        int abs_dc = abs(dc);\n        \n        // Direct Manhattan\n        int best_cost = abs_dr + abs_dc;\n        int strategy = 0; // 0=direct, 1=top, 2=bot, 3=left, 4=right, 5=corner\n        \n        // Via Top: slide up to row 0, walk horiz, walk down to tr\n        int cost_top = 1 + abs_dc + tr;\n        if (cost_top < best_cost) {\n            best_cost = cost_top;\n            strategy = 1;\n        }\n        \n        // Via Bottom: slide down to row 19, walk horiz, walk up to tr\n        int cost_bot = 1 + abs_dc + (MAXC - tr);\n        if (cost_bot < best_cost) {\n            best_cost = cost_bot;\n            strategy = 2;\n        }\n        \n        // Via Left: slide left to col 0, walk vert, walk right to tc\n        int cost_left = 1 + abs_dr + tc;\n        if (cost_left < best_cost) {\n            best_cost = cost_left;\n            strategy = 3;\n        }\n        \n        // Via Right: slide right to col 19, walk vert, walk left to tc\n        int cost_right = 1 + abs_dr + (MAXC - tc);\n        if (cost_right < best_cost) {\n            best_cost = cost_right;\n            strategy = 4;\n        }\n        \n        // Via Corner: 2 slides to a corner, then walk\n        int dist_from_corner = min(tr, MAXC - tr) + min(tc, MAXC - tc);\n        int cost_corner = 2 + dist_from_corner;\n        if (cost_corner < best_cost) {\n            best_cost = cost_corner;\n            strategy = 5;\n        }\n        \n        if (strategy == 0) {\n            // Direct: move vertical then horizontal (order doesn't matter)\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n        } else if (strategy == 1) {\n            // Via top\n            add_slide('U');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('D', tr); // down from row 0 to tr\n        } else if (strategy == 2) {\n            // Via bottom\n            add_slide('D');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('U', MAXC - tr); // up from row 19 to tr\n        } else if (strategy == 3) {\n            // Via left\n            add_slide('L');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('R', tc); // right from col 0 to tc\n        } else if (strategy == 4) {\n            // Via right\n            add_slide('R');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('L', MAXC - tc); // left from col 19 to tc\n        } else if (strategy == 5) {\n            // Via best corner\n            // Determine which corner is best (gives min walking distance)\n            int best_corner = 0; // 0:TL, 1:TR, 2:BL, 3:BR\n            int best_corner_cost = 1000;\n            // TL (0,0): walk down tr, right tc. Cost: tr + tc\n            if (tr + tc < best_corner_cost) { best_corner_cost = tr + tc; best_corner = 0; }\n            // TR (0,19): down tr, left (19-tc)\n            if (tr + (MAXC - tc) < best_corner_cost) { best_corner_cost = tr + (MAXC - tc); best_corner = 1; }\n            // BL (19,0): up (19-tr), right tc\n            if ((MAXC - tr) + tc < best_corner_cost) { best_corner_cost = (MAXC - tr) + tc; best_corner = 2; }\n            // BR (19,19): up (19-tr), left (19-tc)\n            if ((MAXC - tr) + (MAXC - tc) < best_corner_cost) { best_corner_cost = (MAXC - tr) + (MAXC - tc); best_corner = 3; }\n            \n            if (best_corner == 0) {\n                add_slide('U');\n                add_slide('L');\n                add_move('D', tr);\n                add_move('R', tc);\n            } else if (best_corner == 1) {\n                add_slide('U');\n                add_slide('R');\n                add_move('D', tr);\n                add_move('L', MAXC - tc);\n            } else if (best_corner == 2) {\n                add_slide('D');\n                add_slide('L');\n                add_move('U', MAXC - tr);\n                add_move('R', tc);\n            } else {\n                add_slide('D');\n                add_slide('R');\n                add_move('U', MAXC - tr);\n                add_move('L', MAXC - tc);\n            }\n        }\n        \n        cr = tr;\n        cc = tc;\n    }\n    \n    for (auto [a, d] : ans) {\n        cout << a << ' ' << d << \"\\n\";\n    }\n    \n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int l, r, b, t;\n    long long area() const { return 1LL * (r - l) * (t - b); }\n    bool contains(int x, int y) const { return l <= x && x < r && b <= y && y < t; }\n};\n\nint n;\nvector<int> X, Y, R;\nvector<Rect> best_rects;\ndouble best_score = -1.0;\n\n/* ---------- Guillotine Tree ---------- */\nstruct Node {\n    bool leaf = false;\n    int idx = -1;\n    bool vert = false;\n    int child[2] = {-1, -1};\n    int cut = 0;\n    int min_x = 10000, max_x = -1;\n    int min_y = 10000, max_y = -1;\n    long long sum_r = 0;\n};\n\nvector<Node> tree;\nvector<int> cur_x1, cur_y1, cur_x2, cur_y2;\n\nint build(vector<int>& ids, mt19937& rng) {\n    Node node;\n    for (int id : ids) {\n        node.min_x = min(node.min_x, X[id]);\n        node.max_x = max(node.max_x, X[id]);\n        node.min_y = min(node.min_y, Y[id]);\n        node.max_y = max(node.max_y, Y[id]);\n        node.sum_r += R[id];\n    }\n    if ((int)ids.size() == 1) {\n        node.leaf = true;\n        node.idx = ids[0];\n        int id = (int)tree.size();\n        tree.push_back(node);\n        return id;\n    }\n    int dx = node.max_x - node.min_x;\n    int dy = node.max_y - node.min_y;\n    bool vert = (dx >= dy);\n    if (abs(dx - dy) < 2000) vert = (rng() & 1);\n\n    if (vert) sort(ids.begin(), ids.end(), [&](int a, int b){ return X[a] < X[b]; });\n    else      sort(ids.begin(), ids.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n    long long half = node.sum_r / 2;\n    long long cur = 0;\n    int split_pos = 1;\n    for (int i = 0; i < (int)ids.size(); ++i) {\n        cur += R[ids[i]];\n        if (cur >= half && i + 1 < (int)ids.size()) {\n            split_pos = i + 1;\n            break;\n        }\n    }\n    vector<int> left(ids.begin(), ids.begin() + split_pos);\n    vector<int> right(ids.begin() + split_pos, ids.end());\n\n    node.vert = vert;\n    int nid = (int)tree.size();\n    tree.push_back(node);\n    int lch = build(left, rng);\n    int rch = build(right, rng);\n    tree[nid].child[0] = lch;\n    tree[nid].child[1] = rch;\n    return nid;\n}\n\ndouble recalc(int v, int x1, int y1, int x2, int y2, vector<Rect>& rects) {\n    cur_x1[v] = x1; cur_y1[v] = y1; cur_x2[v] = x2; cur_y2[v] = y2;\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        long long s = rects[node.idx].area();\n        long long r = R[node.idx];\n        double ratio = (s <= r) ? (double)s / r : (double)r / s;\n        double d = 1.0 - ratio;\n        return 1.0 - d * d;\n    }\n    double sum = 0.0;\n    if (node.vert) {\n        sum += recalc(node.child[0], x1, y1, node.cut, y2, rects);\n        sum += recalc(node.child[1], node.cut, y1, x2, y2, rects);\n    } else {\n        sum += recalc(node.child[0], x1, y1, x2, node.cut, rects);\n        sum += recalc(node.child[1], x1, node.cut, x2, y2, rects);\n    }\n    return sum;\n}\n\nvoid init_cuts(int v, int x1, int y1, int x2, int y2, vector<Rect>& rects) {\n    Node& node = tree[v];\n    if (node.leaf) {\n        rects[node.idx] = {x1, x2, y1, y2};\n        return;\n    }\n    int lch = node.child[0], rch = node.child[1];\n    if (node.vert) {\n        int lo = max(x1, tree[lch].max_x + 1);\n        int hi = min(x2, tree[rch].min_x);\n        if (lo > hi) lo = hi = (x1 + x2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(x1 + (x2 - x1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, node.cut, y2, rects);\n        init_cuts(rch, node.cut, y1, x2, y2, rects);\n    } else {\n        int lo = max(y1, tree[lch].max_y + 1);\n        int hi = min(y2, tree[rch].min_y);\n        if (lo > hi) lo = hi = (y1 + y2) / 2;\n        double ratio = (double)tree[lch].sum_r / node.sum_r;\n        int ideal = (int)(y1 + (y2 - y1) * ratio);\n        node.cut = clamp(ideal, lo, hi);\n        init_cuts(lch, x1, y1, x2, node.cut, rects);\n        init_cuts(rch, x1, node.cut, x2, y2, rects);\n    }\n}\n\n/* ---------- Guillotine SA ---------- */\nvoid solve_guillotine(mt19937& rng, double time_limit, vector<Rect>& out_rects, double& out_score) {\n    tree.clear();\n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    int root = build(ids, rng);\n\n    vector<Rect> rects(n);\n    init_cuts(root, 0, 0, 10000, 10000, rects);\n    cur_x1.assign(tree.size(), 0);\n    cur_y1.assign(tree.size(), 0);\n    cur_x2.assign(tree.size(), 0);\n    cur_y2.assign(tree.size(), 0);\n\n    double cur_score = recalc(root, 0, 0, 10000, 10000, rects);\n    vector<Rect> local_best = rects;\n    double local_best_score = cur_score;\n\n    vector<int> inodes;\n    for (int i = 0; i < (int)tree.size(); ++i) if (!tree[i].leaf) inodes.push_back(i);\n    if (inodes.empty()) {\n        out_rects = local_best;\n        out_score = local_best_score;\n        return;\n    }\n\n    uniform_int_distribution<int> pick_node(0, (int)inodes.size() - 1);\n    uniform_real_distribution<double> uni(0.0, 1.0);\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n\n        double progress = elapsed / time_limit;\n        double T = pow(0.0001, progress);\n\n        int v = inodes[pick_node(rng)];\n        Node& node = tree[v];\n        int x1 = cur_x1[v], y1 = cur_y1[v], x2 = cur_x2[v], y2 = cur_y2[v];\n        int lo, hi;\n        if (node.vert) {\n            lo = max(x1, tree[node.child[0]].max_x + 1);\n            hi = min(x2, tree[node.child[1]].min_x);\n        } else {\n            lo = max(y1, tree[node.child[0]].max_y + 1);\n            hi = min(y2, tree[node.child[1]].min_y);\n        }\n        if (lo >= hi) continue;\n\n        int old = node.cut;\n        int proposal;\n        if (uni(rng) < 0.5) {\n            int range = hi - lo;\n            int max_step = max(1, (int)(range * T * 0.1));\n            uniform_int_distribution<int> d(-max_step, max_step);\n            proposal = old + d(rng);\n        } else {\n            uniform_int_distribution<int> d(lo, hi);\n            proposal = d(rng);\n        }\n        proposal = clamp(proposal, lo, hi);\n        if (proposal == old) continue;\n\n        node.cut = proposal;\n        double new_score = recalc(root, 0, 0, 10000, 10000, rects);\n        double delta = new_score - cur_score;\n\n        if (delta > 0.0 || exp(delta / T) > uni(rng)) {\n            cur_score = new_score;\n            if (cur_score > local_best_score) {\n                local_best_score = cur_score;\n                local_best = rects;\n            }\n        } else {\n            node.cut = old;\n            recalc(root, 0, 0, 10000, 10000, rects);\n        }\n    }\n    out_rects = local_best;\n    out_score = local_best_score;\n}\n\n/* ---------- Edge-Based Polish ---------- */\ninline bool valid_move(const vector<Rect>& rects, int i, const Rect& nr) {\n    if (nr.l >= nr.r || nr.b >= nr.t) return false;\n    if (nr.l < 0 || nr.r > 10000 || nr.b < 0 || nr.t > 10000) return false;\n    if (!nr.contains(X[i], Y[i])) return false;\n    for (int j = 0; j < n; ++j) if (j != i) {\n        const Rect& o = rects[j];\n        if (max(nr.l, o.l) < min(nr.r, o.r) && max(nr.b, o.b) < min(nr.t, o.t))\n            return false;\n    }\n    return true;\n}\n\ninline double score_rect_fast(int i, long long area) {\n    long long r = R[i];\n    double ratio = (area <= r) ? (double)area / r : (double)r / area;\n    double d = 1.0 - ratio;\n    return 1.0 - d * d;\n}\n\n/* Tournament selection: pick worst of k */\nint pick_worst(const vector<Rect>& rects, mt19937& rng, int k = 5) {\n    uniform_int_distribution<int> pick(0, n - 1);\n    int worst_idx = pick(rng);\n    double worst_sc = score_rect_fast(worst_idx, rects[worst_idx].area());\n    for (int i = 1; i < k; ++i) {\n        int idx = pick(rng);\n        double sc = score_rect_fast(idx, rects[idx].area());\n        if (sc < worst_sc) {\n            worst_sc = sc;\n            worst_idx = idx;\n        }\n    }\n    return worst_idx;\n}\n\nvoid polish(mt19937& rng, double time_limit, vector<Rect>& rects, double& cur_score) {\n    uniform_int_distribution<int> pick_side(0, 3);\n    uniform_int_distribution<int> pick_dir(0, 1);\n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    auto start = chrono::steady_clock::now();\n    long long iter = 0;\n\n    while (true) {\n        ++iter;\n        if ((iter & 255) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > time_limit) break;\n        }\n\n        auto now = chrono::steady_clock::now();\n        double progress = chrono::duration<double>(now - start).count() / time_limit;\n        if (progress > 1.0) break;\n        double T = 0.02 * max(0.0, 1.0 - progress);\n\n        int i = pick_worst(rects, rng, 5); // k=5 proven optimal\n        double cur_sat = score_rect_fast(i, rects[i].area());\n        \n        int max_step;\n        if (cur_sat < 0.7) max_step = 15;\n        else max_step = max(1, (int)(5 * (1.0 - progress)));\n        \n        int side = pick_side(rng);\n        int delta = (pick_dir(rng) == 0) ? max_step : -max_step;\n\n        Rect nr = rects[i];\n        if (side == 0) nr.l += delta;\n        else if (side == 1) nr.r += delta;\n        else if (side == 2) nr.b += delta;\n        else nr.t += delta;\n\n        if (!valid_move(rects, i, nr)) continue;\n\n        double old_s = cur_sat;\n        double new_s = score_rect_fast(i, nr.area());\n        double delta_sc = new_s - old_s;\n\n        if (delta_sc > 0 || (T > 1e-9 && exp(delta_sc / T) > uni(rng))) {\n            cur_score += delta_sc;\n            rects[i] = nr;\n        }\n    }\n}\n\n/* ---------- Greedy Hill Climb (Time Bounded) ---------- */\nvoid greedy_hill_climb(vector<Rect>& rects, double& cur_score, double time_limit) {\n    bool improved = true;\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    mt19937 rng_local(12345);\n    \n    auto start = chrono::steady_clock::now();\n    int checks = 0;\n    \n    while (improved) {\n        improved = false;\n        shuffle(order.begin(), order.end(), rng_local);\n        \n        for (int i : order) {\n            if ((++checks & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start).count() > time_limit) return;\n            }\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                Rect nr = rects[i];\n                if (dir == 0) nr.l -= 1;\n                else if (dir == 1) nr.r += 1;\n                else if (dir == 2) nr.b -= 1;\n                else nr.t += 1;\n                \n                if (!valid_move(rects, i, nr)) continue;\n                \n                double old_s = score_rect_fast(i, rects[i].area());\n                double new_s = score_rect_fast(i, nr.area());\n                if (new_s > old_s + 1e-12) {\n                    cur_score += (new_s - old_s);\n                    rects[i] = nr;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n    }\n}\n\n/* ---------- Main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    const double TOTAL_TL = 4.90;\n    const int ATTEMPTS = 5;\n    const double T_GUILL = 0.76;       \n    const double T_POLISH_SHORT = 0.05; \n    const double T_POLISH_FINAL = 0.65; \n    const double T_GREEDY = 0.03;      // restored greedy phase\n\n    for (int att = 0; att < ATTEMPTS; ++att) {\n        uint64_t seed = 1234567ULL + att * 999983ULL +\n                        chrono::steady_clock::now().time_since_epoch().count();\n        mt19937 rng((unsigned)seed);\n        \n        vector<Rect> rects;\n        double score;\n        solve_guillotine(rng, T_GUILL, rects, score);\n        polish(rng, T_POLISH_SHORT, rects, score);\n        \n        if (score > best_score) {\n            best_score = score;\n            best_rects = rects;\n        }\n    }\n\n    if (!best_rects.empty()) {\n        uint64_t seed = 7777777ULL + chrono::steady_clock::now().time_since_epoch().count();\n        mt19937 rng((unsigned)seed);\n        polish(rng, T_POLISH_FINAL, best_rects, best_score);\n        greedy_hill_climb(best_rects, best_score, T_GREEDY);\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << best_rects[i].l << ' ' << best_rects[i].b << ' '\n             << best_rects[i].r << ' ' << best_rects[i].t << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 50;\nconstexpr int W = 50;\n\nstruct Solver {\n    static constexpr int DI[4] = {-1, 1, 0, 0};\n    static constexpr int DJ[4] = {0, 0, -1, 1};\n    static constexpr char DC[4] = {'U', 'D', 'L', 'R'};\n    \n    int si, sj;\n    vector<vector<int>> tile;\n    vector<vector<int>> val;\n    int M;\n    \n    uint32_t rng_seed = 123456789;\n    uint32_t rand_u32() {\n        rng_seed ^= rng_seed << 13;\n        rng_seed ^= rng_seed >> 17;\n        rng_seed ^= rng_seed << 5;\n        return rng_seed;\n    }\n    double rand_double() {\n        return (double)rand_u32() / UINT32_MAX;\n    }\n    \n    long long evaluate_path(const string& path) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        long long score = val[i][j];\n        \n        for (char c : path) {\n            int d = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n            int ni = i + DI[d];\n            int nj = j + DJ[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) return -1;\n            int nt = tile[ni][nj];\n            if (vis[nt]) return -1;\n            i = ni; j = nj;\n            vis[nt] = 1;\n            score += val[i][j];\n        }\n        return score;\n    }\n    \n    // Calculate degree of a cell given visited set\n    int get_degree(int i, int j, const vector<char>& vis) {\n        int deg = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + DI[d];\n            int nj = j + DJ[d];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n            if (!vis[tile[ni][nj]]) deg++;\n        }\n        return deg;\n    }\n    \n    string greedy_walk(double w_val, double w_deg, double dead_penalty, \n                       double w_future, bool use_random_tiebreak, int forced_first_dir = -1) {\n        vector<char> vis(M, 0);\n        int i = si, j = sj;\n        vis[tile[i][j]] = 1;\n        string path;\n        path.reserve(M);\n        int steps = 0;\n        \n        while (true) {\n            struct Cand {\n                double score;\n                int dir;\n                int ni, nj;\n                int deg;\n                bool is_leaf;\n            };\n            vector<Cand> cands;\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + DI[d];\n                int nj = j + DJ[d];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n                int nt = tile[ni][nj];\n                if (vis[nt]) continue;\n                \n                // Calculate degree after visiting this tile\n                int deg = 0;\n                int max_next_val = 0;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int ni2 = ni + DI[d2];\n                    int nj2 = nj + DJ[d2];\n                    if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                    int nt2 = tile[ni2][nj2];\n                    if (nt2 == nt) continue;\n                    if (!vis[nt2]) {\n                        deg++;\n                        max_next_val = max(max_next_val, val[ni2][nj2]);\n                    }\n                }\n                \n                bool is_leaf = (deg == 0);\n                \n                // Depth-2 lookahead: find best 2-step continuation\n                double future_val = 0;\n                if (!is_leaf) {\n                    vis[nt] = 1;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int ni2 = ni + DI[d2];\n                        int nj2 = nj + DJ[d2];\n                        if (ni2 < 0 || ni2 >= H || nj2 < 0 || nj2 >= W) continue;\n                        int nt2 = tile[ni2][nj2];\n                        if (nt2 == nt) continue;\n                        if (vis[nt2]) continue;\n                        \n                        double val2 = val[ni2][nj2];\n                        // Look one step further\n                        int max_next2 = 0;\n                        vis[nt2] = 1;\n                        for (int d3 = 0; d3 < 4; ++d3) {\n                            int ni3 = ni2 + DI[d3];\n                            int nj3 = nj2 + DJ[d3];\n                            if (ni3 < 0 || ni3 >= H || nj3 < 0 || nj3 >= W) continue;\n                            int nt3 = tile[ni3][nj3];\n                            if (nt3 == nt || nt3 == nt2) continue;\n                            if (!vis[nt3]) max_next2 = max(max_next2, val[ni3][nj3]);\n                        }\n                        vis[nt2] = 0;\n                        val2 += 0.5 * max_next2;\n                        future_val = max(future_val, val2);\n                    }\n                    vis[nt] = 0;\n                }\n                \n                double base_score = val[ni][nj] * w_val;\n                \n                // Adaptive phase: early = connectivity, late = value\n                double phase = min(1.0, steps / 150.0);\n                base_score += deg * w_deg * (1.0 - phase * 0.7);\n                \n                if (is_leaf) {\n                    base_score -= dead_penalty;\n                }\n                \n                base_score += future_val * w_future;\n                \n                // Critical: if this is a leaf neighbor (deg == 0 after visiting), \n                // and it's not the only option, we might want to penalize heavily\n                // unless it has high value\n                \n                if (use_random_tiebreak) {\n                    base_score += rand_double() * 0.3;\n                }\n                \n                cands.push_back({base_score, d, ni, nj, deg, is_leaf});\n            }\n            \n            if (cands.empty()) break;\n            \n            // Forced first direction\n            if (forced_first_dir >= 0 && steps == 0) {\n                bool found = false;\n                for (auto& c : cands) {\n                    if (c.dir == forced_first_dir) {\n                        cands = {c};\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n            \n            // If there are leaves (dead ends) available, prioritize them only if decent value\n            // Actually, we should visit leaves with ANY value to avoid losing them forever\n            // But only if we can return (if current pos has degree > 1) or if it's the only way\n            \n            auto best = *max_element(cands.begin(), cands.end(),\n                [](const Cand& a, const Cand& b) { return a.score < b.score; });\n            \n            i = best.ni;\n            j = best.nj;\n            vis[tile[i][j]] = 1;\n            path.push_back(DC[best.dir]);\n            steps++;\n        }\n        return path;\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Phase 1: All 4 initial directions with conservative parameters\n        for (int d = 0; d < 4; ++d) {\n            string p = greedy_walk(1.0, 50.0, 20000.0, 0.8, false, d);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 2: Deterministic presets\n        vector<tuple<double, double, double, double>> presets = {\n            {1.0, 30.0, 10000.0, 1.0},   // Balanced\n            {1.0, 60.0, 5000.0, 0.5},    // High connectivity early\n            {1.0, 10.0, 50000.0, 0.3},   // Avoid dead ends strongly\n            {1.0, 0.0, 0.0, 0.0},        // Pure greedy\n            {1.0, 100.0, 1000.0, 0.2},   // Extreme connectivity\n        };\n        \n        for (auto& [wv, wd, dp, wf] : presets) {\n            string p = greedy_walk(wv, wd, dp, wf, false, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        // Phase 3: Extensive stochastic search\n        for (int iter = 0; iter < 3000; ++iter) {\n            double wv = 1.0;\n            double wd = rand_double() * 100.0;      // 0 to 100\n            double dp = rand_double() * 50000.0;    // 0 to 50000\n            double wf = rand_double() * 1.5;        // 0 to 1.5\n            \n            string p = greedy_walk(wv, wd, dp, wf, true, -1);\n            long long s = evaluate_path(p);\n            if (s > best_score) {\n                best_score = s;\n                best_path = p;\n            }\n        }\n        \n        return best_path;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    while (true) {\n        int si, sj;\n        if (!(cin >> si >> sj)) break;\n        \n        vector<vector<int>> t(H, vector<int>(W));\n        vector<vector<int>> p(H, vector<int>(W));\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                cin >> p[i][j];\n        \n        Solver solver;\n        solver.si = si;\n        solver.sj = sj;\n        solver.tile = t;\n        solver.val = p;\n        \n        int max_id = 0;\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                max_id = max(max_id, t[i][j]);\n        solver.M = max_id + 1;\n        \n        cout << solver.solve() << \"\\n\";\n    }\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    constexpr int N = 30;\n    constexpr int Q = 1000;\n    constexpr double LR_BASE = 0.6;      // proven stable rate\n    constexpr double LR_BOOST = 0.2;     // extra rate early on\n    constexpr int    LR_BOOST_UNTIL = 200;\n    constexpr double SIGMA0 = 2000.0;   // exploration prior\n    constexpr double WMIN = 100.0;\n    constexpr double WMAX = 10000.0;\n    constexpr double SMOOTH_ALPHA = 0.04; // Laplacian strength\n    constexpr int SMOOTH_UNTIL = 980;    // revert to peak value\n    constexpr int EXPLORE_UNTIL = 850;   // protect late queries\n    \n    // estimates and visit counters\n    double H[N][N - 1];\n    double V[N - 1][N];\n    int    CntH[N][N - 1] = {};\n    int    CntV[N - 1][N] = {};\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            H[i][j] = 5000.0;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            V[i][j] = 5000.0;\n    \n    // temporaries for smoothing\n    double tmpH[N][N - 1];\n    double tmpV[N - 1][N];\n    \n    // random generator for Thompson sampling\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    std::normal_distribution<double> gauss(0.0, 1.0);\n    \n    // sampled weights for Dijkstra\n    double sH[N][N - 1];\n    double sV[N - 1][N];\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    for (int q = 0; q < Q; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n        \n        // Decay schedules\n        double explore_decay = max(0.0, 1.0 - static_cast<double>(q) / EXPLORE_UNTIL);\n        double smooth_decay  = max(0.0, 1.0 - static_cast<double>(q) / SMOOTH_UNTIL);\n        // Boosted LR early, then base LR\n        double lr = LR_BASE + LR_BOOST * max(0.0, 1.0 - static_cast<double>(q) / LR_BOOST_UNTIL);\n        \n        // ---------- 1. Thompson sampling with decaying variance ----------\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                double sigma = SIGMA0 * explore_decay / sqrt((double)CntH[i][j] + 1.0);\n                double w = H[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sH[i][j] = w;\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double sigma = SIGMA0 * explore_decay / sqrt((double)CntV[i][j] + 1.0);\n                double w = V[i][j] + gauss(rng) * sigma;\n                if (w < WMIN) w = WMIN;\n                if (w > WMAX) w = WMAX;\n                sV[i][j] = w;\n            }\n        }\n        \n        // ---------- 2. Dijkstra ----------\n        double dist[N][N];\n        int par_i[N][N];\n        int par_j[N][N];\n        char par_dir[N][N];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = 1e100;\n        \n        using State = tuple<double, int, int>;\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[si][sj] = 0.0;\n        pq.emplace(0.0, si, sj);\n        \n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j] + 1e-9) continue;\n            if (i == ti && j == tj) break;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                double w;\n                if (dir == 0) w = sV[i - 1][j];\n                else if (dir == 1) w = sV[i][j];\n                else if (dir == 2) w = sH[i][j - 1];\n                else               w = sH[i][j];\n                if (dist[ni][nj] > d + w) {\n                    dist[ni][nj] = d + w;\n                    par_i[ni][nj] = i;\n                    par_j[ni][nj] = j;\n                    par_dir[ni][nj] = dc[dir];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n        \n        // reconstruct path\n        string path;\n        int ci = ti, cj = tj;\n        while (ci != si || cj != sj) {\n            path.push_back(par_dir[ci][cj]);\n            int pi = par_i[ci][cj];\n            int pj = par_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << '\\n';\n        cout.flush();\n        \n        // ---------- 3. Observation & Weighted SGD ----------\n        long long obs_in;\n        cin >> obs_in;\n        double obs = static_cast<double>(obs_in);\n        \n        double lenEst = 0.0;\n        ci = si; cj = sj;\n        struct Edge { char type; int i, j; };\n        vector<Edge> edges;\n        edges.reserve(path.size());\n        for (char c : path) {\n            if (c == 'U') {\n                lenEst += V[ci - 1][cj];\n                edges.push_back({'V', ci - 1, cj});\n                --ci;\n            } else if (c == 'D') {\n                lenEst += V[ci][cj];\n                edges.push_back({'V', ci, cj});\n                ++ci;\n            } else if (c == 'L') {\n                lenEst += H[ci][cj - 1];\n                edges.push_back({'H', ci, cj - 1});\n                --cj;\n            } else { // 'R'\n                lenEst += H[ci][cj];\n                edges.push_back({'H', ci, cj});\n                ++cj;\n            }\n        }\n        \n        double err = obs - lenEst;\n        // uncertainty-based weights: 1/sqrt(count+1)\n        double sumW = 0.0;\n        vector<double> uweight;\n        uweight.reserve(edges.size());\n        for (auto &e : edges) {\n            int cnt = (e.type == 'H') ? CntH[e.i][e.j] : CntV[e.i][e.j];\n            double uw = 1.0 / sqrt((double)cnt + 1.0);\n            uweight.push_back(uw);\n            sumW += uw;\n        }\n        \n        // apply weighted update with adaptive learning rate\n        for (size_t idx = 0; idx < edges.size(); ++idx) {\n            const auto &e = edges[idx];\n            double delta = lr * err * (uweight[idx] / sumW);\n            if (e.type == 'H') {\n                H[e.i][e.j] += delta;\n                if (H[e.i][e.j] < WMIN) H[e.i][e.j] = WMIN;\n                if (H[e.i][e.j] > WMAX) H[e.i][e.j] = WMAX;\n                ++CntH[e.i][e.j];\n            } else {\n                V[e.i][e.j] += delta;\n                if (V[e.i][e.j] < WMIN) V[e.i][e.j] = WMIN;\n                if (V[e.i][e.j] > WMAX) V[e.i][e.j] = WMAX;\n                ++CntV[e.i][e.j];\n            }\n        }\n        \n        // ---------- 4. Standard Laplacian smoothing (linearly decayed) ----------\n        if (smooth_decay > 0.0) {\n            double alpha = SMOOTH_ALPHA * smooth_decay;\n            \n            // Horizontal edges: smooth along rows\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N - 1; ++j) {\n                    double left  = (j > 0)     ? H[i][j - 1] : H[i][j];\n                    double right = (j < N - 2) ? H[i][j + 1] : H[i][j];\n                    double lap = left + right - 2.0 * H[i][j];\n                    tmpH[i][j] = H[i][j] + alpha * lap;\n                    if (tmpH[i][j] < WMIN) tmpH[i][j] = WMIN;\n                    if (tmpH[i][j] > WMAX) tmpH[i][j] = WMAX;\n                }\n            }\n            // Vertical edges: smooth along columns\n            for (int i = 0; i < N - 1; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    double up   = (i > 0)     ? V[i - 1][j] : V[i][j];\n                    double down = (i < N - 2) ? V[i + 1][j] : V[i][j];\n                    double lap = up + down - 2.0 * V[i][j];\n                    tmpV[i][j] = V[i][j] + alpha * lap;\n                    if (tmpV[i][j] < WMIN) tmpV[i][j] = WMIN;\n                    if (tmpV[i][j] > WMAX) tmpV[i][j] = WMAX;\n                }\n            }\n            // copy back\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N - 1; ++j)\n                    H[i][j] = tmpH[i][j];\n            for (int i = 0; i < N - 1; ++i)\n                for (int j = 0; j < N; ++j)\n                    V[i][j] = tmpV[i][j];\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int str_id;\n    uint8_t len;\n};\n\nstruct Ref {\n    int pid;\n    uint8_t req;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    int N_input, M;\n    if (!(cin >> N_input >> M)) return 0;\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) cin >> strs[i];\n\n    auto ch2i = [](char c)->int{ return c - 'A'; };\n\n    const int C = N * N;\n    vector<vector<Ref>> cell_refs(C);\n    vector<Placement> plc;\n    plc.reserve(M * 2 * N * N);\n\n    for (int s = 0; s < M; ++s) {\n        const string &st = strs[s];\n        int L = st.size();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    cell_refs[r * N + cc].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pid = plc.size();\n                plc.push_back({s, (uint8_t)L});\n                for (int p = 0; p < L; ++p) {\n                    int rr = (r + p) % N;\n                    cell_refs[rr * N + c].push_back({pid, (uint8_t)ch2i(st[p])});\n                }\n            }\n        }\n    }\n\n    const int P = plc.size();\n    const double TIME_LIMIT = 2.95;\n    auto start = chrono::steady_clock::now();\n    \n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Frequency info\n    vector<array<int, 8>> freq(C);\n    vector<uint8_t> greedy_best(C);\n    for (int cid = 0; cid < C; ++cid) {\n        freq[cid].fill(0);\n        for (const auto &rf : cell_refs[cid]) {\n            freq[cid][rf.req]++;\n        }\n        greedy_best[cid] = max_element(freq[cid].begin(), freq[cid].end()) - freq[cid].begin();\n    }\n    \n    vector<uint8_t> global_best_grid;\n    int global_best_sat = 0;\n    \n    vector<uint8_t> grid(C), counter(P);\n    vector<int> sat_cnt(M);\n    int total_sat;\n    \n    auto evaluate = [&]() {\n        fill(counter.begin(), counter.end(), 0);\n        fill(sat_cnt.begin(), sat_cnt.end(), 0);\n        total_sat = 0;\n        for (int cid = 0; cid < C; ++cid) {\n            uint8_t v = grid[cid];\n            for (const auto &rf : cell_refs[cid]) {\n                if (rf.req == v) ++counter[rf.pid];\n            }\n        }\n        for (int pid = 0; pid < P; ++pid) {\n            if (counter[pid] == plc[pid].len) {\n                ++sat_cnt[plc[pid].str_id];\n            }\n        }\n        for (int s = 0; s < M; ++s) if (sat_cnt[s] > 0) ++total_sat;\n    };\n    \n    auto apply = [&](int cid, uint8_t from, uint8_t to) -> int {\n        if (from == to) return 0;\n        int delta = 0;\n        for (const auto &rf : cell_refs[cid]) {\n            bool fm = (from == rf.req), tm = (to == rf.req);\n            if (fm == tm) continue;\n            auto &cnt = counter[rf.pid];\n            uint8_t len = plc[rf.pid].len;\n            int sid = plc[rf.pid].str_id;\n            if (fm) {\n                if (cnt-- == len) {\n                    if (--sat_cnt[sid] == 0) --delta;\n                }\n            } else {\n                if (++cnt == len) {\n                    if (sat_cnt[sid]++ == 0) ++delta;\n                }\n            }\n        }\n        total_sat += delta;\n        return delta;\n    };\n    \n    auto time_left = [&]()->double {\n        return TIME_LIMIT - chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    // Phase 1: Many diverse restarts\n    int restart = 0;\n    while (time_left() > 0.15) {\n        ++restart;\n        \n        // Diverse initialization strategies\n        int strategy = restart % 4;\n        if (strategy == 0) {\n            // Pure random\n            for (int i = 0; i < C; ++i) grid[i] = (uint8_t)(rng() & 7);\n        } else if (strategy == 1) {\n            // Greedy best with noise\n            for (int i = 0; i < C; ++i) {\n                grid[i] = (rng() % 3 == 0) ? (uint8_t)(rng() & 7) : greedy_best[i];\n            }\n        } else if (strategy == 2) {\n            // Frequency weighted\n            for (int cid = 0; cid < C; ++cid) {\n                int total = 0;\n                for (int c = 0; c < 8; ++c) total += freq[cid][c] + 1;\n                int r = (int)(rng() % total);\n                for (int c = 0; c < 8; ++c) {\n                    r -= freq[cid][c] + 1;\n                    if (r < 0) { grid[cid] = c; break; }\n                }\n            }\n        } else {\n            // Random with 50% greedy\n            for (int i = 0; i < C; ++i) {\n                grid[i] = (rng() & 1) ? greedy_best[i] : (uint8_t)(rng() & 7);\n            }\n        }\n        \n        evaluate();\n        \n        // Quick SA (short but effective)\n        double temp = 0.8;\n        for (int iter = 0; iter < 30000 && time_left() > 0.15; ++iter) {\n            if ((iter & 511) == 0) temp *= 0.995;\n            \n            int cid = (int)(rng() % C);\n            uint8_t oldv = grid[cid];\n            uint8_t newv = (uint8_t)(rng() & 7);\n            if (oldv == newv) continue;\n            \n            int before = total_sat;\n            apply(cid, oldv, newv);\n            int delta = total_sat - before;\n            \n            if (delta < 0 && uniform_real_distribution<double>(0.0, 1.0)(rng) >= exp(delta / temp)) {\n                apply(cid, newv, oldv);\n            } else {\n                grid[cid] = newv;\n            }\n        }\n        \n        // Hill climbing to local optimum\n        for (int round = 0; round < 3 && time_left() > 0.15; ++round) {\n            for (int cid = 0; cid < C && time_left() > 0.15; ++cid) {\n                uint8_t cur = grid[cid];\n                uint8_t bestc = cur;\n                int best_sc = total_sat;\n                \n                for (uint8_t cand = 0; cand < 8; ++cand) {\n                    if (cand == cur) continue;\n                    apply(cid, cur, cand);\n                    if (total_sat > best_sc) {\n                        best_sc = total_sat;\n                        bestc = cand;\n                    }\n                    apply(cid, cand, cur);\n                }\n                \n                if (bestc != cur) {\n                    apply(cid, cur, bestc);\n                    grid[cid] = bestc;\n                }\n            }\n        }\n        \n        if (total_sat > global_best_sat) {\n            global_best_sat = total_sat;\n            global_best_grid = grid;\n        }\n        if (global_best_sat == M) break;\n    }\n    \n    // Phase 2: Intensive polishing on global best\n    if (global_best_sat > 0 && time_left() > 0.05) {\n        grid = global_best_grid;\n        evaluate();\n        \n        // Repeated exhaustive passes until no improvement\n        for (int big_pass = 0; big_pass < 10 && time_left() > 0.03; ++big_pass) {\n            bool any_improve = false;\n            \n            for (int cid = 0; cid < C && time_left() > 0.02; ++cid) {\n                uint8_t cur = grid[cid];\n                uint8_t bestc = cur;\n                int best_sc = total_sat;\n                \n                for (uint8_t cand = 0; cand < 8; ++cand) {\n                    if (cand == cur) continue;\n                    apply(cid, cur, cand);\n                    if (total_sat > best_sc) {\n                        best_sc = total_sat;\n                        bestc = cand;\n                    }\n                    apply(cid, cand, cur);\n                }\n                \n                if (bestc != cur) {\n                    apply(cid, cur, bestc);\n                    grid[cid] = bestc;\n                    any_improve = true;\n                }\n            }\n            \n            if (!any_improve) break;\n        }\n        \n        global_best_sat = total_sat;\n        global_best_grid = grid;\n    }\n    \n    // Dot removal\n    grid = global_best_grid;\n    evaluate();\n    \n    if (total_sat == M) {\n        vector<int> order(C);\n        iota(order.begin(), order.end(), 0);\n        \n        for (int rep = 0; rep < 5; ++rep) {\n            shuffle(order.begin(), order.end(), rng);\n            for (int cid : order) {\n                if (grid[cid] == 8) continue;\n                uint8_t oldv = grid[cid];\n                \n                bool safe = true;\n                for (const auto &rf : cell_refs[cid]) {\n                    if (oldv != rf.req) continue;\n                    if (counter[rf.pid] <= 1) {\n                        safe = false;\n                        break;\n                    }\n                }\n                \n                if (safe) {\n                    for (const auto &rf : cell_refs[cid]) {\n                        if (oldv == rf.req) --counter[rf.pid];\n                    }\n                    grid[cid] = 8;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (int r = 0; r < N; ++r) {\n        string line;\n        line.reserve(N);\n        for (int c = 0; c < N; ++c) {\n            int v = grid[r * N + c];\n            line.push_back(v == 8 ? '.' : char('A' + v));\n        }\n        cout << line << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastBitset {\n    static const int MAXR = 5000;\n    static const int WORDS = (MAXR + 63) / 64;\n    uint64_t w[WORDS];\n    FastBitset() { memset(w, 0, sizeof(w)); }\n    void set(int i) { w[i>>6] |= 1ULL << (i&63); }\n    bool test(int i) const { return (w[i>>6] >> (i&63)) & 1ULL; }\n    void clear() { memset(w, 0, sizeof(w)); }\n    int count() const {\n        int s = 0;\n        for (int i = 0; i < WORDS; i++) s += __builtin_popcountll(w[i]);\n        return s;\n    }\n    FastBitset operator|(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] | o.w[i];\n        return r;\n    }\n    FastBitset operator&(const FastBitset& o) const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = w[i] & o.w[i];\n        return r;\n    }\n    FastBitset operator~() const {\n        FastBitset r;\n        for (int i = 0; i < WORDS; i++) r.w[i] = ~w[i];\n        return r;\n    }\n    FastBitset& operator|=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] |= o.w[i];\n        return *this;\n    }\n    FastBitset& operator&=(const FastBitset& o) {\n        for (int i = 0; i < WORDS; i++) w[i] &= o.w[i];\n        return *this;\n    }\n    bool any() const {\n        for (int i = 0; i < WORDS; i++) if (w[i]) return true;\n        return false;\n    }\n    bool is_subset_of(const FastBitset& o) const {\n        for (int i = 0; i < WORDS; i++) {\n            if ((w[i] & ~o.w[i]) != 0) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = cells.size();\n                cells.emplace_back(i, j);\n            }\n        }\n    }\n    int R = cells.size();\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // Build segments\n    vector<vector<int>> h_id(N, vector<int>(N, -1));\n    vector<vector<int>> v_id(N, vector<int>(N, -1));\n    vector<FastBitset> h_cover, v_cover;\n    \n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != '#') {\n                int l = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int r = j - 1;\n                FastBitset bs;\n                int sid = h_cover.size();\n                for (int k = l; k <= r; k++) h_id[i][k] = sid, bs.set(id[i][k]);\n                h_cover.push_back(bs);\n            } else j++;\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != '#') {\n                int t = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int b = i - 1;\n                FastBitset bs;\n                int sid = v_cover.size();\n                for (int k = t; k <= b; k++) v_id[k][j] = sid, bs.set(id[k][j]);\n                v_cover.push_back(bs);\n            } else i++;\n        }\n    }\n    \n    vector<FastBitset> cell_cover(R);\n    for (int idx = 0; idx < R; idx++) {\n        auto [i, j] = cells[idx];\n        cell_cover[idx] = h_cover[h_id[i][j]] | v_cover[v_id[i][j]];\n    }\n    \n    int start_idx = id[si][sj];\n    \n    // Greedy set cover\n    FastBitset uncovered;\n    for (int i = 0; i < R; i++) uncovered.set(i);\n    FastBitset start_cover = cell_cover[start_idx];\n    for (int w = 0; w < FastBitset::WORDS; w++) uncovered.w[w] &= ~start_cover.w[w];\n    \n    vector<int> selected;\n    vector<bool> is_selected(R, false);\n    \n    while (uncovered.any()) {\n        int best = -1, best_cnt = -1;\n        for (int c = 0; c < R; c++) {\n            if (is_selected[c]) continue;\n            bool has = false;\n            for (int w = 0; w < FastBitset::WORDS; w++) \n                if (cell_cover[c].w[w] & uncovered.w[w]) { has = true; break; }\n            if (!has) continue;\n            FastBitset inter;\n            for (int w = 0; w < FastBitset::WORDS; w++) \n                inter.w[w] = cell_cover[c].w[w] & uncovered.w[w];\n            int cnt = inter.count();\n            if (cnt > best_cnt) best_cnt = cnt, best = c;\n        }\n        if (best == -1) break;\n        selected.push_back(best);\n        is_selected[best] = true;\n        for (int w = 0; w < FastBitset::WORDS; w++) \n            uncovered.w[w] &= ~cell_cover[best].w[w];\n    }\n    \n    // Redundancy elimination\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int i = 0; i < (int)selected.size(); i++) {\n            FastBitset without = start_cover;\n            for (int j = 0; j < (int)selected.size(); j++) \n                if (i != j) without |= cell_cover[selected[j]];\n            FastBitset loss;\n            for (int w = 0; w < FastBitset::WORDS; w++)\n                loss.w[w] = cell_cover[selected[i]].w[w] & ~without.w[w];\n            if (!loss.any()) {\n                is_selected[selected[i]] = false;\n                selected.erase(selected.begin() + i);\n                changed = true;\n                break;\n            }\n        }\n    }\n    \n    // Build points\n    vector<int> points;\n    points.push_back(start_idx);\n    for (int idx : selected) points.push_back(idx);\n    int K = points.size();\n    \n    if (K == 1) {\n        cout << \"\\n\";\n        return 0;\n    }\n    \n    vector<int> node_to_point(R, -1);\n    for (int i = 0; i < K; i++) node_to_point[points[i]] = i;\n    \n    const int INF = 1e9;\n    \n    // Distance matrix\n    vector<vector<int>> dmat(K, vector<int>(K, INF));\n    for (int pi = 0; pi < K; pi++) {\n        int src = points[pi];\n        vector<int> dist(R, INF);\n        dist[src] = 0;\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.emplace(0, src);\n        int settled = 0;\n        \n        while (!pq.empty() && settled < K) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (node_to_point[u] != -1) settled++;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir], nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        for (int pj = 0; pj < K; pj++) dmat[pi][pj] = dist[points[pj]];\n    }\n    \n    // TSP functions\n    auto calc_cost = [&](const vector<int>& tour) -> int {\n        int c = 0;\n        for (int i = 0; i < K; i++) c += dmat[tour[i]][tour[(i+1)%K]];\n        return c;\n    };\n    \n    // Exhaustive 2-opt\n    auto do_2opt = [&](vector<int>& tour) -> int {\n        int cost = calc_cost(tour);\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < K && !improved; i++) {\n                for (int j = i + 2; j < K && !improved; j++) {\n                    if (i == 0 && j == K-1) continue;\n                    int a = tour[i], b = tour[(i+1)%K];\n                    int c = tour[j], d = tour[(j+1)%K];\n                    int cur = dmat[a][b] + dmat[c][d];\n                    int rev = dmat[a][c] + dmat[b][d];\n                    if (rev < cur) {\n                        reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                        cost += rev - cur;\n                        improved = true;\n                    }\n                }\n            }\n        }\n        return cost;\n    };\n    \n    // Node shift: move a node to a better position\n    auto do_shift = [&](vector<int>& tour) -> int {\n        int cost = calc_cost(tour);\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 1; i < K && !improved; i++) {\n                int node = tour[i];\n                int prev = tour[i-1];\n                int next = tour[(i+1)%K];\n                int cur_edges = dmat[prev][node] + dmat[node][next];\n                \n                // Try moving to other positions\n                for (int pos = 0; pos < K-1 && !improved; pos++) {\n                    if (pos == i-1 || pos == i) continue;\n                    int a = tour[pos];\n                    int b = tour[(pos+1)%K];\n                    int removed = dmat[a][b];\n                    int added = dmat[a][node] + dmat[node][b];\n                    if (pos < i) {\n                        // New edges at pos, lose edge i-1->i and i->i+1, gain i-1->i+1\n                        int gain = cur_edges - dmat[prev][next];\n                        int loss = added - removed;\n                        if (loss < gain) {\n                            // Do the shift\n                            tour.erase(tour.begin() + i);\n                            tour.insert(tour.begin() + pos + 1, node);\n                            cost += loss - gain;\n                            improved = true;\n                        }\n                    } else {\n                        // pos > i\n                        int gain = cur_edges - dmat[prev][next];\n                        int loss = added - removed;\n                        if (loss < gain) {\n                            tour.erase(tour.begin() + i);\n                            tour.insert(tour.begin() + pos, node);\n                            cost += loss - gain;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        return cost;\n    };\n    \n    // Generate tours\n    vector<int> best_tour;\n    int best_cost = INF;\n    mt19937 rng(42);\n    \n    // Many insertion heuristics\n    for (int t = 0; t < 30; t++) {\n        vector<int> tour = {0};\n        vector<int> nodes;\n        for (int i = 1; i < K; i++) nodes.push_back(i);\n        \n        if (t < 10) {\n            // Farthest first\n            sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n                int da = 0, db = 0;\n                for (int j = 0; j < K; j++) {\n                    da = max(da, dmat[j][a]);\n                    db = max(db, dmat[j][b]);\n                }\n                return da > db;\n            });\n        } else if (t < 20) {\n            // Nearest to tour first\n            shuffle(nodes.begin(), nodes.end(), rng);\n        } else {\n            shuffle(nodes.begin(), nodes.end(), rng);\n        }\n        \n        for (int node : nodes) {\n            int best_pos = -1, best_inc = INF;\n            for (int pos = 0; pos < (int)tour.size(); pos++) {\n                int a = tour[pos], b = tour[(pos+1)%tour.size()];\n                int inc = dmat[a][node] + dmat[node][b] - dmat[a][b];\n                if (inc < best_inc) best_inc = inc, best_pos = pos;\n            }\n            tour.insert(tour.begin() + best_pos + 1, node);\n        }\n        \n        int c = calc_cost(tour);\n        c = do_2opt(tour);\n        c = do_shift(tour);\n        c = do_2opt(tour);\n        \n        if (c < best_cost) {\n            best_cost = c;\n            best_tour = tour;\n        }\n    }\n    \n    // Nearest neighbor with restarts\n    for (int start = 0; start < min(K, 15); start++) {\n        vector<int> tour;\n        vector<bool> used(K, false);\n        tour.push_back(start);\n        used[start] = true;\n        int cur = start;\n        \n        while ((int)tour.size() < K) {\n            int nxt = -1, best_d = INF;\n            for (int i = 0; i < K; i++) if (!used[i] && dmat[cur][i] < best_d) {\n                best_d = dmat[cur][i];\n                nxt = i;\n            }\n            if (nxt == -1) break;\n            tour.push_back(nxt);\n            used[nxt] = true;\n            cur = nxt;\n        }\n        \n        auto it = find(tour.begin(), tour.end(), 0);\n        if (it != tour.end()) rotate(tour.begin(), it, tour.end());\n        \n        int c = do_2opt(tour);\n        c = do_shift(tour);\n        c = do_2opt(tour);\n        \n        if (c < best_cost) {\n            best_cost = c;\n            best_tour = tour;\n        }\n    }\n    \n    // Build route\n    string route;\n    route.reserve(N * N * 4);\n    \n    for (int ii = 0; ii < K; ii++) {\n        int from_idx = points[best_tour[ii]];\n        int to_idx = points[best_tour[(ii+1)%K]];\n        if (from_idx == to_idx) continue;\n        \n        vector<int> dist(R, INF);\n        vector<int> prev(R, -1);\n        vector<int> prev_dir(R, -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[from_idx] = 0;\n        pq.emplace(0, from_idx);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == to_idx) break;\n            auto [ui, uj] = cells[u];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ui + di[dir], nj = uj + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id[ni][nj];\n                if (v == -1) continue;\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_dir[v] = dir;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int cur_node = to_idx;\n        while (cur_node != from_idx) {\n            dirs.push_back(prev_dir[cur_node]);\n            cur_node = prev[cur_node];\n        }\n        reverse(dirs.begin(), dirs.end());\n        for (int d : dirs) route += \"UDLR\"[d];\n    }\n    \n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if(!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> sum_d(N, 0);\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<K; j++) {\n            cin >> d[i][j];\n            sum_d[i] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0);\n    for(int i=0; i<R; i++) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    // State\n    vector<vector<double>> est_s(M, vector<double>(K, 30.0));\n    vector<vector<double>> lb(M, vector<double>(K, 0.0));\n    vector<int> total_obs(M, 0);\n    \n    vector<int> indeg_cur = indeg;\n    vector<int> task_state(N, 0);\n    vector<int> member_task(M, -1);\n    vector<int> task_start_day(N, -1);\n    \n    int day = 0;\n    const int MAX_DAY = 2000;\n    \n    while(day < MAX_DAY) {\n        ++day;\n        \n        // Update available tasks\n        vector<int> available;\n        for(int i=0; i<N; i++) {\n            if(task_state[i] == 0 && indeg_cur[i] == 0) {\n                task_state[i] = 1;\n            }\n            if(task_state[i] == 1) available.push_back(i);\n        }\n        \n        // Find free members\n        vector<int> free_members;\n        for(int j=0; j<M; j++) if(member_task[j] == -1) free_members.push_back(j);\n        \n        if(!available.empty() && !free_members.empty()) {\n            // Calculate times for all task-member pairs\n            vector<vector<double>> est_time(M, vector<double>(N, 1.0));\n            vector<vector<double>> pessimistic_time(M, vector<double>(N, 1.0));\n            \n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                for(int j=0; j<M; j++) {\n                    // Optimistic estimate\n                    double w_opt = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > est_s[j][k]) w_opt += d[i][k] - est_s[j][k];\n                    est_time[j][i] = (w_opt <= 0) ? 1.0 : max(1.0, w_opt);\n                    \n                    // Pessimistic estimate using lower bounds\n                    double w_pes = 0;\n                    for(int k=0; k<K; k++) if(d[i][k] > lb[j][k]) w_pes += d[i][k] - lb[j][k];\n                    pessimistic_time[j][i] = (w_pes <= 0) ? 1.0 : max(1.0, w_pes);\n                }\n            }\n            \n            // Critical path using pessimistic times\n            vector<double> cp(N, -1.0);\n            function<double(int)> solve_cp = [&](int u) -> double {\n                if(task_state[u] == 3) return 0.0;\n                if(cp[u] >= 0) return cp[u];\n                double max_next = 0.0;\n                for(int v : adj[u]) if(task_state[v] != 3) {\n                    max_next = max(max_next, solve_cp(v));\n                }\n                // Use pessimistic average\n                double avg = 0;\n                for(int j=0; j<M; j++) avg += pessimistic_time[j][u];\n                cp[u] = avg / M + max_next;\n                return cp[u];\n            };\n            for(int i : available) solve_cp(i);\n            \n            // Best and second best times for bottleneck detection\n            vector<double> best_time(N, 1e18), second_time(N, 1e18);\n            vector<int> best_member(N, -1);\n            for(int i=0; i<N; i++) {\n                if(task_state[i] == 3) continue;\n                for(int j=0; j<M; j++) {\n                    if(est_time[j][i] < best_time[i]) {\n                        second_time[i] = best_time[i];\n                        best_time[i] = est_time[j][i];\n                        best_member[i] = j;\n                    } else if(est_time[j][i] < second_time[i]) {\n                        second_time[i] = est_time[j][i];\n                    }\n                }\n            }\n            \n            // Priority: critical path + bottleneck\n            vector<double> priority(N, 0.0);\n            for(int i : available) {\n                double bottleneck = second_time[i] - best_time[i];\n                priority[i] = cp[i] + 1.5 * bottleneck;\n            }\n            \n            sort(available.begin(), available.end(), [&](int a, int b) {\n                return priority[a] > priority[b];\n            });\n            \n            // Greedy assignment with risk awareness\n            vector<bool> used(M, false);\n            vector<pair<int,int>> assignments;\n            \n            for(int task_id : available) {\n                if(assignments.size() >= free_members.size()) break;\n                \n                // Find best free member, penalizing uncertainty\n                int best_j = -1;\n                double best_score = 1e18;\n                \n                for(int j : free_members) {\n                    if(used[j]) continue;\n                    \n                    double time = est_time[j][task_id];\n                    // Risk penalty: unexplored members are risky for critical tasks\n                    double risk = (5.0 / (1.0 + total_obs[j])) * (cp[task_id] / 50.0);\n                    double score = time + risk;\n                    \n                    if(score < best_score) {\n                        best_score = score;\n                        best_j = j;\n                    }\n                }\n                \n                if(best_j != -1) {\n                    assignments.emplace_back(best_j, task_id);\n                    used[best_j] = true;\n                }\n            }\n            \n            cout << assignments.size();\n            for(auto& [j, i] : assignments) {\n                cout << \" \" << j+1 << \" \" << i+1;\n                member_task[j] = i;\n                task_state[i] = 2;\n                task_start_day[i] = day;\n            }\n            cout << endl;\n        } else {\n            cout << 0 << endl;\n        }\n        cout.flush();\n        \n        // Read completions\n        int n_comp;\n        cin >> n_comp;\n        if(n_comp == -1) break;\n        \n        vector<int> completed(n_comp);\n        for(int i=0; i<n_comp; i++) cin >> completed[i], completed[i]--;\n        \n        // Process completions and update skills\n        for(int j : completed) {\n            int task_id = member_task[j];\n            if(task_id == -1) continue;\n            \n            int duration = day - task_start_day[task_id] + 1;\n            double obs_w = max(0, duration - 1);\n            total_obs[j]++;\n            \n            // Calculate predicted deficiency\n            double pred_w = 0;\n            vector<int> active_dims;\n            vector<double> deficits;\n            for(int k=0; k<K; k++) {\n                if(d[task_id][k] > est_s[j][k]) {\n                    double def = (double)d[task_id][k] - est_s[j][k];\n                    pred_w += def;\n                    active_dims.push_back(k);\n                    deficits.push_back(def);\n                }\n            }\n            \n            if(obs_w == 0) {\n                // Skills are at least requirements\n                for(int k=0; k<K; k++) {\n                    lb[j][k] = max(lb[j][k], (double)d[task_id][k]);\n                    est_s[j][k] = max(est_s[j][k], (double)d[task_id][k]);\n                }\n            } else if(active_dims.empty()) {\n                // Severe underestimate: distribute deficiency using squared weights\n                double sum_sq = 0;\n                for(int k=0; k<K; k++) {\n                    sum_sq += (double)d[task_id][k] * d[task_id][k];\n                }\n                \n                if(sum_sq > 0) {\n                    for(int k=0; k<K; k++) {\n                        double reduction = obs_w * (double)d[task_id][k] * d[task_id][k] / sum_sq;\n                        est_s[j][k] = max(0.0, (double)d[task_id][k] - reduction);\n                    }\n                }\n            } else {\n                // Adjust active dimensions proportionally\n                if(pred_w > 0) {\n                    double ratio = obs_w / pred_w;\n                    // Clamp ratio for stability\n                    ratio = min(2.0, max(0.5, ratio));\n                    \n                    for(size_t idx=0; idx<active_dims.size(); idx++) {\n                        int k = active_dims[idx];\n                        double new_def = deficits[idx] * ratio;\n                        est_s[j][k] = (double)d[task_id][k] - new_def;\n                        est_s[j][k] = max(lb[j][k], est_s[j][k]);\n                    }\n                }\n            }\n            \n            task_state[task_id] = 3;\n            member_task[j] = -1;\n            for(int v : adj[task_id]) indeg_cur[v]--;\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double now() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 1000;\n    const int OFFICE = 0;\n    const int OFFICE_X = 400, OFFICE_Y = 400;\n    const int MAX_P = 2 * N + 1; // 0..2000\n    \n    vector<int> a(N), b(N), c(N), d(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> a[i] >> b[i] >> c[i] >> d[i];\n    }\n    \n    // Coordinate compression: 0 = office, 1..N = pickup, N+1..2N = delivery\n    vector<int> xs(MAX_P), ys(MAX_P);\n    xs[OFFICE] = OFFICE_X; ys[OFFICE] = OFFICE_Y;\n    for (int i = 0; i < N; ++i) {\n        xs[1 + i] = a[i]; ys[1 + i] = b[i];\n        xs[1 + N + i] = c[i]; ys[1 + N + i] = d[i];\n    }\n    \n    // Flat distance matrix: dist[i * MAX_P + j]\n    vector<int> dist(MAX_P * MAX_P);\n    auto D = [&](int i, int j) -> int& { return dist[i * MAX_P + j]; };\n    for (int i = 0; i < MAX_P; ++i) {\n        for (int j = 0; j < MAX_P; ++j) {\n            D(i, j) = abs(xs[i] - xs[j]) + abs(ys[i] - ys[j]);\n        }\n    }\n    \n    Timer timer;\n    \n    // ---------- Greedy Insertion ----------\n    vector<int> route;\n    route.reserve(105);\n    route.push_back(OFFICE);\n    route.push_back(OFFICE);\n    vector<int> selected; selected.reserve(50);\n    vector<bool> used(N, false);\n    \n    for (int iter = 0; iter < 50; ++iter) {\n        int m = (int)route.size();\n        int best_o = -1, best_i = -1, best_j = -1;\n        int best_delta = 1e9;\n        \n        for (int o = 0; o < N; ++o) if (!used[o]) {\n            int p = 1 + o;\n            int del = 1 + N + o;\n            for (int i = 0; i < m - 1; ++i) {\n                int ri = route[i];\n                int ri1 = route[i+1];\n                int dpi = -D(ri, ri1);\n                for (int j = i; j < m - 1; ++j) {\n                    int rj = route[j];\n                    int rj1 = route[j+1];\n                    int delta;\n                    if (i == j) {\n                        delta = dpi + D(ri, p) + D(p, del) + D(del, rj1);\n                    } else {\n                        int dpj = -D(rj, rj1);\n                        delta = dpi + dpj + D(ri, p) + D(p, ri1) + D(rj, del) + D(del, rj1);\n                    }\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_o = o;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        int p = 1 + best_o;\n        int del = 1 + N + best_o;\n        if (best_i == best_j) {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_i + 2, del);\n        } else {\n            route.insert(route.begin() + best_i + 1, p);\n            route.insert(route.begin() + best_j + 2, del);\n        }\n        selected.push_back(best_o);\n        used[best_o] = true;\n    }\n    \n    // Prepare for SA: cur sequence and position array\n    vector<int> cur = route; // size 102\n    const int LEN = 102;\n    const int MIDDLE = 100; // indices 1..100 are movable\n    \n    array<int, MAX_P> pos;\n    for (int i = 0; i < LEN; ++i) pos[cur[i]] = i;\n    \n    auto calc_full = [&](const vector<int>& seq) {\n        int s = 0;\n        for (int i = 0; i + 1 < LEN; ++i) s += D(seq[i], seq[i+1]);\n        return s;\n    };\n    int cur_cost = calc_full(cur);\n    int best_cost = cur_cost;\n    vector<int> best_seq = cur;\n    \n    // Type: 0 = pickup, 1 = delivery\n    auto is_pickup = [&](int idx)->bool{ return idx >= 1 && idx <= N; };\n    auto is_delivery = [&](int idx)->bool{ return idx > N; };\n    \n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(1, 100); // movable range\n    \n    // Precompute exp table for fast annealing\n    const int EXP_TABLE_SIZE = 1000;\n    vector<double> exp_table(EXP_TABLE_SIZE);\n    for (int i = 0; i < EXP_TABLE_SIZE; ++i) {\n        double t = (double)i / 100.0; // delta / T\n        exp_table[i] = exp(-t);\n    }\n    \n    double T_start = 1000.0;\n    double T_end = 0.1;\n    double time_limit = 1.98 - timer.now(); // remaining time for SA\n    if (time_limit < 0.1) time_limit = 0.1;\n    double start_time = timer.now();\n    \n    long long iter = 0;\n    while (timer.now() - start_time < time_limit) {\n        double elapsed = timer.now() - start_time;\n        double progress = elapsed / time_limit;\n        double T = T_start * pow(T_end / T_start, progress);\n        \n        int type = rng() & 1; // 0 = swap, 1 = 2-opt\n        bool accept = false;\n        int delta = 0;\n        \n        if (type == 0) {\n            // Swap\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l == r) continue;\n            if (l > r) swap(l, r);\n            \n            int u = cur[l];\n            int v = cur[r];\n            \n            // Validity check: O(1)\n            bool ok = true;\n            if (is_pickup(u)) {\n                if (pos[u + N] <= r) ok = false; // delivery must be after new pos r\n            } else {\n                if (pos[u - N] >= r) ok = false; // pickup must be before new pos r\n            }\n            if (ok && is_pickup(v)) {\n                if (pos[v + N] <= l) ok = false;\n            } else if (ok) {\n                if (pos[v - N] >= l) ok = false;\n            }\n            if (!ok) continue;\n            \n            // Delta calculation\n            int ul = cur[l-1];\n            int ur = cur[l+1];\n            int vl = cur[r-1];\n            int vr = cur[r+1];\n            \n            if (r == l + 1) {\n                // Adjacent: ... ul, u, v, vr ...\n                delta = -D(ul, u) - D(u, v) - D(v, vr)\n                        + D(ul, v) + D(v, u) + D(u, vr);\n            } else {\n                delta = -D(ul, u) - D(u, ur) - D(vl, v) - D(v, vr)\n                        + D(ul, v) + D(v, ur) + D(vl, u) + D(u, vr);\n            }\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    if (uniform_real_distribution<double>(0,1)(rng) >= 0) continue; // reject with high probability\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                swap(cur[l], cur[r]);\n                pos[u] = r;\n                pos[v] = l;\n            }\n        } else {\n            // 2-opt reverse [l, r]\n            int l = dist_idx(rng);\n            int r = dist_idx(rng);\n            if (l >= r) continue;\n            \n            // Validity: no order has both ends inside [l, r]\n            bool ok = true;\n            for (int o : selected) {\n                int p = 1 + o;\n                int d = 1 + N + o;\n                if (l <= pos[p] && pos[p] <= r && l <= pos[d] && pos[d] <= r) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            \n            int before = cur[l-1];\n            int after = cur[r+1];\n            int left = cur[l];\n            int right = cur[r];\n            delta = -D(before, left) - D(right, after) + D(before, right) + D(left, after);\n            \n            double prob = 1.0;\n            if (delta > 0) {\n                int idx = (int)(delta / T * 100.0);\n                if (idx >= EXP_TABLE_SIZE) {\n                    continue;\n                } else {\n                    prob = exp_table[idx];\n                }\n            }\n            if (delta < 0 || uniform_real_distribution<double>(0,1)(rng) < prob) {\n                accept = true;\n                reverse(cur.begin() + l, cur.begin() + r + 1);\n                for (int i = l; i <= r; ++i) pos[cur[i]] = i;\n            }\n        }\n        \n        if (accept) {\n            cur_cost += delta;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_seq = cur;\n            }\n        }\n        ++iter;\n    }\n    \n    // ---------- Output ----------\n    cout << 50;\n    for (int o : selected) cout << ' ' << (o + 1);\n    cout << '\\n';\n    \n    cout << best_seq.size();\n    for (int idx : best_seq) {\n        cout << ' ' << xs[idx] << ' ' << ys[idx];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        r.assign(n, 0);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        return p[x] == x ? x : p[x] = find(p[x]);\n    }\n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n    void unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> xs[i] >> ys[i];\n    }\n    \n    vector<int> u(M), v(M);\n    vector<long long> d(M);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        long long dx = (long long)xs[u[i]] - xs[v[i]];\n        long long dy = (long long)ys[u[i]] - ys[v[i]];\n        long long dist_sq = dx * dx + dy * dy;\n        long long dist = llround(sqrt((double)dist_sq));\n        d[i] = dist;\n    }\n    \n    // Precompute which edges are bridges in the suffix graph\n    vector<char> is_bridge(M, 0);\n    DSU dsu_back(N);\n    for (int i = M - 1; i >= 0; --i) {\n        if (dsu_back.same(u[i], v[i])) {\n            is_bridge[i] = 0;\n        } else {\n            is_bridge[i] = 1;\n            dsu_back.unite(u[i], v[i]);\n        }\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;\n        cin >> l;\n        \n        if (dsu.same(u[i], v[i])) {\n            cout << 0 << '\\n';\n        } else {\n            int need = components - 1;\n            int remaining = M - i;\n            bool take = false;\n            \n            // Must take if it's a bridge in suffix\n            if (is_bridge[i]) {\n                take = true;\n            } \n            // Must take if we can't afford to skip\n            else if (need >= remaining) {\n                take = true;\n            } \n            else {\n                double ratio = (double)need / (double)remaining;\n                // Slightly more aggressive base\n                double base_threshold = 0.75 + 2.25 * ratio;\n                \n                // Maximum aggression for tiny edges\n                double bonus;\n                if (d[i] <= 8) {\n                    bonus = 1.8;  // Almost always accept\n                } else if (d[i] <= 20) {\n                    bonus = 1.3;  // Very aggressive\n                } else if (d[i] <= 40) {\n                    bonus = 0.85; // Good bonus\n                } else if (d[i] <= 70) {\n                    bonus = 0.5;\n                } else if (d[i] <= 120) {\n                    bonus = 0.3;\n                } else {\n                    bonus = min(0.1, 12.0 / (double)d[i]);\n                }\n                \n                double threshold = min(3.0, base_threshold + bonus);\n                \n                if ((double)l <= threshold * (double)d[i]) {\n                    take = true;\n                } else {\n                    take = false;\n                }\n            }\n            \n            if (take) {\n                cout << 1 << '\\n';\n                dsu.unite(u[i], v[i]);\n                components--;\n            } else {\n                cout << 0 << '\\n';\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool blocked[32][32];\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char wall_cmd[4] = {'u', 'd', 'l', 'r'};\nconst char move_cmd[4] = {'U', 'D', 'L', 'R'};\n\nbool is_passable(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30 && !blocked[x][y];\n}\n\nbool can_place_wall(int x, int y) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) return false;\n    if (blocked[x][y]) return false;\n    \n    for (auto& p : pets) {\n        if (p.x == x && p.y == y) return false;\n    }\n    for (auto& h : humans) {\n        if (h.x == x && h.y == y) return false;\n    }\n    \n    for (auto& p : pets) {\n        for (int d = 0; d < 4; d++) {\n            if (p.x + dx[d] == x && p.y + dy[d] == y) return false;\n        }\n    }\n    return true;\n}\n\nint bfs_area(int sx, int sy) {\n    if (!is_passable(sx, sy)) return 0;\n    bool visited[32][32] = {};\n    queue<pair<int,int>> q;\n    q.push({sx, sy});\n    visited[sx][sy] = true;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (is_passable(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return cnt;\n}\n\nint bfs_next_move(int sx, int sy, int tx, int ty, const vector<pair<int,int>>& obstacles) {\n    if (sx == tx && sy == ty) return -1;\n    \n    queue<pair<int,int>> q;\n    int dist[32][32];\n    memset(dist, -1, sizeof(dist));\n    \n    q.push({sx, sy});\n    dist[sx][sy] = 0;\n    int first_move[32][32];\n    memset(first_move, -1, sizeof(first_move));\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (!is_passable(nx, ny)) continue;\n            if (dist[nx][ny] != -1) continue;\n            \n            bool occupied = false;\n            for (auto& obs : obstacles) {\n                if (obs.first == nx && obs.second == ny) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (occupied) continue;\n            \n            dist[nx][ny] = dist[x][y] + 1;\n            first_move[nx][ny] = (dist[x][y] == 0) ? d : first_move[x][y];\n            \n            if (nx == tx && ny == ty) {\n                return first_move[nx][ny];\n            }\n            q.push({nx, ny});\n        }\n    }\n    return -1;\n}\n\nint nearest_pet_dist(int hx, int hy) {\n    int dist = 1000;\n    for (auto& p : pets) {\n        dist = min(dist, abs(p.x - hx) + abs(p.y - hy));\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    memset(blocked, false, sizeof(blocked));\n    \n    // Calculate initial fortress bounds\n    int min_x = 30, max_x = 1, min_y = 30, max_y = 1;\n    for (auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n    \n    int expand = 2;\n    int f_min_x = max(2, min_x - expand);\n    int f_max_x = min(29, max_x + expand);\n    int f_min_y = max(2, min_y - expand);\n    int f_max_y = min(29, max_y + expand);\n    \n    // Check if pets are initially inside\n    bool individual_mode = false;\n    for (auto& p : pets) {\n        if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n            individual_mode = true;\n            break;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> human_targets(M);\n    \n    if (individual_mode) {\n        // Each human builds their own 3x3 cell\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx + dx[d];\n                int wy = hy + dy[d];\n                if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                    human_targets[i].push_back({wx, wy});\n                }\n            }\n        }\n    } else {\n        // Shared fortress - assign perimeter sections\n        vector<pair<int,int>> all_targets;\n        for (int y = f_min_y; y <= f_max_y; y++) {\n            all_targets.push_back({f_min_x, y});\n            all_targets.push_back({f_max_x, y});\n        }\n        for (int x = f_min_x + 1; x <= f_max_x - 1; x++) {\n            all_targets.push_back({x, f_min_y});\n            all_targets.push_back({x, f_max_y});\n        }\n        \n        // Sort by angle from center to distribute evenly\n        double cx = (min_x + max_x) / 2.0;\n        double cy = (min_y + max_y) / 2.0;\n        sort(all_targets.begin(), all_targets.end(), [&](auto& a, auto& b) {\n            double ang_a = atan2(a.first - cx, a.second - cy);\n            double ang_b = atan2(b.first - cx, b.second - cy);\n            return ang_a < ang_b;\n        });\n        \n        // Round-robin assignment\n        for (int i = 0; i < (int)all_targets.size(); i++) {\n            human_targets[i % M].push_back(all_targets[i]);\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        // Check for invasion (pets inside fortress)\n        if (!individual_mode && turn > 0) {\n            for (auto& p : pets) {\n                if (p.x >= f_min_x && p.x <= f_max_x && p.y >= f_min_y && p.y <= f_max_y) {\n                    // Pet invaded! Switch to emergency individual mode\n                    individual_mode = true;\n                    human_targets.assign(M, {});\n                    for (int i = 0; i < M; i++) {\n                        int hx = humans[i].x, hy = humans[i].y;\n                        for (int d = 0; d < 4; d++) {\n                            int wx = hx + dx[d], wy = hy + dy[d];\n                            if (wx >= 1 && wx <= 30 && wy >= 1 && wy <= 30) {\n                                human_targets[i].push_back({wx, wy});\n                            }\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n        \n        string actions(M, '.');\n        vector<pair<int,int>> next_pos(M);\n        vector<bool> will_build(M, false);\n        \n        // Process humans in order of threat (most threatened first)\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return nearest_pet_dist(humans[a].x, humans[a].y) < nearest_pet_dist(humans[b].x, humans[b].y);\n        });\n        \n        // Track occupied positions for collision avoidance\n        vector<pair<int,int>> occupied;\n        for (auto& h : humans) occupied.push_back({h.x, h.y});\n        \n        for (int idx : order) {\n            int hx = humans[idx].x, hy = humans[idx].y;\n            bool acted = false;\n            \n            // Remove completed targets\n            human_targets[idx].erase(\n                remove_if(human_targets[idx].begin(), human_targets[idx].end(),\n                    [&](auto& t) { return blocked[t.first][t.second]; }),\n                human_targets[idx].end()\n            );\n            \n            // Try to build adjacent wall\n            for (auto& target : human_targets[idx]) {\n                int tx = target.first, ty = target.second;\n                if (abs(tx - hx) + abs(ty - hy) == 1) {\n                    if (can_place_wall(tx, ty)) {\n                        // Safety check: ensure building this wall doesn't trap us in tiny space\n                        blocked[tx][ty] = true;\n                        int area = bfs_area(hx, hy);\n                        blocked[tx][ty] = false;\n                        \n                        if (area >= 4) { // Ensure at least 4 cells accessible\n                            int d = (tx == hx - 1) ? 0 : (tx == hx + 1) ? 1 : (ty == hy - 1) ? 2 : 3;\n                            actions[idx] = wall_cmd[d];\n                            will_build[idx] = true;\n                            next_pos[idx] = {hx, hy};\n                            acted = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (acted) continue;\n            \n            // Move toward nearest target\n            if (!human_targets[idx].empty()) {\n                // Find nearest reachable target\n                int best_target = -1;\n                int best_dist = 1000;\n                \n                for (int i = 0; i < (int)human_targets[idx].size(); i++) {\n                    int tx = human_targets[idx][i].first;\n                    int ty = human_targets[idx][i].second;\n                    int d = abs(tx - hx) + abs(ty - hy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_target = i;\n                    }\n                }\n                \n                if (best_target != -1) {\n                    int tx = human_targets[idx][best_target].first;\n                    int ty = human_targets[idx][best_target].second;\n                    int d = bfs_next_move(hx, hy, tx, ty, occupied);\n                    \n                    if (d != -1) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        actions[idx] = move_cmd[d];\n                        next_pos[idx] = {nx, ny};\n                        // Update occupied for subsequent humans\n                        for (auto& o : occupied) {\n                            if (o.first == hx && o.second == hy) {\n                                o = {nx, ny};\n                                break;\n                            }\n                        }\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                // Defensive: move away from pets if too close\n                int min_dist = nearest_pet_dist(hx, hy);\n                if (min_dist <= 2) {\n                    int best_d = -1;\n                    int max_new_dist = min_dist;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (!is_passable(nx, ny)) continue;\n                        \n                        bool collides = false;\n                        for (auto& o : occupied) {\n                            if (o.first == nx && o.second == ny && !(o.first == hx && o.second == hy)) {\n                                collides = true;\n                                break;\n                            }\n                        }\n                        if (collides) continue;\n                        \n                        int new_dist = 1000;\n                        for (auto& p : pets) {\n                            new_dist = min(new_dist, abs(p.x - nx) + abs(p.y - ny));\n                        }\n                        if (new_dist > max_new_dist) {\n                            max_new_dist = new_dist;\n                            best_d = d;\n                        }\n                    }\n                    if (best_d != -1) {\n                        actions[idx] = move_cmd[best_d];\n                        next_pos[idx] = {hx + dx[best_d], hy + dy[best_d]};\n                        acted = true;\n                    }\n                }\n            }\n            \n            if (!acted) {\n                actions[idx] = '.';\n                next_pos[idx] = {hx, hy};\n            }\n        }\n        \n        // Final conflict resolution for moves\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    // Later human stays\n                    actions[j] = '.';\n                    next_pos[j] = {humans[j].x, humans[j].y};\n                }\n            }\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n        \n        // Update state\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u') blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    double score;\n    double value;\n    array<double, 400> prob;\n    string s;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    const int N = 20;\n    auto ID = [&](int i, int j) { return i * N + j; };\n    const int target = ID(ti, tj);\n    const int start = ID(si, sj);\n    const double q = 1.0 - p;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    const char dc[4] = {'U', 'D', 'L', 'R'};\n    \n    /*------------------------------------------------------------\n        1. Precompute transitions\n      ------------------------------------------------------------*/\n    int nxt[400][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            int id = ID(i, j);\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                bool wall = false;\n                if (dir == 0) wall = (i == 0) ? true : (v[i-1][j] == '1');\n                else if (dir == 1) wall = (i == 19) ? true : (v[i][j] == '1');\n                else if (dir == 2) wall = (j == 0) ? true : (h[i][j-1] == '1');\n                else wall = (j == 19) ? true : (h[i][j] == '1');\n                nxt[id][dir] = wall ? id : ID(ni, nj);\n            }\n        }\n    }\n    \n    /*------------------------------------------------------------\n        2. Closed-loop optimal values V[t][i]\n      ------------------------------------------------------------*/\n    static double V[201][400];\n    for (int i = 0; i < 400; ++i) V[200][i] = 0.0;\n    \n    for (int t = 199; t >= 0; --t) {\n        double turn_score = 401.0 - (t + 1);\n        for (int i = 0; i < 400; ++i) {\n            if (i == target) {\n                V[t][i] = 0.0;\n                continue;\n            }\n            double best_val = 0.0;\n            for (int dir = 0; dir < 4; ++dir) {\n                int to = nxt[i][dir];\n                double reward = (to == target) ? turn_score : V[t+1][to];\n                double val = p * V[t+1][i] + q * reward;\n                if (val > best_val) best_val = val;\n            }\n            V[t][i] = best_val;\n        }\n    }\n    \n    /*------------------------------------------------------------\n        3. Exact evaluation\n      ------------------------------------------------------------*/\n    auto evaluate = [&](const string& s) -> double {\n        array<double, 400> cur, nxt_arr;\n        cur.fill(0.0);\n        cur[start] = 1.0;\n        double score = 0.0;\n        for (int step = 0; step < (int)s.size(); ++step) {\n            nxt_arr.fill(0.0);\n            int dir = (s[step] == 'U') ? 0 : (s[step] == 'D') ? 1 : (s[step] == 'L') ? 2 : 3;\n            double ts = 401.0 - (step + 1);\n            for (int i = 0; i < 400; ++i) {\n                double pr = cur[i];\n                if (pr < 1e-15) continue;\n                nxt_arr[i] += pr * p;\n                int to = nxt[i][dir];\n                if (to == target) score += pr * q * ts;\n                else nxt_arr[to] += pr * q;\n            }\n            cur.swap(nxt_arr);\n        }\n        return score;\n    };\n    \n    /*------------------------------------------------------------\n        4. Beam Search (width 200)\n      ------------------------------------------------------------*/\n    const int BEAM = 200;\n    vector<State> beam;\n    beam.reserve(BEAM * 2);\n    State init;\n    init.score = 0.0;\n    init.prob.fill(0.0);\n    init.prob[start] = 1.0;\n    init.s.clear();\n    init.value = V[0][start];\n    beam.push_back(init);\n    \n    string best_string;\n    double best_score = 0.0;\n    \n    for (int step = 0; step < 200; ++step) {\n        vector<State> cand;\n        cand.reserve(beam.size() * 4);\n        \n        for (const State& st : beam) {\n            if (st.value <= best_score) continue;\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                State ns;\n                ns.score = st.score;\n                ns.prob.fill(0.0);\n                double ts = 401.0 - (step + 1);\n                \n                for (int i = 0; i < 400; ++i) {\n                    double pr = st.prob[i];\n                    if (pr < 1e-15) continue;\n                    ns.prob[i] += pr * p;\n                    int to = nxt[i][dir];\n                    if (to == target) ns.score += pr * q * ts;\n                    else ns.prob[to] += pr * q;\n                }\n                \n                ns.s = st.s + dc[dir];\n                \n                double future = 0.0;\n                for (int i = 0; i < 400; ++i) future += ns.prob[i] * V[step+1][i];\n                ns.value = ns.score + future;\n                \n                if (ns.score > best_score) {\n                    best_score = ns.score;\n                    best_string = ns.s;\n                }\n                cand.push_back(std::move(ns));\n            }\n        }\n        \n        if (cand.empty()) break;\n        \n        if ((int)cand.size() > BEAM) {\n            nth_element(cand.begin(), cand.begin() + BEAM, cand.end(),\n                [](const State& a, const State& b) { return a.value > b.value; });\n            cand.resize(BEAM);\n        }\n        beam.swap(cand);\n    }\n    \n    if (best_string.empty()) {\n        best_string = string(1, dc[0]);\n        best_score = evaluate(best_string);\n    }\n    \n    /*------------------------------------------------------------\n        5. Hill Climbing (5000 evaluations)\n      ------------------------------------------------------------*/\n    string cur_s = best_string;\n    double cur_val = evaluate(cur_s);\n    if (cur_val > best_score) {\n        best_score = cur_val;\n        best_string = cur_s;\n    }\n    \n    const int MAX_EVAL = 5000;\n    int evals = 1;\n    bool improved = true;\n    \n    while (improved && evals < MAX_EVAL) {\n        improved = false;\n        int L = cur_s.size();\n        \n        static array<double, 400> pref[201];\n        static double pref_sc[201];\n        pref[0].fill(0.0);\n        pref[0][start] = 1.0;\n        pref_sc[0] = 0.0;\n        \n        for (int i = 0; i < L; ++i) {\n            pref[i+1].fill(0.0);\n            int dir = (cur_s[i] == 'U') ? 0 : (cur_s[i] == 'D') ? 1 : (cur_s[i] == 'L') ? 2 : 3;\n            double ts = 401.0 - (i + 1);\n            double sc = 0.0;\n            for (int j = 0; j < 400; ++j) {\n                double pr = pref[i][j];\n                if (pr < 1e-15) continue;\n                pref[i+1][j] += pr * p;\n                int to = nxt[j][dir];\n                if (to == target) sc += pr * q * ts;\n                else pref[i+1][to] += pr * q;\n            }\n            pref_sc[i+1] = pref_sc[i] + sc;\n        }\n        \n        for (int pos = 0; pos < L && evals < MAX_EVAL; ++pos) {\n            char orig = cur_s[pos];\n            for (int nd = 0; nd < 4; ++nd) {\n                if (dc[nd] == orig) continue;\n                \n                array<double, 400> dist = pref[pos];\n                double sc = pref_sc[pos];\n                \n                array<double, 400> ndist;\n                ndist.fill(0.0);\n                double ts = 401.0 - (pos + 1);\n                for (int j = 0; j < 400; ++j) {\n                    double pr = dist[j];\n                    if (pr < 1e-15) continue;\n                    ndist[j] += pr * p;\n                    int to = nxt[j][nd];\n                    if (to == target) sc += pr * q * ts;\n                    else ndist[to] += pr * q;\n                }\n                dist = ndist;\n                \n                for (int k = pos + 1; k < L; ++k) {\n                    array<double, 400> ndist2;\n                    ndist2.fill(0.0);\n                    int dir = (cur_s[k] == 'U') ? 0 : (cur_s[k] == 'D') ? 1 : (cur_s[k] == 'L') ? 2 : 3;\n                    double ts2 = 401.0 - (k + 1);\n                    for (int j = 0; j < 400; ++j) {\n                        double pr = dist[j];\n                        if (pr < 1e-15) continue;\n                        ndist2[j] += pr * p;\n                        int to = nxt[j][dir];\n                        if (to == target) sc += pr * q * ts2;\n                        else ndist2[to] += pr * q;\n                    }\n                    dist = ndist2;\n                }\n                ++evals;\n                \n                if (sc > cur_val + 1e-9) {\n                    cur_s[pos] = dc[nd];\n                    cur_val = sc;\n                    improved = true;\n                    if (sc > best_score) {\n                        best_score = sc;\n                        best_string = cur_s;\n                    }\n                    goto restart_hc;\n                }\n            }\n        }\n        restart_hc:;\n    }\n    \n    cout << best_string << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG() { s = chrono::steady_clock::now().time_since_epoch().count(); }\n    inline uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline int rand(int n) { return next() % n; }\n    inline double drand() { return (double)next() / UINT32_MAX; }\n} rng;\n\nconst int rot[8][4] = {\n    {0, 1, 2, 3},\n    {1, 2, 3, 0},\n    {2, 3, 0, 1},\n    {3, 0, 1, 2},\n    {4, 5, 4, 5},\n    {5, 4, 5, 4},\n    {6, 7, 6, 7},\n    {7, 6, 7, 6}\n};\n\nconst int8_t to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nconst int8_t di[4] = {0, -1, 0, 1};\nconst int8_t dj[4] = {-1, 0, 1, 0};\n\nstatic int16_t nxt[3600];\nstatic int16_t dist_arr[3600];\nstatic uint32_t visited[3600];\nstatic uint32_t visit_token = 1;\n\ninline int eval(int& L1, int& L2) {\n    if (++visit_token == 0) {\n        memset(visited, 0, sizeof(visited));\n        visit_token = 1;\n    }\n    \n    L1 = L2 = 0;\n    \n    for (int s = 0; s < 3600; s++) {\n        if (visited[s] == visit_token || nxt[s] < 0) continue;\n        \n        int cur = s;\n        int depth = 0;\n        \n        while (cur >= 0) {\n            if (visited[cur] == visit_token) {\n                if (dist_arr[cur] >= 0) {\n                    int len = depth - dist_arr[cur];\n                    if (len > L1) { L2 = L1; L1 = len; }\n                    else if (len > L2) { L2 = len; }\n                }\n                break;\n            }\n            visited[cur] = visit_token;\n            dist_arr[cur] = depth++;\n            cur = nxt[cur];\n        }\n        \n        cur = s;\n        while (cur >= 0 && visited[cur] == visit_token && dist_arr[cur] >= 0) {\n            dist_arr[cur] = -1;\n            cur = nxt[cur];\n        }\n    }\n    \n    return (L2 > 0) ? L1 * L2 : 0;\n}\n\ninline void build(const array<array<int, 30>, 30>& r, \n                 const array<array<int, 30>, 30>& init) {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = rot[init[i][j]][r[i][j]];\n            int base = (i * 30 + j) * 4;\n            for (int d = 0; d < 4; d++) {\n                int8_t d2 = to[t][d];\n                if (d2 < 0) {\n                    nxt[base + d] = -1;\n                } else {\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) {\n                        nxt[base + d] = -1;\n                    } else {\n                        nxt[base + d] = (ni * 30 + nj) * 4 + ((d2 + 2) & 3);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid init_pattern(array<array<int, 30>, 30>& r, \n                 const array<array<int, 30>, 30>& init, int pattern) {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int t = init[i][j];\n            int best = 0, best_s = -100;\n            \n            for (int rotv = 0; rotv < 4; rotv++) {\n                int rt = rot[t][rotv];\n                int s = 0;\n                \n                if (pattern == 0) {\n                    if (i % 4 < 2) {\n                        if (rt == 6) s = 10;\n                        else if (rt == 4 || rt == 5) s = 5;\n                    } else {\n                        if (rt == 7) s = 10;\n                        else if (rt < 4) s = 3;\n                    }\n                } else if (pattern == 1) {\n                    if (j % 4 < 2) {\n                        if (rt == 7) s = 10;\n                        else if (rt == 4 || rt == 5) s = 5;\n                    } else {\n                        if (rt == 6) s = 10;\n                        else if (rt < 4) s = 3;\n                    }\n                } else if (pattern == 2) {\n                    if ((i + j) % 4 < 2) {\n                        if (rt == 4 || rt == 5) s = 10;\n                        else if (rt < 4) s = 5;\n                    } else {\n                        if (rt == 6 || rt == 7) s = 5;\n                    }\n                } else if (pattern == 3) {\n                    if (rt == 4 || rt == 5) s = 10;\n                    else if (rt == 6 || rt == 7) s = 6;\n                    else s = 3;\n                } else {\n                    if (rt < 4) s = 10;\n                    else if (rt == 4 || rt == 5) s = 6;\n                    else s = 3;\n                }\n                \n                if (s > best_s) {\n                    best_s = s;\n                    best = rotv;\n                }\n            }\n            r[i][j] = best;\n        }\n    }\n}\n\nvoid crossover(array<array<int, 30>, 30>& res,\n               const array<array<int, 30>, 30>& a,\n               const array<array<int, 30>, 30>& b, int type) {\n    if (type == 0) {\n        int i1 = rng.rand(30), i2 = rng.rand(30);\n        int j1 = rng.rand(30), j2 = rng.rand(30);\n        if (i1 > i2) swap(i1, i2);\n        if (j1 > j2) swap(j1, j2);\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                res[i][j] = (i >= i1 && i <= i2 && j >= j1 && j <= j2) ? a[i][j] : b[i][j];\n            }\n        }\n    } else if (type == 1) {\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                res[i][j] = (i % 4 < 2) ? a[i][j] : b[i][j];\n            }\n        }\n    } else if (type == 2) {\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                res[i][j] = (j % 4 < 2) ? a[i][j] : b[i][j];\n            }\n        }\n    } else {\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                res[i][j] = ((i + j) % 2 == 0) ? a[i][j] : b[i][j];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    array<array<int, 30>, 30> init{};\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) init[i][j] = s[j] - '0';\n    }\n    \n    array<array<int, 30>, 30> best{}, cur{};\n    int best_score = -1;\n    int L1, L2;\n    \n    const double TL = 1.95;\n    clock_t start = clock();\n    \n    // Pattern initializations\n    for (int p = 0; p < 5; p++) {\n        init_pattern(cur, init, p);\n        build(cur, init);\n        int s = eval(L1, L2);\n        if (s > best_score) {\n            best_score = s;\n            memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n        }\n    }\n    \n    vector<pair<int, array<array<int, 30>, 30>>> elite;\n    \n    // More restarts with adaptive phase length\n    for (int restart = 0; restart < 120; restart++) {\n        double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n        if (elapsed > TL * 0.65) break;\n        \n        double r = rng.drand();\n        if (r < 0.38 || elite.size() < 2) {\n            for (int i = 0; i < 30; i++)\n                for (int j = 0; j < 30; j++)\n                    cur[i][j] = rng.rand(4);\n        } else if (r < 0.70) {\n            int a = rng.rand(elite.size());\n            int b = rng.rand(elite.size());\n            while (b == a) b = rng.rand(elite.size());\n            crossover(cur, elite[a].second, elite[b].second, rng.rand(4));\n        } else {\n            cur = elite[rng.rand(elite.size())].second;\n            for (int k = 0; k < 35 + rng.rand(35); k++) {\n                cur[rng.rand(30)][rng.rand(30)] = rng.rand(4);\n            }\n        }\n        \n        build(cur, init);\n        int cur_score = eval(L1, L2);\n        \n        if (cur_score > 0) {\n            elite.push_back({cur_score, cur});\n            sort(elite.begin(), elite.end(), greater<pair<int, array<array<int, 30>, 30>>>());\n            if (elite.size() > 7) elite.resize(7);\n        }\n        \n        if (cur_score > best_score) {\n            best_score = cur_score;\n            memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n        }\n        \n        // Adaptive SA - shorter for worse starts\n        double temp = 60.0;\n        int iter = 0;\n        int last_imp = 0;\n        double phase_end = min(elapsed + 0.020, TL * 0.70);\n        \n        while (true) {\n            elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elapsed > phase_end || elapsed > TL * 0.72) break;\n            \n            // 3 mutations per iteration\n            for (int mut = 0; mut < 3; mut++) {\n                int i = rng.rand(30);\n                int j = rng.rand(30);\n                int old = cur[i][j];\n                cur[i][j] = rng.rand(4);\n                if (cur[i][j] == old) continue;\n                \n                build(cur, init);\n                int s = eval(L1, L2);\n                \n                if (s >= cur_score || rng.drand() < exp((s - cur_score) / temp)) {\n                    cur_score = s;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                        last_imp = iter;\n                        \n                        elite.push_back({s, cur});\n                        sort(elite.begin(), elite.end(), greater<pair<int, array<array<int, 30>, 30>>>());\n                        if (elite.size() > 7) elite.resize(7);\n                    }\n                } else {\n                    cur[i][j] = old;\n                }\n            }\n            \n            temp *= 0.998;\n            iter++;\n            \n            if (iter - last_imp > 500) {\n                for (int k = 0; k < 45; k++) {\n                    cur[rng.rand(30)][rng.rand(30)] = rng.rand(4);\n                }\n                build(cur, init);\n                cur_score = eval(L1, L2);\n                last_imp = iter;\n                temp = 40.0;\n            }\n        }\n    }\n    \n    // Intensive greedy optimization\n    memcpy(&cur[0][0], &best[0][0], 900 * sizeof(int));\n    build(cur, init);\n    int cur_score = eval(L1, L2);\n    \n    for (int round = 0; round < 15; round++) {\n        bool improved = false;\n        vector<int> order(900);\n        iota(order.begin(), order.end(), 0);\n        \n        if (round % 6 == 0) shuffle(order.begin(), order.end(), mt19937(rng.next()));\n        else if (round % 6 == 1) reverse(order.begin(), order.end());\n        else if (round % 6 == 2) {\n            for (int i = 0; i < 900; i++) order[i] = 899 - i;\n        } else if (round % 6 == 3) {\n            for (int i = 0; i < 30; i++)\n                for (int j = 0; j < 30; j++)\n                    order[i * 30 + j] = (29 - i) * 30 + j;\n        } else if (round % 6 == 4) {\n            for (int i = 0; i < 30; i++)\n                for (int j = 0; j < 30; j++)\n                    order[i * 30 + j] = i * 30 + (29 - j);\n        } else {\n            for (int i = 0; i < 900; i++) order[i] = rng.rand(900);\n        }\n        \n        for (int idx : order) {\n            double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n            if (elapsed > TL * 0.88) goto output;\n            \n            int i = idx / 30;\n            int j = idx % 30;\n            int old = cur[i][j];\n            \n            for (int rv = 0; rv < 4; rv++) {\n                if (rv == old) continue;\n                cur[i][j] = rv;\n                build(cur, init);\n                int s = eval(L1, L2);\n                if (s > cur_score) {\n                    cur_score = s;\n                    improved = true;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                    }\n                    goto next_tile;\n                }\n            }\n            cur[i][j] = old;\n            next_tile:;\n        }\n        \n        if (!improved) break;\n    }\n    \n    // 2-swap local search\n    memcpy(&cur[0][0], &best[0][0], 900 * sizeof(int));\n    build(cur, init);\n    cur_score = eval(L1, L2);\n    \n    for (int attempt = 0; attempt < 6000; attempt++) {\n        double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n        if (elapsed > TL) break;\n        \n        int i1 = rng.rand(30), j1 = rng.rand(30);\n        int i2 = (i1 + rng.rand(3) - 1 + 30) % 30;\n        int j2 = (j1 + rng.rand(3) - 1 + 30) % 30;\n        \n        int old1 = cur[i1][j1];\n        int old2 = cur[i2][j2];\n        \n        for (int r1 = 0; r1 < 4; r1++) {\n            for (int r2 = 0; r2 < 4; r2++) {\n                if (r1 == old1 && r2 == old2) continue;\n                cur[i1][j1] = r1;\n                cur[i2][j2] = r2;\n                build(cur, init);\n                int s = eval(L1, L2);\n                if (s > cur_score) {\n                    cur_score = s;\n                    if (s > best_score) {\n                        best_score = s;\n                        memcpy(&best[0][0], &cur[0][0], 900 * sizeof(int));\n                    }\n                    goto next_pair;\n                }\n            }\n        }\n        cur[i1][j1] = old1;\n        cur[i2][j2] = old2;\n        next_pair:;\n    }\n    \n    output:\n    string out;\n    out.reserve(900);\n    for (int i = 0; i < 30; i++)\n        for (int j = 0; j < 30; j++)\n            out += char('0' + best[i][j]);\n    cout << out << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, TARGET;\nchrono::time_point<chrono::steady_clock> start_time;\nconst double TL = 2.9;\n\ninline bool timeout() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > TL;\n}\n\nstruct State {\n    array<array<uint8_t, 10>, 10> bd;\n    int er, ec;\n    vector<char> moves;\n    int score;\n    \n    void init(const vector<string>& board) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = board[i][j];\n                bd[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n                if (bd[i][j] == 0) {\n                    er = i;\n                    ec = j;\n                }\n            }\n        }\n        moves.clear();\n        score = calc_score();\n    }\n    \n    inline bool in(int r, int c) const {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    inline char rev(char c) const {\n        return c == 'U' ? 'D' : c == 'D' ? 'U' : c == 'L' ? 'R' : 'L';\n    }\n    \n    inline bool can(char c) const {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else nc++;\n        return in(nr, nc);\n    }\n    \n    inline void move(char c) {\n        int nr = er, nc = ec;\n        if (c == 'U') nr--;\n        else if (c == 'D') nr++;\n        else if (c == 'L') nc--;\n        else nc++;\n        swap(bd[er][ec], bd[nr][nc]);\n        er = nr;\n        ec = nc;\n        moves.push_back(c);\n    }\n    \n    int calc_score() const {\n        int par[100];\n        iota(par, par + N*N, 0);\n        \n        function<int(int)> find = [&](int x) -> int {\n            return par[x] == x ? x : par[x] = find(par[x]);\n        };\n        \n        auto unite = [&](int x, int y) {\n            x = find(x), y = find(y);\n            if (x != y) par[x] = y;\n        };\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N-1; j++) {\n                if (bd[i][j] && bd[i][j+1] && (bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    unite(i*N + j, i*N + j + 1);\n                }\n            }\n        }\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] && bd[i+1][j] && (bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    unite(i*N + j, (i+1)*N + j);\n                }\n            }\n        }\n        \n        int vert[100] = {}, edge[100] = {};\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j]) vert[find(i*N + j)]++;\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N-1; j++) {\n                if (bd[i][j] && bd[i][j+1] && (bd[i][j] & 4) && (bd[i][j+1] & 1)) {\n                    edge[find(i*N + j)]++;\n                }\n            }\n        }\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                if (bd[i][j] && bd[i+1][j] && (bd[i][j] & 8) && (bd[i+1][j] & 2)) {\n                    edge[find(i*N + j)]++;\n                }\n            }\n        }\n        \n        int best = 0;\n        for (int i = 0; i < N*N; i++) {\n            if (vert[i] > 0 && edge[i] == vert[i] - 1) {\n                best = max(best, vert[i]);\n            }\n        }\n        return best;\n    }\n    \n    void copy_from(const State& o) {\n        bd = o.bd;\n        er = o.er;\n        ec = o.ec;\n        moves = o.moves;\n        score = o.score;\n    }\n};\n\n// Run SA with given seed, return best state found\nState run_sa(const vector<string>& board, uint32_t seed, double time_limit) {\n    mt19937 rng(seed);\n    State cur, init;\n    init.init(board);\n    cur.copy_from(init);\n    \n    State best;\n    best.copy_from(cur);\n    \n    const double START_TEMP = 50.0;\n    double temp = START_TEMP;\n    int iter = 0;\n    int no_improve = 0;\n    \n    auto epoch_start = chrono::steady_clock::now();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - epoch_start).count();\n        if (elapsed > time_limit) break;\n        \n        // Reset if path too long or stuck\n        if ((int)cur.moves.size() >= T - 5 || no_improve > 5000) {\n            cur.copy_from(init);\n            temp = START_TEMP;\n            no_improve = 0;\n            continue;\n        }\n        \n        char ban = cur.moves.empty() ? 'X' : cur.rev(cur.moves.back());\n        vector<pair<char, int>> cand;\n        \n        for (char c : {'U', 'D', 'L', 'R'}) {\n            if (c == ban) continue;\n            if (!cur.can(c)) continue;\n            \n            State nxt = cur;\n            nxt.move(c);\n            int sc = nxt.calc_score();\n            cand.push_back({c, sc});\n        }\n        \n        if (cand.empty()) continue;\n        \n        sort(cand.begin(), cand.end(), [](auto& a, auto& b) { return a.second > b.second; });\n        \n        char pick;\n        int new_score;\n        bool accept = false;\n        \n        // Greedy improvement\n        if (cand[0].second > cur.score) {\n            pick = cand[0].first;\n            new_score = cand[0].second;\n            accept = true;\n        }\n        // Equal score - sometimes accept to explore\n        else if (cand[0].second == cur.score && (rng() & 3) == 0) {\n            pick = cand[0].first;\n            new_score = cand[0].second;\n            accept = true;\n        }\n        // SA acceptance\n        else {\n            uniform_int_distribution<int> dist(0, min(2, (int)cand.size()) - 1);\n            int idx = dist(rng);\n            pick = cand[idx].first;\n            new_score = cand[idx].second;\n            \n            if (new_score > cur.score || \n                exp((new_score - cur.score) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            cur.move(pick);\n            cur.score = new_score;\n            \n            if (cur.score > best.score || \n                (cur.score == best.score && cur.score == TARGET && cur.moves.size() < best.moves.size())) {\n                best.copy_from(cur);\n                no_improve = 0;\n            } else {\n                no_improve++;\n            }\n        } else {\n            no_improve++;\n        }\n        \n        temp *= 0.99995;\n        iter++;\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    TARGET = N*N - 1;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    start_time = chrono::steady_clock::now();\n    \n    State global_best;\n    global_best.init(board);\n    \n    int epoch = 0;\n    while (!timeout()) {\n        double remaining = TL - chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (remaining < 0.1) break;\n        \n        // Distribute time: early epochs get more time\n        double epoch_time = min(remaining / 3.0, 0.5);\n        \n        uint32_t seed = chrono::steady_clock::now().time_since_epoch().count() + epoch * 1234567;\n        State result = run_sa(board, seed, epoch_time);\n        \n        if (result.score > global_best.score ||\n            (result.score == global_best.score && result.score == TARGET && result.moves.size() < global_best.moves.size())) {\n            global_best.copy_from(result);\n        }\n        \n        // Early termination if perfect and good length\n        if (global_best.score == TARGET && global_best.moves.size() <= T * 0.5) {\n            break;\n        }\n        \n        epoch++;\n    }\n    \n    // Verify\n    State verify;\n    verify.init(board);\n    for (char c : global_best.moves) {\n        if (!verify.can(c)) {\n            cout << \"\\n\";\n            return 0;\n        }\n        verify.move(c);\n    }\n    \n    string result(global_best.moves.begin(), global_best.moves.end());\n    cout << result << \"\\n\";\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long x1, y1, x2, y2;\n};\n\nint N, K;\nint target[11];\nint cur_cnt[12];\nvector<Point> pts;\nvector<Line> cuts;\nvector<vector<int>> pieces;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint side(const Point& p, const Line& ln) {\n    long long v1x = ln.x2 - ln.x1;\n    long long v1y = ln.y2 - ln.y1;\n    long long v2x = p.x - ln.x1;\n    long long v2y = p.y - ln.y1;\n    __int128 cr = (__int128)v1x * v2y - (__int128)v1y * v2x;\n    if (cr < 0) return -1;\n    if (cr > 0) return 1;\n    return 0;\n}\n\nint calc_delta(int S, int a, int b) {\n    int old_score = 0, new_score = 0;\n    \n    if (S >= 1 && S <= 10) {\n        old_score += min(cur_cnt[S], target[S]);\n        new_score += min(cur_cnt[S] - 1, target[S]);\n    }\n    \n    if (a >= 1 && a <= 10) {\n        old_score += min(cur_cnt[a], target[a]);\n        new_score += min(cur_cnt[a] + 1, target[a]);\n    }\n    \n    if (b >= 1 && b <= 10) {\n        int add_b = (a == b) ? 1 : 0;\n        old_score += min(cur_cnt[b], target[b]);\n        new_score += min(cur_cnt[b] + add_b, target[b]);\n    }\n    \n    return new_score - old_score;\n}\n\nbool valid_line(const Line& ln) {\n    const long long LIM = 1000000000LL;\n    return abs(ln.x1) <= LIM && abs(ln.y1) <= LIM && \n           abs(ln.x2) <= LIM && abs(ln.y2) <= LIM &&\n           !(ln.x1 == ln.x2 && ln.y1 == ln.y2);\n}\n\n// Core split finding with a specific direction\nbool try_direction(const vector<int>& P, int want_left, double dx, double dy, Line& out_ln) {\n    int n = P.size();\n    vector<pair<double, int>> proj;\n    proj.reserve(n);\n    for (int idx : P) {\n        proj.emplace_back(dx * pts[idx].x + dy * pts[idx].y, idx);\n    }\n    \n    nth_element(proj.begin(), proj.begin() + want_left, proj.end());\n    double split = proj[want_left].first;\n    \n    int cnt_l = 0;\n    double max_l = -1e300, min_r = 1e300;\n    int id_l = -1, id_r = -1;\n    \n    for (auto& [v, id] : proj) {\n        if (v < split - 1e-9) {\n            cnt_l++;\n            if (v > max_l) { max_l = v; id_l = id; }\n        } else if (v > split + 1e-9) {\n            if (v < min_r) { min_r = v; id_r = id; }\n        }\n    }\n    \n    for (auto& [v, id] : proj) {\n        if (abs(v - split) < 1e-9) {\n            if (cnt_l < want_left) {\n                cnt_l++;\n                if (v > max_l) { max_l = v; id_l = id; }\n            } else {\n                if (v < min_r) { min_r = v; id_r = id; }\n            }\n        }\n    }\n    \n    if (cnt_l != want_left || id_l == -1 || id_r == -1) return false;\n    if (max_l >= min_r) return false;\n    \n    // Build line perpendicular to (dx,dy) at midpoint\n    double mx = (pts[id_l].x + pts[id_r].x) / 2.0;\n    double my = (pts[id_l].y + pts[id_r].y) / 2.0;\n    double px = -dy, py = dx;\n    \n    Line ln;\n    const double SCALE = 1e6;\n    ln.x1 = (long long)(mx - px * SCALE);\n    ln.y1 = (long long)(my - py * SCALE);\n    ln.x2 = (long long)(mx + px * SCALE);\n    ln.y2 = (long long)(my + py * SCALE);\n    \n    if (!valid_line(ln)) return false;\n    \n    // Verify clean split\n    int cn = 0, cz = 0;\n    for (int idx : P) {\n        int s = side(pts[idx], ln);\n        if (s < 0) cn++;\n        else if (s == 0) cz++;\n    }\n    \n    if (cz > 0) return false;\n    \n    if (cn == want_left) {\n        out_ln = ln;\n        return true;\n    } else if (cn == n - want_left) {\n        swap(ln.x1, ln.x2);\n        swap(ln.y1, ln.y2);\n        out_ln = ln;\n        return true;\n    }\n    return false;\n}\n\n// Try random angles\nbool find_split_random(const vector<int>& P, int want_left, Line& out_ln, int iters) {\n    uniform_real_distribution<double> ang(0.0, 2.0 * M_PI);\n    for (int i = 0; i < iters; i++) {\n        double th = ang(rng);\n        if (try_direction(P, want_left, cos(th), sin(th), out_ln))\n            return true;\n    }\n    return false;\n}\n\n// Try angles from point pairs (more likely to work for hard cases)\nbool find_split_from_points(const vector<int>& P, int want_left, Line& out_ln) {\n    int n = P.size();\n    if (n > 80) return false; // Too slow\n    \n    // Sample points\n    vector<int> samp;\n    int step = max(1, n / 15);\n    for (int i = 0; i < n; i += step) samp.push_back(P[i]);\n    \n    for (int i1 : samp) {\n        for (int i2 : samp) {\n            if (i1 >= i2) continue;\n            // Direction perpendicular to i1-i2\n            double dx = pts[i2].y - pts[i1].y;\n            double dy = pts[i1].x - pts[i2].x;\n            double len = hypot(dx, dy);\n            if (len < 1e-6) continue;\n            \n            if (try_direction(P, want_left, dx/len, dy/len, out_ln))\n                return true;\n        }\n    }\n    return false;\n}\n\nbool find_split(const vector<int>& P, int want_left, Line& out_ln, bool aggressive) {\n    if (want_left <= 0 || want_left >= (int)P.size()) return false;\n    \n    // Try random first\n    int random_iters = aggressive ? 400 : 150;\n    if (find_split_random(P, want_left, out_ln, random_iters)) return true;\n    \n    // Try point-based angles\n    if (find_split_from_points(P, want_left, out_ln)) return true;\n    \n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> target[i];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n    \n    pieces.resize(1);\n    pieces[0].resize(N);\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n    \n    memset(cur_cnt, 0, sizeof(cur_cnt));\n    if (N <= 10) cur_cnt[N] = 1;\n    else cur_cnt[0] = 1;\n    \n    for (int cut_iter = 0; cut_iter < K; cut_iter++) {\n        // Find best piece to split\n        int best_pidx = -1, best_pri = -1;\n        for (int i = 0; i < (int)pieces.size(); i++) {\n            int S = pieces[i].size();\n            if (S <= 1) continue;\n            int pri = S;\n            if (S > 10) pri += 20000;  // Critical\n            else if (cur_cnt[S] > target[S]) pri += 200; // Excess\n            if (pri > best_pri) {\n                best_pri = pri;\n                best_pidx = i;\n            }\n        }\n        if (best_pidx == -1) break;\n        \n        const auto& P = pieces[best_pidx];\n        int S = P.size();\n        bool aggressive = (S > 10) || (S <= 10 && cur_cnt[S] > target[S] + 2);\n        \n        // Build candidate list\n        vector<pair<int, int>> cands; // (delta, a)\n        \n        // Prioritize creating needed pieces\n        for (int need = 1; need <= min(10, S-1); need++) {\n            if (cur_cnt[need] < target[need]) {\n                int other = S - need;\n                int delta = calc_delta(S, need, other);\n                cands.emplace_back(delta, need);\n                // Prioritize if both sides useful\n                if (other >= 1 && other <= 10 && cur_cnt[other] < target[other]) {\n                    cands.emplace_back(delta + 1, need);\n                }\n            }\n        }\n        \n        // Balanced splits as fallback\n        if (cands.empty()) {\n            for (int a = max(1, S/2 - 1); a <= min(S-1, S/2 + 1); a++) {\n                cands.emplace_back(calc_delta(S, a, S-a), a);\n            }\n        }\n        \n        sort(cands.rbegin(), cands.rend());\n        \n        // Remove duplicates\n        vector<pair<int, int>> uniq;\n        for (auto& c : cands) {\n            if (uniq.empty() || uniq.back().second != c.second)\n                uniq.push_back(c);\n        }\n        \n        bool found = false;\n        Line best_ln;\n        int best_a = 0;\n        \n        for (auto& [delta, a] : uniq) {\n            Line ln;\n            if (find_split(P, a, ln, aggressive)) {\n                found = true;\n                best_ln = ln;\n                best_a = a;\n                break;\n            }\n        }\n        \n        if (!found) {\n            // Last resort: try middle split with extra effort\n            if (!find_split(P, S/2, best_ln, true)) {\n                // Try adjacent sizes\n                for (int da = -2; da <= 2 && !found; da++) {\n                    int a = S/2 + da;\n                    if (a <= 0 || a >= S) continue;\n                    if (find_split(P, a, best_ln, true)) {\n                        found = true;\n                        best_a = a;\n                    }\n                }\n            } else {\n                found = true;\n                best_a = S/2;\n            }\n        }\n        \n        if (!found) break;\n        \n        int best_b = S - best_a;\n        \n        // Apply\n        vector<int> left, right;\n        for (int idx : P) {\n            if (side(pts[idx], best_ln) < 0) left.push_back(idx);\n            else right.push_back(idx);\n        }\n        \n        if (S <= 10) cur_cnt[S]--;\n        else cur_cnt[0]--;\n        if (best_a <= 10) cur_cnt[best_a]++;\n        else cur_cnt[0]++;\n        if (best_b <= 10) cur_cnt[best_b]++;\n        else cur_cnt[0]++;\n        \n        pieces[best_pidx] = move(left);\n        pieces.push_back(move(right));\n        cuts.push_back(best_ln);\n    }\n    \n    cout << cuts.size() << \"\\n\";\n    for (auto& ln : cuts) {\n        cout << ln.x1 << \" \" << ln.y1 << \" \" << ln.x2 << \" \" << ln.y2 << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nusing ull = unsigned long long;\nusing ll = long long;\n\nint N, M, C;\nconst double TIME_LIMIT = 4.95;\n\nstatic ull mask_closed[64][64];\nstatic ull mask_open[64][64];\n\nstatic ull dot_row[64];\nstatic ull dot_col[64];\nstatic ull dot_d1[128];\nstatic ull dot_d2[128];\n\nstatic ull edge_h[64];\nstatic ull edge_v[64];\nstatic ull edge_d1[128];\nstatic ull edge_d2[128];\n\nstatic int buf_d1[128][64];\nstatic int buf_d2[128][64];\nstatic int cnt_d1[128];\nstatic int cnt_d2[128];\n\nstatic int d1_idx[64][64];\nstatic int d2_idx[64][64];\n\nstruct Operation {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\nstruct Cand {\n    int x2, y2, x3, y3, x4, y4;\n    int perim;\n    bool axis;\n};\n\ninline double get_time() {\n    return chrono::duration<double>(chrono::steady_clock::now().time_since_epoch()).count();\n}\n\ninline void add_dot(int x, int y) {\n    dot_row[y] |= (1ULL << x);\n    dot_col[x] |= (1ULL << y);\n    dot_d1[d1_idx[x][y]] |= (1ULL << x);\n    dot_d2[d2_idx[x][y]] |= (1ULL << x);\n}\n\ninline void add_edge_h(int y, int l, int r) { edge_h[y] |= mask_closed[l][r-1]; }\ninline void add_edge_v(int x, int l, int r) { edge_v[x] |= mask_closed[l][r-1]; }\ninline void add_edge_d1(int i, int l, int r) { edge_d1[i] |= mask_closed[l][r-1]; }\ninline void add_edge_d2(int i, int l, int r) { edge_d2[i] |= mask_closed[l][r-1]; }\n\ninline bool check_axis(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    if (xl == xr || yl == yr) return false;\n    if (mask_open[xl][xr] & (dot_row[yl] | dot_row[yr])) return false;\n    if (mask_open[yl][yr] & (dot_col[xl] | dot_col[xr])) return false;\n    ull hm = mask_closed[xl][xr-1];\n    if ((edge_h[yl] & hm) || (edge_h[yr] & hm)) return false;\n    ull vm = mask_closed[yl][yr-1];\n    if ((edge_v[xl] & vm) || (edge_v[xr] & vm)) return false;\n    return true;\n}\n\ninline void apply_axis(int x1, int y1, int x2, int y2) {\n    int xl = min(x1, x2), xr = max(x1, x2);\n    int yl = min(y1, y2), yr = max(y1, y2);\n    add_edge_h(yl, xl, xr);\n    add_edge_h(yr, xl, xr);\n    add_edge_v(xl, yl, yr);\n    add_edge_v(xr, yl, yr);\n}\n\ninline bool check_45(const Cand &c, int x1, int y1) {\n    int d1 = d1_idx[x1][y1];\n    int s1 = d2_idx[x1][y1];\n    int d3 = d1_idx[c.x3][c.y3];\n    int s2 = d2_idx[c.x2][c.y2];\n    if (mask_open[min(x1,c.x2)][max(x1,c.x2)] & dot_d1[d1]) return false;\n    if (mask_open[min(c.x2,c.x3)][max(c.x2,c.x3)] & dot_d2[s2]) return false;\n    if (mask_open[min(c.x3,c.x4)][max(c.x3,c.x4)] & dot_d1[d3]) return false;\n    if (mask_open[min(c.x4,x1)][max(c.x4,x1)] & dot_d2[s1]) return false;\n    if (mask_closed[min(x1,c.x2)][max(x1,c.x2)-1] & edge_d1[d1]) return false;\n    if (mask_closed[min(c.x2,c.x3)][max(c.x2,c.x3)-1] & edge_d2[s2]) return false;\n    if (mask_closed[min(c.x3,c.x4)][max(c.x3,c.x4)-1] & edge_d1[d3]) return false;\n    if (mask_closed[min(c.x4,x1)][max(c.x4,x1)-1] & edge_d2[s1]) return false;\n    return true;\n}\n\ninline void apply_45(const Cand &c, int x1, int y1) {\n    int d1 = d1_idx[x1][y1];\n    int s1 = d2_idx[x1][y1];\n    int d3 = d1_idx[c.x3][c.y3];\n    int s2 = d2_idx[c.x2][c.y2];\n    add_edge_d1(d1, min(x1,c.x2), max(x1,c.x2));\n    add_edge_d2(s2, min(c.x2,c.x3), max(c.x2,c.x3));\n    add_edge_d1(d3, min(c.x3,c.x4), max(c.x3,c.x4));\n    add_edge_d2(s1, min(c.x4,x1), max(c.x4,x1));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    C = (N - 1) / 2;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = i; j < N; ++j) {\n            mask_closed[i][j] = ((1ULL << (j - i + 1)) - 1ULL) << i;\n            mask_open[i][j] = (j > i + 1) ? (((1ULL << (j - i - 1)) - 1ULL) << (i + 1)) : 0ULL;\n        }\n    }\n\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y) {\n            d1_idx[x][y] = x - y + (N - 1);\n            d2_idx[x][y] = x + y;\n        }\n\n    vector<pair<int,int>> init;\n    init.reserve(M);\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        init.emplace_back(x, y);\n    }\n\n    static int W[64][64];\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            W[x][y] = (x - C) * (x - C) + (y - C) * (y - C) + 1;\n\n    double start = get_time();\n    vector<Operation> best_ops;\n    ll best_score = -1;\n    unsigned rng_seed = (unsigned)chrono::steady_clock::now().time_since_epoch().count();\n    mt19937 rng(rng_seed);\n\n    static pair<int, pair<int,int>> cells[4000];\n    int cell_cnt = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            cells[cell_cnt++] = {W[x][y], {x, y}};\n\n    sort(cells, cells + cell_cnt, [](const auto& a, const auto& b){ return a.first > b.first; });\n    int high_thresh = cells[cell_cnt * 15 / 100].first;\n\n    while (get_time() - start < TIME_LIMIT) {\n        memset(dot_row, 0, sizeof(ull) * N);\n        memset(dot_col, 0, sizeof(ull) * N);\n        memset(dot_d1, 0, sizeof(ull) * (2 * N));\n        memset(dot_d2, 0, sizeof(ull) * (2 * N));\n        memset(edge_h, 0, sizeof(ull) * N);\n        memset(edge_v, 0, sizeof(ull) * N);\n        memset(edge_d1, 0, sizeof(ull) * (2 * N));\n        memset(edge_d2, 0, sizeof(ull) * (2 * N));\n        memset(cnt_d1, 0, sizeof(int) * (2 * N));\n        memset(cnt_d2, 0, sizeof(int) * (2 * N));\n\n        for (auto &p : init) {\n            int x = p.first, y = p.second;\n            add_dot(x, y);\n            buf_d1[d1_idx[x][y]][cnt_d1[d1_idx[x][y]]++] = x;\n            buf_d2[d2_idx[x][y]][cnt_d2[d2_idx[x][y]]++] = x;\n        }\n\n        int order_type = uniform_int_distribution<int>(0, 2)(rng);\n        if (order_type == 0) {\n            shuffle(cells, cells + cell_cnt, rng);\n            sort(cells, cells + cell_cnt, [](const auto& a, const auto& b){ return a.first > b.first; });\n        } else if (order_type == 1) {\n            shuffle(cells, cells + cell_cnt, rng);\n            sort(cells, cells + cell_cnt, [](const auto& a, const auto& b){ return a.first < b.first; });\n        } else {\n            shuffle(cells, cells + cell_cnt, rng);\n        }\n\n        vector<Operation> ops;\n        ops.reserve(N * N);\n        ll cur_score = 0;\n        for (auto &p : init) cur_score += W[p.first][p.second];\n        int placed = M;\n\n        int strategy = uniform_int_distribution<int>(0, 4)(rng);\n\n        bool progress = true;\n        while (progress) {\n            progress = false;\n            for (int i = 0; i < cell_cnt; ++i) {\n                int x1 = cells[i].second.first;\n                int y1 = cells[i].second.second;\n                int val = cells[i].first;\n                if ((dot_row[y1] >> x1) & 1ULL) continue;\n\n                int d1i = d1_idx[x1][y1];\n                int s1 = d2_idx[x1][y1];\n                if (!dot_row[y1] && !dot_col[x1] && !dot_d1[d1i] && !dot_d2[s1])\n                    continue;\n\n                static Cand cand[15000]; // increased buffer for safety\n                int cnum = 0;\n\n                // Axis-aligned\n                ull rb = dot_row[y1];\n                while (rb) {\n                    int x2 = __builtin_ctzll(rb);\n                    rb &= rb - 1;\n                    if (x2 == x1) continue;\n                    ull cb = dot_col[x1];\n                    while (cb) {\n                        int y2 = __builtin_ctzll(cb);\n                        cb &= cb - 1;\n                        if (y2 == y1) continue;\n                        if ((dot_row[y2] >> x2) & 1ULL) {\n                            int dx = x1 - x2;\n                            int dy = y1 - y2;\n                            int perim = 2 * ((dx < 0 ? -dx : dx) + (dy < 0 ? -dy : dy));\n                            cand[cnum++] = {x2, y1, x2, y2, x1, y2, perim, true};\n                        }\n                    }\n                }\n\n                // 45-degree\n                int n1 = cnt_d1[d1i];\n                int n2 = cnt_d2[s1];\n                int d1_base = x1 - y1;\n                if (n1 <= n2) {\n                    for (int a = 0; a < n1; ++a) {\n                        int x2 = buf_d1[d1i][a];\n                        if (x2 == x1) continue;\n                        int y2 = x2 - d1_base;\n                        if (((dot_row[y2] >> x2) & 1ULL) == 0) continue;\n                        for (int b = 0; b < n2; ++b) {\n                            int x4 = buf_d2[s1][b];\n                            if (x4 == x1) continue;\n                            int y4 = s1 - x4;\n                            if (((dot_row[y4] >> x4) & 1ULL) == 0) continue;\n                            int x3 = x2 + x4 - x1;\n                            int y3 = y2 + y4 - y1;\n                            if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                            if (((dot_row[y3] >> x3) & 1ULL) == 0) continue;\n                            int a1 = x2 - x1, a2 = x4 - x1;\n                            int perim = 2 * ((a1 < 0 ? -a1 : a1) + (a2 < 0 ? -a2 : a2));\n                            cand[cnum++] = {x2, y2, x3, y3, x4, y4, perim, false};\n                        }\n                    }\n                } else {\n                    for (int b = 0; b < n2; ++b) {\n                        int x4 = buf_d2[s1][b];\n                        if (x4 == x1) continue;\n                        int y4 = s1 - x4;\n                        if (((dot_row[y4] >> x4) & 1ULL) == 0) continue;\n                        for (int a = 0; a < n1; ++a) {\n                            int x2 = buf_d1[d1i][a];\n                            if (x2 == x1) continue;\n                            int y2 = x2 - d1_base;\n                            if (((dot_row[y2] >> x2) & 1ULL) == 0) continue;\n                            int x3 = x2 + x4 - x1;\n                            int y3 = y2 + y4 - y1;\n                            if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                            if (((dot_row[y3] >> x3) & 1ULL) == 0) continue;\n                            int a1 = x2 - x1, a2 = x4 - x1;\n                            int perim = 2 * ((a1 < 0 ? -a1 : a1) + (a2 < 0 ? -a2 : a2));\n                            cand[cnum++] = {x2, y2, x3, y3, x4, y4, perim, false};\n                        }\n                    }\n                }\n\n                if (cnum == 0) continue;\n\n                int eff_strat = strategy;\n                if (strategy == 4) {\n                    eff_strat = (val >= high_thresh) ? 1 : 0;\n                }\n\n                int best_idx = 0;\n                if (eff_strat == 0) { // min perim\n                    for (int k = 1; k < cnum; ++k)\n                        if (cand[k].perim < cand[best_idx].perim) best_idx = k;\n                } else if (eff_strat == 1) { // max perim\n                    for (int k = 1; k < cnum; ++k)\n                        if (cand[k].perim > cand[best_idx].perim) best_idx = k;\n                } else if (eff_strat == 2) { // prefer axis, min perim among axis\n                    best_idx = -1;\n                    int best_p = INT_MAX;\n                    for (int k = 0; k < cnum; ++k) {\n                        if (cand[k].axis && cand[k].perim < best_p) {\n                            best_idx = k;\n                            best_p = cand[k].perim;\n                        }\n                    }\n                    if (best_idx == -1) {\n                        best_idx = 0;\n                        for (int k = 1; k < cnum; ++k)\n                            if (cand[k].perim < cand[best_idx].perim) best_idx = k;\n                    }\n                } else { // prefer 45, max perim among 45\n                    best_idx = -1;\n                    int best_p = -1;\n                    for (int k = 0; k < cnum; ++k) {\n                        if (!cand[k].axis && cand[k].perim > best_p) {\n                            best_idx = k;\n                            best_p = cand[k].perim;\n                        }\n                    }\n                    if (best_idx == -1) {\n                        best_idx = 0;\n                        for (int k = 1; k < cnum; ++k)\n                            if (cand[k].perim > cand[best_idx].perim) best_idx = k;\n                    }\n                }\n                swap(cand[0], cand[best_idx]);\n\n                for (int k = 0; k < cnum; ++k) {\n                    const Cand &c = cand[k];\n                    bool ok;\n                    if (c.axis) {\n                        ok = check_axis(x1, y1, c.x3, c.y3);\n                        if (ok) apply_axis(x1, y1, c.x3, c.y3);\n                    } else {\n                        ok = check_45(c, x1, y1);\n                        if (ok) apply_45(c, x1, y1);\n                    }\n                    if (ok) {\n                        ops.push_back({x1, y1, c.x2, c.y2, c.x3, c.y3, c.x4, c.y4});\n                        add_dot(x1, y1);\n                        int id1 = d1_idx[x1][y1];\n                        int id2 = d2_idx[x1][y1];\n                        buf_d1[id1][cnt_d1[id1]++] = x1;\n                        buf_d2[id2][cnt_d2[id2]++] = x1;\n                        cur_score += val;\n                        ++placed;\n                        progress = true;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            best_ops = ops;\n        }\n        if (placed == N * N) break;\n    }\n\n    cout << best_ops.size() << '\\n';\n    for (auto &op : best_ops) {\n        cout << op.x1 << ' ' << op.y1 << ' '\n             << op.x2 << ' ' << op.y2 << ' '\n             << op.x3 << ' ' << op.y3 << ' '\n             << op.x4 << ' ' << op.y4 << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed = chrono::steady_clock::now().time_since_epoch().count()) {\n        s = seed;\n    }\n    uint64_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return s;\n    }\n    int randint(int n) {\n        return next() % n;\n    }\n} rng;\n\nstruct Grid {\n    uint8_t a[10][10];\n    \n    Grid() {\n        memset(a, 0, sizeof(a));\n    }\n    \n    void place(int p, int f) {\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void placeRandom(int f, int numEmpty) {\n        int p = rng.randint(numEmpty) + 1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) {\n                    if (--p == 0) {\n                        a[i][j] = f;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') {\n            for (int j = 0; j < 10; j++) {\n                int write = 0;\n                for (int i = 0; i < 10; i++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write++][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'B') {\n            for (int j = 0; j < 10; j++) {\n                int write = 9;\n                for (int i = 9; i >= 0; i--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[write--][j] = val;\n                    }\n                }\n            }\n        } else if (dir == 'L') {\n            for (int i = 0; i < 10; i++) {\n                int write = 0;\n                for (int j = 0; j < 10; j++) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write++] = val;\n                    }\n                }\n            }\n        } else if (dir == 'R') {\n            for (int i = 0; i < 10; i++) {\n                int write = 9;\n                for (int j = 9; j >= 0; j--) {\n                    if (a[i][j] != 0) {\n                        uint8_t val = a[i][j];\n                        a[i][j] = 0;\n                        a[i][write--] = val;\n                    }\n                }\n            }\n        }\n    }\n    \n    int countEmpty() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++)\n            for (int j = 0; j < 10; j++)\n                if (a[i][j] == 0) cnt++;\n        return cnt;\n    }\n    \n    long long calcScore() const {\n        bool vis[10][10] = {};\n        long long res = 0;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] != 0 && !vis[i][j]) {\n                    uint8_t f = a[i][j];\n                    int sz = 0;\n                    int q[100];\n                    int qe = 0;\n                    q[qe++] = i * 10 + j;\n                    vis[i][j] = true;\n                    \n                    while (qe > 0) {\n                        int cur = q[--qe];\n                        int x = cur / 10, y = cur % 10;\n                        sz++;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !vis[nx][ny] && a[nx][ny] == f) {\n                                vis[nx][ny] = true;\n                                q[qe++] = nx * 10 + ny;\n                            }\n                        }\n                    }\n                    res += 1LL * sz * sz;\n                }\n            }\n        }\n        return res;\n    }\n    \n    // Fast heuristic: count same-flavor adjacent pairs\n    int countEdges() const {\n        int cnt = 0;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (a[i][j] == 0) continue;\n                if (i < 9 && a[i][j] == a[i+1][j]) cnt++;\n                if (j < 9 && a[i][j] == a[i][j+1]) cnt++;\n            }\n        }\n        return cnt;\n    }\n    \n    // Greedy tilt: choose direction maximizing edges\n    char greedyTilt() {\n        char bestDir = 'F';\n        int bestEdges = -1;\n        char dirs[4] = {'F', 'B', 'L', 'R'};\n        \n        for (int d = 0; d < 4; d++) {\n            Grid tmp = *this;\n            tmp.tilt(dirs[d]);\n            int e = tmp.countEdges();\n            if (e > bestEdges) {\n                bestEdges = e;\n                bestDir = dirs[d];\n            }\n        }\n        return bestDir;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> f[i];\n    }\n    \n    Grid grid;\n    const char dirs[4] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        grid.place(p, f[t]);\n        \n        if (t == 99) {\n            cout << \"F\\n\" << flush;\n            break;\n        }\n        \n        int remaining = 99 - t;\n        // Adaptive samples: more samples early when structure matters\n        int samples = max(15, min(50, 2000 / (remaining + 5)));\n        \n        long long bestTotal = -1;\n        char bestDir = 'F';\n        \n        // Try each direction for the current tilt\n        for (int d = 0; d < 4; d++) {\n            long long totalScore = 0;\n            \n            for (int s = 0; s < samples; s++) {\n                Grid sim = grid;\n                sim.tilt(dirs[d]);\n                int numEmpty = 100 - (t + 1);\n                \n                // Rollout with greedy policy\n                for (int tt = t + 1; tt < 100; tt++) {\n                    sim.placeRandom(f[tt], numEmpty--);\n                    char gdir = sim.greedyTilt();\n                    sim.tilt(gdir);\n                }\n                \n                totalScore += sim.calcScore();\n            }\n            \n            if (totalScore > bestTotal) {\n                bestTotal = totalScore;\n                bestDir = dirs[d];\n            }\n        }\n        \n        cout << bestDir << \"\\n\" << flush;\n        grid.tilt(bestDir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nvector<double> extract_features(const vector<bitset<100>>& adj, int N) {\n    vector<double> features;\n    features.reserve(2 * N + 10);\n    \n    // 1. Sorted degrees\n    vector<int> degs(N);\n    for (int i = 0; i < N; ++i) degs[i] = adj[i].count();\n    sort(degs.begin(), degs.end());\n    for (int d : degs) features.push_back(d);\n    \n    // 2. Laplacian eigenvalues\n    Eigen::MatrixXd L = Eigen::MatrixXd::Zero(N, N);\n    for (int i = 0; i < N; ++i) {\n        L(i, i) = degs[i];\n        for (int j = i + 1; j < N; ++j) {\n            if (adj[i][j]) {\n                L(i, j) = L(j, i) = -1.0;\n            }\n        }\n    }\n    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(L);\n    Eigen::VectorXd eig = solver.eigenvalues();\n    sort(eig.data(), eig.data() + N);\n    for (int i = 0; i < N; ++i) features.push_back(eig[i]);\n    \n    // 3. Number of triangles (normalized)\n    long long triangles = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (!adj[i][j]) continue;\n            for (int k = j + 1; k < N; ++k) {\n                if (adj[i][k] && adj[j][k]) triangles++;\n            }\n        }\n    }\n    features.push_back((double)triangles / (N * (N - 1) * (N - 2) / 6.0));\n    \n    // 4. Clustering coefficient approximation\n    double cc = 0;\n    int valid = 0;\n    for (int i = 0; i < N; ++i) {\n        int d = degs[i];\n        if (d < 2) continue;\n        valid++;\n        long long local_tri = 0;\n        vector<int> neighbors;\n        for (int j = 0; j < N; ++j) if (adj[i][j]) neighbors.push_back(j);\n        for (int u = 0; u < (int)neighbors.size(); ++u) {\n            for (int v = u + 1; v < (int)neighbors.size(); ++v) {\n                if (adj[neighbors[u]][neighbors[v]]) local_tri++;\n            }\n        }\n        cc += (double)local_tri / (d * (d - 1) / 2);\n    }\n    features.push_back(valid > 0 ? cc / valid : 0);\n    \n    return features;\n}\n\ndouble feature_dist(const vector<double>& a, const vector<double>& b, double eps) {\n    // Normalize by expected noise scale\n    double dist = 0;\n    // Degrees: first N features, variance scales with N*eps*(1-eps)\n    double deg_scale = max(1.0, sqrt(a.size() * eps * (1 - eps) * 0.5));\n    // Eigenvalues: scale with N\n    double eig_scale = max(1.0, a.size() * 0.5);\n    \n    int N = (a.size() - 2) / 2;\n    for (int i = 0; i < N; ++i) {\n        double d = (a[i] - b[i]) / deg_scale;\n        dist += d * d;\n    }\n    for (int i = N; i < 2 * N; ++i) {\n        double d = (a[i] - b[i]) / eig_scale;\n        dist += d * d;\n    }\n    // Global features\n    dist += (a[2*N] - b[2*N]) * (a[2*N] - b[2*N]) * 10;\n    dist += (a[2*N+1] - b[2*N+1]) * (a[2*N+1] - b[2*N+1]) * 10;\n    \n    return sqrt(dist);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Adaptive N: larger N for higher epsilon\n    int N;\n    if (eps < 0.10) N = 20;\n    else if (eps < 0.20) N = 30;\n    else if (eps < 0.30) N = 50;\n    else if (eps < 0.35) N = 80;\n    else N = 100;\n    \n    if (N > 100) N = 100;\n    if (N < 4) N = 4;\n    \n    // Generate reference graphs with diverse structure\n    vector<vector<bitset<100>>> refs(M, vector<bitset<100>>(N));\n    vector<vector<double>> ref_features(M);\n    vector<string> ref_strs(M);\n    \n    // Use different graph models for diversity\n    for (int i = 0; i < M; ++i) {\n        mt19937 gen(i * 1234567 + 42);\n        \n        // Mix of random graphs and structured graphs\n        if (i < M / 2) {\n            // G(n,p) with varying p\n            double p = 0.3 + 0.4 * (i % 5) / 4.0;  // 0.3 to 0.7\n            bernoulli_distribution d(p);\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (d(gen)) {\n                        refs[i][u].set(v);\n                        refs[i][v].set(u);\n                    }\n                }\n            }\n        } else {\n            // Random regular-like or stochastic block model\n            bernoulli_distribution d(0.5);\n            int blocks = 2 + (i % 4);\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    bool edge = d(gen);\n                    // Bias based on block membership\n                    if ((u % blocks) == (v % blocks)) {\n                        edge = (edge || d(gen));  // higher intra-block density\n                    }\n                    if (edge) {\n                        refs[i][u].set(v);\n                        refs[i][v].set(u);\n                    }\n                }\n            }\n        }\n        \n        ref_features[i] = extract_features(refs[i], N);\n        \n        string s;\n        s.reserve(N * (N - 1) / 2);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s.push_back(refs[i][u][v] ? '1' : '0');\n            }\n        }\n        ref_strs[i] = s;\n    }\n    \n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << ref_strs[i] << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        vector<bitset<100>> h_adj(N);\n        int pos = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (h_str[pos++] == '1') {\n                    h_adj[u].set(v);\n                    h_adj[v].set(u);\n                }\n            }\n        }\n        \n        auto h_feat = extract_features(h_adj, N);\n        \n        // Find best match\n        int best_idx = 0;\n        double best_dist = 1e300;\n        \n        for (int i = 0; i < M; ++i) {\n            double d = feature_dist(ref_features[i], h_feat, eps);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        \n        cout << best_idx << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    const long long INF = (long long)1e12;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Criticality\n    vector<double> crit(M, 0.0);\n    const int SAMPLES = 300;\n    \n    for (int iter = 0; iter < SAMPLES; iter++) {\n        int s = rng() % N;\n        vector<long long> dist(N, INF);\n        vector<int> parent(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            for (auto [v, eid] : adj[u]) {\n                int w = edges[eid].w;\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    parent[v] = eid;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (v != s && parent[v] >= 0) {\n                crit[parent[v]] += 1.0;\n            }\n        }\n    }\n    \n    double max_crit = *max_element(crit.begin(), crit.end());\n    if (max_crit > 0) {\n        for (int i = 0; i < M; i++) crit[i] /= max_crit;\n    }\n    \n    // Build adjacency (distance 1) and distance-2 neighbors\n    vector<vector<int>> vertex_edges(N);\n    for (int i = 0; i < M; i++) {\n        vertex_edges[edges[i].u].push_back(i);\n        vertex_edges[edges[i].v].push_back(i);\n    }\n    \n    vector<vector<int>> edge_adj(M);\n    vector<unordered_set<int>> edge_dist2(M);\n    \n    for (int i = 0; i < M; i++) {\n        unordered_set<int> dist1;\n        for (int v : {edges[i].u, edges[i].v}) {\n            for (int e : vertex_edges[v]) {\n                if (e != i) dist1.insert(e);\n            }\n        }\n        edge_adj[i] = vector<int>(dist1.begin(), dist1.end());\n        \n        // Distance 2: neighbors of neighbors\n        for (int nb : edge_adj[i]) {\n            for (int v : {edges[nb].u, edges[nb].v}) {\n                for (int e2 : vertex_edges[v]) {\n                    if (e2 != i && e2 != nb && !dist1.count(e2)) {\n                        edge_dist2[i].insert(e2);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Greedy initialization with conflict avoidance\n    vector<int> assign(M, -1);\n    vector<vector<int>> day_edges(D);\n    vector<double> day_sum(D, 0.0);\n    vector<unordered_set<int>> day_edge_set(D);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return crit[a] > crit[b]; });\n    \n    for (int eid : order) {\n        int best_day = -1;\n        double best_cost = 1e300;\n        for (int d = 0; d < D; d++) {\n            if ((int)day_edges[d].size() >= K) continue;\n            double new_sum = day_sum[d] + crit[eid];\n            \n            // Count conflicts at distance 1 and 2\n            int conflict = 0;\n            for (int other : edge_adj[eid]) {\n                if (day_edge_set[d].count(other)) conflict += 2; // Strong weight for adjacent\n            }\n            for (int other : edge_dist2[eid]) {\n                if (day_edge_set[d].count(other)) conflict += 1; // Weaker for dist-2\n            }\n            \n            double cost = new_sum * new_sum + conflict * 0.3;\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_day = d;\n            }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if ((int)day_edges[d].size() < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n        }\n        assign[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_edge_set[best_day].insert(eid);\n        day_sum[best_day] += crit[eid];\n    }\n    \n    // Setup for local search\n    vector<int> best_assign = assign;\n    double best_obj = 0;\n    for (int d = 0; d < D; d++) best_obj += day_sum[d] * day_sum[d];\n    \n    vector<int> pos(M, -1);\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < (int)day_edges[d].size(); i++) {\n            pos[day_edges[d][i]] = i;\n        }\n    }\n    \n    auto start = chrono::steady_clock::now();\n    const double TL = 5.7;\n    \n    int no_improve = 0;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TL) break;\n        \n        bool improved = false;\n        \n        // Batch of hill climbing steps\n        for (int step = 0; step < 5000 && !improved; step++) {\n            // 60% swaps, 40% moves\n            if (uniform_real_distribution<double>(0,1)(rng) < 0.6) {\n                int e1 = rng() % M;\n                int d1 = assign[e1];\n                int e2, d2;\n                int att = 0;\n                do {\n                    e2 = rng() % M;\n                    d2 = assign[e2];\n                } while (d1 == d2 && ++att < 5);\n                if (d1 == d2) continue;\n                \n                double s1 = day_sum[d1], s2 = day_sum[d2];\n                double ns1 = s1 - crit[e1] + crit[e2];\n                double ns2 = s2 - crit[e2] + crit[e1];\n                \n                double delta = (ns1*ns1 + ns2*ns2) - (s1*s1 + s2*s2);\n                \n                if (delta < -0.001) {\n                    swap(day_edges[d1][pos[e1]], day_edges[d2][pos[e2]]);\n                    swap(pos[e1], pos[e2]);\n                    swap(assign[e1], assign[e2]);\n                    day_sum[d1] = ns1;\n                    day_sum[d2] = ns2;\n                    improved = true;\n                }\n            } else {\n                int e = rng() % M;\n                int from = assign[e];\n                if (day_edges[from].size() <= 1) continue;\n                \n                int to = rng() % D;\n                if (to == from || (int)day_edges[to].size() >= K) continue;\n                \n                double s_from = day_sum[from], s_to = day_sum[to];\n                double ns_from = s_from - crit[e];\n                double ns_to = s_to + crit[e];\n                \n                double delta = (ns_from*ns_from + ns_to*ns_to) - (s_from*s_from + s_to*s_to);\n                \n                if (delta < -0.001) {\n                    int p = pos[e];\n                    day_edges[from][p] = day_edges[from].back();\n                    pos[day_edges[from][p]] = p;\n                    day_edges[from].pop_back();\n                    \n                    pos[e] = day_edges[to].size();\n                    day_edges[to].push_back(e);\n                    assign[e] = to;\n                    day_sum[from] = ns_from;\n                    day_sum[to] = ns_to;\n                    improved = true;\n                }\n            }\n        }\n        \n        if (improved) {\n            no_improve = 0;\n            double curr_obj = 0;\n            for (int d = 0; d < D; d++) curr_obj += day_sum[d] * day_sum[d];\n            if (curr_obj < best_obj) {\n                best_obj = curr_obj;\n                best_assign = assign;\n            }\n        } else {\n            no_improve++;\n            if (no_improve >= 10) {\n                // Gentle diversification: swap 10 random pairs\n                for (int p = 0; p < 10; p++) {\n                    int e1 = rng() % M;\n                    int d1 = assign[e1];\n                    int e2, d2;\n                    do {\n                        e2 = rng() % M;\n                        d2 = assign[e2];\n                    } while (d1 == d2);\n                    \n                    swap(day_edges[d1][pos[e1]], day_edges[d2][pos[e2]]);\n                    swap(pos[e1], pos[e2]);\n                    swap(assign[e1], assign[e2]);\n                    day_sum[d1] = day_sum[d1] - crit[e1] + crit[e2];\n                    day_sum[d2] = day_sum[d2] - crit[e2] + crit[e1];\n                }\n                no_improve = 0;\n            }\n        }\n    }\n    \n    // Restore best\n    assign = best_assign;\n    day_edges = vector<vector<int>>(D);\n    for (int i = 0; i < M; i++) {\n        day_edges[assign[i]].push_back(i);\n    }\n    \n    // Fix constraints\n    for (int d = 0; d < D; d++) {\n        while ((int)day_edges[d].size() > K) {\n            int e = day_edges[d].back();\n            day_edges[d].pop_back();\n            for (int d2 = 0; d2 < D; d2++) {\n                if ((int)day_edges[d2].size() < K) {\n                    day_edges[d2].push_back(e);\n                    assign[e] = d2;\n                    break;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << assign[i] + 1;\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<array<array<int,3>,3>> rotations;\n\nvoid init_rotations() {\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int parity[6] = {1, -1, -1, 1, 1, -1};\n    for (int p=0; p<6; p++) {\n        for (int sx : {1, -1}) {\n            for (int sy : {1, -1}) {\n                for (int sz : {1, -1}) {\n                    if (sx * sy * sz * parity[p] == 1) {\n                        array<array<int,3>,3> mat = {};\n                        mat[0][perms[p][0]] = sx;\n                        mat[1][perms[p][1]] = sy;\n                        mat[2][perms[p][2]] = sz;\n                        rotations.push_back(mat);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvector<array<int,3>> normalize_shape(vector<array<int,3>> cells) {\n    if (cells.empty()) return cells;\n    int minx = 1e9, miny = 1e9, minz = 1e9;\n    for (auto& c : cells) {\n        minx = min(minx, c[0]);\n        miny = min(miny, c[1]);\n        minz = min(minz, c[2]);\n    }\n    for (auto& c : cells) {\n        c[0] -= minx;\n        c[1] -= miny;\n        c[2] -= minz;\n    }\n    vector<vector<array<int,3>>> candidates;\n    for (auto& rot : rotations) {\n        vector<array<int,3>> cur;\n        for (auto& c : cells) {\n            int x = c[0], y = c[1], z = c[2];\n            int nx = rot[0][0]*x + rot[0][1]*y + rot[0][2]*z;\n            int ny = rot[1][0]*x + rot[1][1]*y + rot[1][2]*z;\n            int nz = rot[2][0]*x + rot[2][1]*y + rot[2][2]*z;\n            cur.push_back({nx, ny, nz});\n        }\n        int mix = 1e9, miy = 1e9, miz = 1e9;\n        for (auto& c : cur) {\n            mix = min(mix, c[0]);\n            miy = min(miy, c[1]);\n            miz = min(miz, c[2]);\n        }\n        for (auto& c : cur) {\n            c[0] -= mix;\n            c[1] -= miy;\n            c[2] -= miz;\n        }\n        sort(cur.begin(), cur.end());\n        candidates.push_back(cur);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\nstruct Component {\n    vector<array<int,3>> cells;\n    vector<array<int,3>> shape;\n    int id;\n};\n\nvector<Component> extract_components(const vector<vector<vector<bool>>>& valid) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<Component> comps;\n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (valid[x][y][z] && !vis[x][y][z]) {\n                    Component comp;\n                    queue<array<int,3>> q;\n                    q.push({x,y,z});\n                    vis[x][y][z] = true;\n                    while (!q.empty()) {\n                        auto cur = q.front(); q.pop();\n                        comp.cells.push_back(cur);\n                        int cx=cur[0], cy=cur[1], cz=cur[2];\n                        for (int dir=0; dir<6; dir++) {\n                            int nx=cx+dx[dir], ny=cy+dy[dir], nz=cz+dz[dir];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && valid[nx][ny][nz] && !vis[nx][ny][nz]) {\n                                vis[nx][ny][nz] = true;\n                                q.push({nx,ny,nz});\n                            }\n                        }\n                    }\n                    comp.shape = normalize_shape(comp.cells);\n                    comps.push_back(comp);\n                }\n            }\n        }\n    }\n    return comps;\n}\n\n// Improved reduction: prioritize removing leaf nodes to preserve connectivity\nvoid reduce_set_improved(vector<vector<vector<bool>>>& cells, \n                const vector<vector<vector<bool>>>& base,\n                const vector<string>& f, const vector<string>& r) {\n    vector<vector<int>> front(D, vector<int>(D, 0));\n    vector<vector<int>> right(D, vector<int>(D, 0));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (base[x][y][z] || cells[x][y][z]) {\n                    front[z][x]++;\n                    right[z][y]++;\n                }\n            }\n        }\n    }\n    \n    int dx[6] = {1,-1,0,0,0,0};\n    int dy[6] = {0,0,1,-1,0,0};\n    int dz[6] = {0,0,0,0,1,-1};\n    \n    // Compute initial degrees\n    vector<vector<vector<int>>> degree(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (!cells[x][y][z]) continue;\n                for (int dir=0; dir<6; dir++) {\n                    int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                    if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz])\n                        degree[x][y][z]++;\n                }\n            }\n        }\n    }\n    \n    // Priority: degree (lower first), prefer leaves\n    using T = tuple<int, int, int, int>; // degree, x, y, z\n    priority_queue<T, vector<T>, greater<T>> pq;\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (cells[x][y][z] && front[z][x] > 1 && right[z][y] > 1) {\n                    pq.push({degree[x][y][z], x, y, z});\n                }\n            }\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [d, x, y, z] = pq.top(); pq.pop();\n        if (!cells[x][y][z]) continue;\n        if (front[z][x] <= 1 || right[z][y] <= 1) continue;\n        \n        // Remove the cell\n        cells[x][y][z] = false;\n        front[z][x]--;\n        right[z][y]--;\n        \n        // Update neighbors\n        for (int dir=0; dir<6; dir++) {\n            int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && cells[nx][ny][nz]) {\n                degree[nx][ny][nz]--;\n                if (front[nz][nx] > 1 && right[nz][ny] > 1) {\n                    pq.push({degree[nx][ny][nz], nx, ny, nz});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotations();\n    \n    cin >> D;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i=0; i<2; i++) {\n        for (int j=0; j<D; j++) cin >> f[i][j];\n        for (int j=0; j<D; j++) cin >> r[i][j];\n    }\n    \n    vector<vector<vector<bool>>> P1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> P2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1') P1[x][y][z] = true;\n                if (f[1][z][x] == '1' && r[1][z][y] == '1') P2[x][y][z] = true;\n            }\n        }\n    }\n    \n    vector<vector<vector<bool>>> C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> R2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    for (int x=0; x<D; x++) {\n        for (int y=0; y<D; y++) {\n            for (int z=0; z<D; z++) {\n                if (P1[x][y][z] && P2[x][y][z]) C[x][y][z] = true;\n                else if (P1[x][y][z]) R1[x][y][z] = true;\n                else if (P2[x][y][z]) R2[x][y][z] = true;\n            }\n        }\n    }\n    \n    reduce_set_improved(R1, C, f[0], r[0]);\n    reduce_set_improved(R2, C, f[1], r[1]);\n    \n    auto compsC = extract_components(C);\n    auto compsR1 = extract_components(R1);\n    auto compsR2 = extract_components(R2);\n    \n    int n = 0;\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto idx = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n    \n    for (auto& comp : compsC) {\n        n++;\n        for (auto& c : comp.cells) {\n            b1[idx(c[0], c[1], c[2])] = n;\n            b2[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    map<vector<array<int,3>>, vector<Component*>> shape_map;\n    for (auto& comp : compsR1) {\n        shape_map[comp.shape].push_back(&comp);\n    }\n    \n    vector<Component*> unmatched_R2;\n    for (auto& comp : compsR2) {\n        auto& vec = shape_map[comp.shape];\n        if (!vec.empty()) {\n            Component* c1 = vec.back();\n            vec.pop_back();\n            n++;\n            for (auto& c : c1->cells) b1[idx(c[0], c[1], c[2])] = n;\n            for (auto& c : comp.cells) b2[idx(c[0], c[1], c[2])] = n;\n        } else {\n            unmatched_R2.push_back(&comp);\n        }\n    }\n    \n    for (auto& [shape, vec] : shape_map) {\n        for (auto* comp : vec) {\n            n++;\n            for (auto& c : comp->cells) b1[idx(c[0], c[1], c[2])] = n;\n        }\n    }\n    \n    for (auto* comp : unmatched_R2) {\n        n++;\n        for (auto& c : comp->cells) b2[idx(c[0], c[1], c[2])] = n;\n    }\n    \n    cout << n << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0; i<D*D*D; i++) {\n        if (i) cout << \" \";\n        cout << b2[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {int x, y;};\nstruct Edge{int u, v; int w;};\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    void unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a!=b) p[a]=b;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<Point> V(N);\n    for(int i=0;i<N;i++) cin>>V[i].x>>V[i].y;\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++) {\n        int u,v,w;\n        cin>>u>>v>>w;\n        u--; v--;\n        edges[i] = {u,v,w};\n        adj[u].push_back({v,i});\n        adj[v].push_back({u,i});\n    }\n    vector<Point> R(K);\n    for(int i=0;i<K;i++) cin>>R[i].x>>R[i].y;\n    \n    const int COVER_DIST2 = 5000*5000;\n    const long long INF = (1LL<<60);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Precompute shortest paths\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    vector<vector<int>> parent_edge(N, vector<int>(N, -1));\n    \n    for(int s=0; s<N; s++) {\n        distV[s][s] = 0;\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u] = pq.top(); pq.pop();\n            if(d!=distV[s][u]) continue;\n            for(auto [v,eid]: adj[u]){\n                long long nd = d + edges[eid].w;\n                if(nd < distV[s][v]){\n                    distV[s][v] = nd;\n                    parent_edge[s][v] = eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // Precompute data\n    vector<vector<int>> needP(K, vector<int>(N));\n    vector<vector<int>> sortedVertices(K);\n    vector<vector<int>> coverList(N);\n    \n    for(int i=0;i<K;i++){\n        vector<pair<long long,int>> tmp;\n        for(int j=0;j<N;j++){\n            long long dx = (long long)R[i].x - V[j].x;\n            long long dy = (long long)R[i].y - V[j].y;\n            long long d2 = dx*dx + dy*dy;\n            needP[i][j] = (int)ceil(sqrt((double)d2) - 1e-9);\n            if(d2 <= COVER_DIST2) {\n                tmp.push_back({d2, j});\n                coverList[j].push_back(i);\n            }\n        }\n        sort(tmp.begin(), tmp.end());\n        for(auto& p: tmp) sortedVertices[i].push_back(p.second);\n    }\n    \n    // Fast evaluation\n    vector<int> maxP_buf(N);\n    vector<char> inSet_buf(N);\n    \n    auto evaluate = [&](const vector<int>& S)->pair<long long, bool>{\n        int sz = (int)S.size();\n        if(sz==0) return {INF, false};\n        \n        fill(maxP_buf.begin(), maxP_buf.end(), 0);\n        fill(inSet_buf.begin(), inSet_buf.end(), 0);\n        for(int v: S) inSet_buf[v] = 1;\n        \n        for(int r=0;r<K;r++){\n            int bestv = -1;\n            for(int v: sortedVertices[r]){\n                if(inSet_buf[v]){\n                    bestv = v;\n                    break;\n                }\n            }\n            if(bestv==-1) return {INF, false};\n            maxP_buf[bestv] = max(maxP_buf[bestv], needP[r][bestv]);\n        }\n        \n        long long fac_cost = 0;\n        for(int v: S) fac_cost += 1LL*maxP_buf[v]*maxP_buf[v];\n        \n        // More accurate tree cost estimation using actual edge costs via metric closure\n        long long tree_cost = 0;\n        if(sz > 1){\n            static vector<long long> min_dist;\n            static vector<char> used;\n            min_dist.assign(sz, INF);\n            used.assign(sz, 0);\n            min_dist[0] = 0;\n            \n            for(int iter=0; iter<sz; iter++){\n                int v = -1;\n                for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_dist[i]<min_dist[v])) v=i;\n                used[v] = 1;\n                tree_cost += min_dist[v];\n                for(int i=0;i<sz;i++) if(!used[i]){\n                    long long d = distV[S[v]][S[i]];\n                    if(d < min_dist[i]) min_dist[i] = d;\n                }\n            }\n        }\n        return {tree_cost + fac_cost, true};\n    };\n    \n    // Greedy initialization with different strategies\n    auto greedy_init = [&](int variant)->vector<int>{\n        vector<int> S;\n        vector<char> inS(N,0);\n        S.push_back(0);\n        inS[0] = 1;\n        vector<char> covered(K,0);\n        \n        while(true){\n            bool all = true;\n            for(int i=0;i<K;i++) if(!covered[i]){all=false; break;}\n            if(all) break;\n            \n            vector<pair<double,int>> candidates;\n            \n            for(int v=0; v<N; v++) if(!inS[v]){\n                int newly = 0, max_need = 0;\n                for(int r: coverList[v]) if(!covered[r]){\n                    newly++;\n                    max_need = max(max_need, needP[r][v]);\n                }\n                if(newly==0) continue;\n                long long conn = INF;\n                for(int u: S) conn = min(conn, distV[u][v]);\n                long long total_cost = conn + 1LL*max_need*max_need;\n                \n                double score;\n                if(variant == 0) score = (double)newly / sqrt((double)total_cost);\n                else if(variant == 1) score = - (double)total_cost / newly;\n                else score = (double)newly * 1000000.0 / (double)total_cost + (rng()%100);\n                \n                candidates.push_back({score, v});\n            }\n            \n            if(candidates.empty()) break;\n            if(variant == 2) {\n                sort(candidates.rbegin(), candidates.rend());\n                int topk = min(3, (int)candidates.size());\n                int pick = uniform_int_distribution<int>(0, topk-1)(rng);\n                int bestv = candidates[pick].second;\n                inS[bestv] = 1;\n                S.push_back(bestv);\n                for(int r: coverList[bestv]) covered[r] = 1;\n            } else {\n                int bestv = max_element(candidates.begin(), candidates.end())->second;\n                inS[bestv] = 1;\n                S.push_back(bestv);\n                for(int r: coverList[bestv]) covered[r] = 1;\n            }\n        }\n        return S;\n    };\n    \n    // SA with reheating\n    auto simulated_annealing = [&](vector<int> S, int iter_limit, int num_reheats)->vector<int>{\n        vector<char> inS(N, 0);\n        for(int v: S) inS[v] = 1;\n        \n        auto [best_cost, ok] = evaluate(S);\n        if(!ok) return S;\n        vector<int> bestS = S;\n        long long cur_cost = best_cost;\n        \n        double initial_T = (double)cur_cost * 0.3;\n        double T = initial_T;\n        const double T_min = 0.1;\n        const double alpha = 0.9985;\n        \n        int no_improve = 0;\n        \n        for(int iter=0; iter<iter_limit; iter++){\n            if(no_improve > iter_limit / (num_reheats + 1)) {\n                T = initial_T * 0.5;\n                no_improve = 0;\n            }\n            \n            vector<int> newS;\n            bool valid = false;\n            int op = rng() % 3;\n            \n            if(op == 0 && (int)S.size() < N){\n                int v = uniform_int_distribution<int>(0, N-1)(rng);\n                if(!inS[v]){\n                    newS = S;\n                    newS.push_back(v);\n                    valid = true;\n                }\n            } else if(op == 1 && (int)S.size() > 1){\n                int idx = uniform_int_distribution<int>(1, (int)S.size()-1)(rng);\n                newS = S;\n                newS.erase(newS.begin() + idx);\n                valid = true;\n            } else if((int)S.size() > 1 && (int)S.size() < N){\n                int idx = uniform_int_distribution<int>(1, (int)S.size()-1)(rng);\n                int v_new;\n                do{ v_new = uniform_int_distribution<int>(0, N-1)(rng); } while(inS[v_new] || v_new==0);\n                newS = S;\n                newS.erase(newS.begin() + idx);\n                newS.push_back(v_new);\n                valid = true;\n            }\n            \n            if(!valid) continue;\n            \n            auto [new_cost, feasible] = evaluate(newS);\n            if(!feasible) continue;\n            \n            long long delta = new_cost - cur_cost;\n            bool accept = delta < 0;\n            if(!accept && T > 0.01){\n                accept = exp(-(double)delta / T) > uniform_real_distribution<double>(0,1)(rng);\n            }\n            \n            if(accept){\n                fill(inS.begin(), inS.end(), 0);\n                for(int v: newS) inS[v] = 1;\n                S = newS;\n                cur_cost = new_cost;\n                if(cur_cost < best_cost){\n                    best_cost = cur_cost;\n                    bestS = S;\n                    no_improve = 0;\n                } else {\n                    no_improve++;\n                }\n            } else {\n                no_improve++;\n            }\n            T = max(T_min, T * alpha);\n        }\n        return bestS;\n    };\n    \n    // Local search with add-remove-swap\n    auto local_search = [&](vector<int> S)->vector<int>{\n        auto [cost, _] = evaluate(S);\n        long long best_cost = cost;\n        vector<int> bestS = S;\n        bool improved = true;\n        int rounds = 0;\n        \n        while(improved && rounds < 250){\n            improved = false;\n            rounds++;\n            vector<char> inS(N, 0);\n            for(int v: S) inS[v] = 1;\n            \n            // Remove\n            for(size_t i=1;i<S.size() && !improved;i++){\n                vector<int> testS = S;\n                testS.erase(testS.begin()+i);\n                auto [c, ok] = evaluate(testS);\n                if(ok && c < best_cost){\n                    best_cost = c; bestS = testS; improved = true; S = testS; break;\n                }\n            }\n            if(improved) continue;\n            \n            // Add (sometimes adding then removing different vertex helps)\n            if((int)S.size() < N){\n                vector<int> outside;\n                for(int v=0;v<N;v++) if(!inS[v]) outside.push_back(v);\n                shuffle(outside.begin(), outside.end(), rng);\n                for(int v: outside){\n                    if(improved) break;\n                    vector<int> testS = S;\n                    testS.push_back(v);\n                    auto [c, ok] = evaluate(testS);\n                    if(ok && c < best_cost){\n                        best_cost = c; bestS = testS; improved = true; S = testS; break;\n                    }\n                }\n            }\n            if(improved) continue;\n            \n            // Swap\n            vector<int> outside;\n            for(int v=0;v<N;v++) if(!inS[v]) outside.push_back(v);\n            shuffle(outside.begin(), outside.end(), rng);\n            \n            for(size_t i=1;i<S.size() && !improved;i++){\n                for(int trial=0; trial<25 && trial<(int)outside.size(); trial++){\n                    int v_in = outside[trial];\n                    vector<int> testS = S;\n                    testS.erase(testS.begin()+i);\n                    testS.push_back(v_in);\n                    auto [c, ok] = evaluate(testS);\n                    if(ok && c < best_cost){\n                        best_cost = c; bestS = testS; improved = true; S = testS; break;\n                    }\n                }\n            }\n        }\n        return bestS;\n    };\n    \n    // Multiple restarts with more iterations\n    vector<int> best_solution;\n    long long global_best = INF;\n    \n    for(int attempt=0; attempt<3; attempt++){\n        vector<int> S = greedy_init(attempt % 3);\n        S = simulated_annealing(S, 10000, 3);\n        S = local_search(S);\n        \n        auto [c, _] = evaluate(S);\n        if(c < global_best){\n            global_best = c;\n            best_solution = S;\n        }\n    }\n    \n    // Extra refinement on best solution\n    vector<int> S = best_solution;\n    S = simulated_annealing(S, 5000, 2);\n    S = local_search(S);\n    \n    // Build output\n    int sz = (int)S.size();\n    vector<int> P(N, 0);\n    vector<char> inS(N, 0);\n    for(int v: S) inS[v] = 1;\n    \n    for(int r=0;r<K;r++){\n        for(int v: sortedVertices[r]){\n            if(inS[v]){\n                P[v] = max(P[v], needP[r][v]);\n                break;\n            }\n        }\n    }\n    \n    vector<int> B(M, 0);\n    if(sz > 1){\n        vector<long long> min_edge(sz, INF);\n        vector<char> used(sz, 0);\n        vector<int> parent_idx(sz, -1);\n        min_edge[0] = 0;\n        \n        for(int iter=0; iter<sz; iter++){\n            int v = -1;\n            for(int i=0;i<sz;i++) if(!used[i] && (v==-1 || min_edge[i]<min_edge[v])) v=i;\n            used[v] = 1;\n            for(int i=0;i<sz;i++) if(!used[i]){\n                long long d = distV[S[v]][S[i]];\n                if(d < min_edge[i]){\n                    min_edge[i] = d;\n                    parent_idx[i] = v;\n                }\n            }\n        }\n        \n        vector<char> edge_active(M, 0);\n        for(int i=1;i<sz;i++){\n            int u = S[parent_idx[i]];\n            int v = S[i];\n            int cur = v;\n            while(cur != u){\n                int e = parent_edge[u][cur];\n                if(e==-1) break;\n                edge_active[e] = 1;\n                int pu = edges[e].u == cur ? edges[e].v : edges[e].u;\n                cur = pu;\n            }\n        }\n        \n        vector<pair<int,int>> active_edges;\n        for(int i=0;i<M;i++) if(edge_active[i]) active_edges.push_back({edges[i].w, i});\n        sort(active_edges.begin(), active_edges.end());\n        \n        DSU dsu(N);\n        for(auto& [w, e]: active_edges){\n            int u=edges[e].u, v=edges[e].v;\n            if(dsu.find(u)!=dsu.find(v)){\n                dsu.unite(u,v);\n                B[e]=1;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int i=0;i<M;i++){\n        if(i) cout << ' ';\n        cout << B[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\n// Hungarian algorithm for minimization, n workers, m jobs (n <= m)\n// Returns pair(min_cost, assignment) where assignment[i] = job assigned to worker i\npair<int, vector<int>> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i = 1; i <= n; ++i) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= m; ++j) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j = 0; j <= m; ++j) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        \n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> assignment(n);\n    for (int j = 1; j <= m; ++j) {\n        if (p[j] != 0) {\n            assignment[p[j]-1] = j-1;\n        }\n    }\n    return {-v[0], assignment};\n}\n\nint calc_dist(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    return max({abs(dx), abs(dy), abs(dx - dy)});\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    const int BALLS = N * (N + 1) / 2;\n    \n    vector<vector<int>> init_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> init_pos(BALLS);\n    \n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v; \n            cin >> v;\n            init_grid[x][y] = v;\n            init_pos[v] = {x, y};\n        }\n    }\n    \n    // Determine optimal target assignment using Hungarian per row\n    vector<vector<int>> target_grid(N, vector<int>(N, -1));\n    vector<pair<int,int>> target_pos(BALLS); // where each value should go\n    \n    for (int x = 0; x < N; ++x) {\n        int m = x + 1;\n        int start = x * (x + 1) / 2;\n        \n        // Cost matrix: cost[i][j] = distance from initial pos of value (start+i) to cell (x,j)\n        vector<vector<int>> cost(m, vector<int>(m));\n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            auto [vx, vy] = init_pos[v];\n            for (int j = 0; j < m; ++j) {\n                cost[i][j] = calc_dist(vx, vy, x, j);\n            }\n        }\n        \n        auto [min_cost, assignment] = hungarian(cost);\n        // assignment[i] = column j where value (start+i) should go\n        \n        for (int i = 0; i < m; ++i) {\n            int v = start + i;\n            int y = assignment[i];\n            target_grid[x][y] = v;\n            target_pos[v] = {x, y};\n        }\n    }\n    \n    // Routing phase: bottom-up greedy swapping\n    vector<vector<int>> cur_grid = init_grid;\n    vector<pair<int,int>> cur_pos = init_pos;\n    vector<array<int,4>> ops;\n    \n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = x; y >= 0; --y) {\n            int target_val = target_grid[x][y];\n            auto [cx, cy] = cur_pos[target_val];\n            \n            while (cx != x || cy != y) {\n                int nx, ny;\n                if (cx < x) {\n                    if (cy > y) {\n                        nx = cx; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx + 1; ny = cy + 1;\n                    } else {\n                        nx = cx + 1; ny = cy;\n                    }\n                } else if (cx > x) {\n                    if (cy > y) {\n                        nx = cx - 1; ny = cy - 1;\n                    } else if (cy < y) {\n                        nx = cx - 1; ny = cy;\n                    } else {\n                        nx = cx - 1; ny = cy;\n                    }\n                } else {\n                    if (cy < y) {\n                        nx = cx; ny = cy + 1;\n                    } else {\n                        nx = cx; ny = cy - 1;\n                    }\n                }\n                \n                int v1 = cur_grid[cx][cy];\n                int v2 = cur_grid[nx][ny];\n                \n                swap(cur_grid[cx][cy], cur_grid[nx][ny]);\n                cur_pos[v1] = {nx, ny};\n                cur_pos[v2] = {cx, cy};\n                ops.push_back({cx, cy, nx, ny});\n                \n                cx = nx; cy = ny;\n            }\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto &op : ops) {\n        cout << op[0] << ' ' << op[1] << ' ' << op[2] << ' ' << op[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    \n    const int si = 0, sj = (D - 1) / 2;\n    const int M = D * D - 1 - N;\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    // BFS to compute distances from entrance (for heuristic)\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (dist[ni][nj] != -1) continue;\n            dist[ni][nj] = dist[i][j] + 1;\n            q.push({ni, nj});\n        }\n    }\n    \n    // Collect valid cells and sort by distance descending\n    // (far cells first, close cells last)\n    vector<pair<int, int>> cells;\n    cells.reserve(M);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == si && j == sj) continue;\n            if (obstacle[i][j]) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](const auto &a, const auto &b) {\n        return dist[a.first][a.second] > dist[b.first][b.second];\n    });\n    \n    // Map from cell to its index in sorted order\n    map<pair<int, int>, int> cell_to_idx;\n    for (int i = 0; i < cells.size(); i++) {\n        cell_to_idx[cells[i]] = i;\n    }\n    \n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    vector<vector<int>> value_at(D, vector<int>(D, -1));\n    \n    // Helper: check if removing cell (ri, rj) keeps all empty cells connected to entrance\n    auto is_safe = [&](int ri, int rj) -> bool {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        vis[si][sj] = true;\n        qq.push({si, sj});\n        int reachable_count = 1;\n        \n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (ni == ri && nj == rj) continue; // Pretend this cell is blocked\n                if (vis[ni][nj]) continue;\n                vis[ni][nj] = true;\n                reachable_count++;\n                qq.push({ni, nj});\n            }\n        }\n        \n        // Count total empty cells (excluding the one we're testing)\n        int total_empty = 1; // entrance\n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == si && j == sj) continue;\n                if (obstacle[i][j]) continue;\n                if (occupied[i][j]) continue;\n                if (i == ri && j == rj) continue;\n                total_empty++;\n            }\n        }\n        \n        return reachable_count == total_empty;\n    };\n    \n    // Placement phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        \n        // Target: small t should be near entrance (end of cells list)\n        // Large t should be far from entrance (beginning of cells list)\n        int target_idx = M - 1 - t;\n        \n        // Compute current reachable cells\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> qq;\n        reachable[si][sj] = true;\n        qq.push({si, sj});\n        while (!qq.empty()) {\n            auto [i, j] = qq.front(); qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                if (obstacle[ni][nj]) continue;\n                if (occupied[ni][nj]) continue;\n                if (reachable[ni][nj]) continue;\n                reachable[ni][nj] = true;\n                qq.push({ni, nj});\n            }\n        }\n        \n        pair<int, int> chosen = {-1, -1};\n        int best_diff = M + 1;\n        \n        // Find safe reachable cell closest to target position\n        for (int idx = 0; idx < M; idx++) {\n            auto [i, j] = cells[idx];\n            if (occupied[i][j]) continue;\n            if (!reachable[i][j]) continue;\n            \n            // Check safety: removing this cell should not disconnect the graph\n            if (!is_safe(i, j)) continue;\n            \n            int diff = abs(idx - target_idx);\n            if (diff < best_diff) {\n                best_diff = diff;\n                chosen = {i, j};\n            }\n        }\n        \n        // If no safe cell found, try without safety check (should not happen with valid input)\n        if (chosen.first == -1) {\n            for (int idx = 0; idx < M; idx++) {\n                auto [i, j] = cells[idx];\n                if (occupied[i][j]) continue;\n                if (!reachable[i][j]) continue;\n                int diff = abs(idx - target_idx);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    chosen = {i, j};\n                }\n            }\n        }\n        \n        // Last resort: any reachable cell\n        if (chosen.first == -1) {\n            for (auto [i, j] : cells) {\n                if (!occupied[i][j] && reachable[i][j]) {\n                    chosen = {i, j};\n                    break;\n                }\n            }\n        }\n        \n        occupied[chosen.first][chosen.second] = true;\n        value_at[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << \"\\n\";\n        cout.flush();\n    }\n    \n    // Retrieval phase: always take smallest available value\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[si][sj] = true;\n    \n    using P = pair<int, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    \n    // Helper to add neighbors of (i,j) to PQ\n    auto add_neighbors = [&](int i, int j) {\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n            if (obstacle[ni][nj]) continue;\n            if (is_empty[ni][nj]) continue;\n            if (value_at[ni][nj] == -1) continue; // No container\n            pq.push({value_at[ni][nj], {ni, nj}});\n        }\n    };\n    \n    // Initialize with cells adjacent to entrance\n    add_neighbors(si, sj);\n    \n    vector<pair<int, int>> retrieval;\n    retrieval.reserve(M);\n    \n    while ((int)retrieval.size() < M) {\n        if (pq.empty()) {\n            // This should not happen if placement was correct\n            break;\n        }\n        auto [val, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (is_empty[i][j]) continue; // Already retrieved\n        \n        is_empty[i][j] = true;\n        retrieval.push_back(pos);\n        add_neighbors(i, j);\n    }\n    \n    for (auto [i, j] : retrieval) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> inp(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> inp[i][j];\n\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    auto inside = [&](int i, int j) {\n        return 0 <= i && i < n && 0 <= j && j < n;\n    };\n\n    // Build adjacency graph from original map\n    vector<set<int>> orig_adj(m + 1);\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = inp[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                int c2 = (inside(ni, nj)) ? inp[ni][nj] : 0;\n                if (c1 != c2) {\n                    orig_adj[c1].insert(c2);\n                    orig_adj[c2].insert(c1);\n                }\n            }\n        }\n    }\n\n    // Working grid\n    vector<vector<int>> grid(n, vector<int>(n, -1));\n    vector<vector<pair<int,int>>> cells(m + 1);\n    \n    auto is_boundary = [&](int i, int j) {\n        return i == 0 || i == n-1 || j == 0 || j == n-1;\n    };\n\n    // Strict validation: can we place color c at (i,j)?\n    auto valid_placement = [&](int c, int i, int j, int target = -1) -> bool {\n        if (!inside(i, j) || grid[i][j] != -1) return false;\n        \n        // Non-0-adjacent colors: strictly no boundary\n        if (!orig_adj[c].count(0) && is_boundary(i, j)) return false;\n        \n        for (int d = 0; d < 4; ++d) {\n            int ni = i + di[d], nj = j + dj[d];\n            int w = inside(ni, nj) ? grid[ni][nj] : 0;\n            if (w == -1 || w == c) continue;\n            if (w == target) continue;\n            if (!orig_adj[c].count(w)) return false;\n        }\n        return true;\n    };\n\n    // Separate colors\n    vector<int> boundary_colors, interior_colors;\n    for (int c = 1; c <= m; ++c) {\n        if (orig_adj[c].count(0)) boundary_colors.push_back(c);\n        else interior_colors.push_back(c);\n    }\n\n    // Place interior colors (strictly interior)\n    for (int col : interior_colors) {\n        bool placed = false;\n        for (int i = 1; i < n-1 && !placed; ++i) {\n            for (int j = 1; j < n-1 && !placed; ++j) {\n                if (valid_placement(col, i, j)) {\n                    grid[i][j] = col;\n                    cells[col].push_back({i, j});\n                    placed = true;\n                }\n            }\n        }\n        // Emergency: any interior cell\n        if (!placed) {\n            for (int i = 1; i < n-1 && !placed; ++i) {\n                for (int j = 1; j < n-1 && !placed; ++j) {\n                    if (grid[i][j] == -1) {\n                        grid[i][j] = col;\n                        cells[col].push_back({i, j});\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Place boundary colors\n    vector<pair<int,int>> bnd;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            if (is_boundary(i, j)) bnd.push_back({i, j});\n    \n    size_t idx = 0;\n    for (int col : boundary_colors) {\n        while (idx < bnd.size()) {\n            auto [i, j] = bnd[idx++];\n            if (grid[i][j] == -1 && valid_placement(col, i, j)) {\n                grid[i][j] = col;\n                cells[col].push_back({i, j});\n                break;\n            }\n        }\n    }\n\n    // Emergency placement for any remaining\n    for (int c = 1; c <= m; ++c) {\n        if (cells[c].empty()) {\n            bool on_bnd = orig_adj[c].count(0);\n            for (int i = 0; i < n; ++i) {\n                for (int j = 0; j < n; ++j) {\n                    if (grid[i][j] != -1) continue;\n                    if (!on_bnd && is_boundary(i, j)) continue;\n                    // Check placement validity\n                    bool ok = true;\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + di[d], nj = j + dj[d];\n                        int w = inside(ni, nj) ? grid[ni][nj] : 0;\n                        if (w != -1 && w != c && !orig_adj[c].count(w)) {\n                            ok = false; break;\n                        }\n                    }\n                    if (!ok) continue;\n                    grid[i][j] = c;\n                    cells[c].push_back({i, j});\n                    i = n; j = n;\n                }\n            }\n        }\n    }\n\n    // Check adjacency\n    auto check_adj = [&](int c1, int c2) {\n        for (auto& [x, y] : cells[c1]) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + di[d], ny = y + dj[d];\n                int w = inside(nx, ny) ? grid[nx][ny] : 0;\n                if (w == c2) return true;\n            }\n        }\n        return false;\n    };\n\n    // Satisfy required adjacencies with strict validation\n    for (int u = 1; u <= m; ++u) {\n        for (int v : orig_adj[u]) {\n            if (v < u) continue;\n            \n            for (int attempt = 0; attempt < 1000 && !check_adj(u, v); ++attempt) {\n                // Find best expansion cell\n                int best = 1e9;\n                pair<int,int> best_cell = {-1,-1};\n                \n                for (auto& [x,y] : cells[u]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int nx = x+di[d], ny = y+dj[d];\n                        if (!valid_placement(u, nx, ny, v)) continue;\n                        \n                        int dist = 0;\n                        for (auto& [vx,vy] : cells[v])\n                            dist = max(dist, abs(nx-vx) + abs(ny-vy));\n                        if (dist < best) {\n                            best = dist;\n                            best_cell = {nx, ny};\n                        }\n                    }\n                }\n                \n                if (best_cell.first == -1) break;\n                \n                grid[best_cell.first][best_cell.second] = u;\n                cells[u].push_back(best_cell);\n            }\n        }\n    }\n\n    // Verify solution\n    bool valid = true;\n    // Check all colors are placed\n    for (int c = 1; c <= m; ++c) {\n        if (cells[c].empty()) valid = false;\n    }\n    // Check adjacencies match\n    for (int c1 = 0; c1 <= m && valid; ++c1) {\n        for (int c2 = c1+1; c2 <= m && valid; ++c2) {\n            bool should = orig_adj[c1].count(c2);\n            bool actual = check_adj(c1, c2);\n            if (should != actual) valid = false;\n        }\n    }\n    // Check connectivity\n    auto check_conn = [&](int c) {\n        if (cells[c].empty()) return false;\n        queue<pair<int,int>> q;\n        vector<vector<bool>> vis(n, vector<bool>(n));\n        for (auto& [x,y] : cells[c]) vis[x][y] = true;\n        q.push(cells[c][0]);\n        int cnt = 1;\n        while (!q.empty()) {\n            auto [x,y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx=x+di[d], ny=y+dj[d];\n                if (inside(nx,ny) && grid[nx][ny]==c && !vis[nx][ny]) {\n                    vis[nx][ny]=true; q.push({nx,ny}); cnt++;\n                }\n            }\n        }\n        return cnt == (int)cells[c].size();\n    };\n    for (int c = 0; c <= m && valid; ++c) {\n        if (!check_conn(c)) valid = false;\n    }\n\n    // Output\n    if (valid) {\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (j) cout << ' ';\n                cout << max(0, grid[i][j]);\n            }\n            cout << '\\n';\n        }\n    } else {\n        // Fallback: output original map (always valid, score 1)\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                if (j) cout << ' ';\n                cout << inp[i][j];\n            }\n            cout << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    vector<double> w(N, 0.0);\n    vector<int> cnt(N, 0);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Ensure minimum coverage: every item compared at least once\n    // Then fill remaining with random\n    \n    int q = 0;\n    \n    // First pass: compare each item with item 0 (except item 0 itself)\n    for (int i = 1; i < N && q < Q; i++) {\n        cout << \"1 1 \" << i << \" 0\" << endl;\n        char r;\n        cin >> r;\n        q++;\n        \n        cnt[i]++; cnt[0]++;\n        if (r == '>') {\n            w[i] += 2.0;\n            w[0] -= 1.0;\n        } else if (r == '<') {\n            w[i] -= 2.0;\n            w[0] += 1.0;\n        }\n    }\n    \n    // Remaining queries: random comparisons, weighted towards less-sampled items\n    while (q < Q) {\n        // Pick first item: prefer less-sampled items\n        vector<int> candidates;\n        int min_cnt = *min_element(cnt.begin(), cnt.end());\n        for (int i = 0; i < N; i++) {\n            if (cnt[i] <= min_cnt + 1) candidates.push_back(i);\n        }\n        \n        int a;\n        if (!candidates.empty()) {\n            a = candidates[rng() % candidates.size()];\n        } else {\n            a = rng() % N;\n        }\n        \n        int b = rng() % N;\n        while (a == b) b = rng() % N;\n        \n        cout << \"1 1 \" << a << \" \" << b << endl;\n        char r;\n        cin >> r;\n        q++;\n        \n        cnt[a]++; cnt[b]++;\n        if (r == '>') {\n            w[a] += 1.0;\n            w[b] -= 1.0;\n        } else if (r == '<') {\n            w[a] -= 1.0;\n            w[b] += 1.0;\n        }\n    }\n    \n    // Normalize to positive\n    double mn = w[0];\n    for (int i = 1; i < N; i++) mn = min(mn, w[i]);\n    for (int i = 0; i < N; i++) w[i] = w[i] - mn + 1.0;\n    \n    // LPT partition\n    vector<int> bel(N, 0);\n    vector<double> sm(D, 0.0);\n    \n    vector<pair<double, int>> v;\n    for (int i = 0; i < N; i++) v.push_back({w[i], i});\n    sort(v.rbegin(), v.rend());\n    \n    for (auto& p : v) {\n        int bi = 0;\n        for (int g = 1; g < D; g++) {\n            if (sm[g] < sm[bi]) bi = g;\n        }\n        bel[p.second] = bi;\n        sm[bi] += p.first;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << bel[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> st(m);\n    vector<int> pos(n + 1);\n    \n    for (int i = 0; i < m; ++i) {\n        int h = n / m;\n        for (int j = 0; j < h; ++j) {\n            int x; \n            cin >> x;\n            st[i].push_back(x);\n            pos[x] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    for (int target = 1; target <= n; ++target) {\n        int s = pos[target];\n        \n        int idx = -1;\n        for (int i = 0; i < (int)st[s].size(); ++i) {\n            if (st[s][i] == target) {\n                idx = i;\n                break;\n            }\n        }\n        \n        while (idx < (int)st[s].size() - 1) {\n            int w = st[s].back();\n            int k = st[s].size() - idx - 1; // number of boxes to move\n            \n            int best_d = -1;\n            double best_cost = 1e300;\n            \n            for (int d = 0; d < m; ++d) {\n                if (d == s) continue;\n                \n                double cost = k + 1; // Immediate cost\n                \n                if (st[d].empty()) {\n                    // No additional cost, very good\n                    cost -= 0.5; // Small bonus to prefer empty over valid\n                } else {\n                    int t = st[d].back();\n                    if (t < w) {\n                        // Invalid move: w blocks t, must move w again later\n                        // Estimate: w will be moved again when we need t\n                        // Count how many boxes in d are smaller than w\n                        int smaller = 0;\n                        for (int x : st[d]) {\n                            if (x < w) smaller++;\n                        }\n                        // Each such box will require moving w again\n                        cost += (k + 1) * smaller * 0.5;\n                    }\n                    // Valid move: no additional cost\n                }\n                \n                // Tie-break by top value (prefer larger top)\n                if (st[d].empty()) {\n                    // Empty is best\n                } else if (best_d == -1 || st[d].back() > st[best_d].back()) {\n                    cost -= 0.001 * st[d].back(); // Small tie-breaker\n                }\n                \n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_d = d;\n                }\n            }\n            \n            int u = st[s][idx + 1];\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            st[s].resize(idx + 1);\n            \n            for (int x : seg) pos[x] = best_d;\n            st[best_d].insert(st[best_d].end(), seg.begin(), seg.end());\n            \n            ops.emplace_back(u, best_d + 1);\n        }\n        \n        st[s].pop_back();\n        ops.emplace_back(target, 0);\n    }\n    \n    for (auto [v, i] : ops) {\n        cout << v << ' ' << i << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n    \n    auto id = [&](int i, int j){ return i*N + j; };\n    const int V = N*N;\n    const int root = 0;\n    \n    // Build adjacency list\n    vector<vector<pair<int,char>>> adj(V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir];\n                int nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                bool ok = false;\n                if (dir == 0) ok = h[ni][j] == '0';\n                else if (dir == 1) ok = h[i][j] == '0';\n                else if (dir == 2) ok = v[i][nj] == '0';\n                else ok = v[i][j] == '0';\n                if (ok) adj[id(i,j)].push_back({id(ni,nj), dc[dir]});\n            }\n        }\n    }\n    \n    // Build tree with priority queue (high d first) to keep high-d nodes shallow\n    vector<int> parent(V, -1);\n    vector<vector<int>> children(V);\n    {\n        priority_queue<pair<int,int>> pq;\n        pq.push({d[0][0], root});\n        parent[root] = -1;\n        while (!pq.empty()) {\n            auto [du, u] = pq.top(); pq.pop();\n            for (auto [w, _] : adj[u]) {\n                if (parent[w] == -1 && w != root) {\n                    parent[w] = u;\n                    children[u].push_back(w);\n                    int wi = w / N, wj = w % N;\n                    pq.push({d[wi][wj], w});\n                }\n            }\n        }\n    }\n    \n    // Bottom-up order\n    vector<int> order;\n    order.reserve(V);\n    {\n        queue<int> q;\n        q.push(root);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            order.push_back(u);\n            for (int w : children[u]) q.push(w);\n        }\n    }\n    reverse(order.begin(), order.end()); // leaves first\n    \n    vector<double> dval(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            dval[id(i,j)] = sqrt((double)d[i][j]);\n    \n    const long long LIM = 100000LL;\n    const int B = 3;\n    vector<long long> k(V, 1);\n    \n    // Binary search on multiplier c\n    double lo = 0, hi = 1e6;\n    for (int it = 0; it < 60; ++it) {\n        double mid = (lo + hi) * 0.5;\n        long long L = 0;\n        for (int u : order) {\n            if (u == root) continue;\n            long long sumc = 0;\n            for (int w : children[u]) sumc += k[w];\n            long long constraint = (sumc + B - 1) / B;\n            long long target = (long long)(mid * dval[u]);\n            if (target < 1) target = 1;\n            long long ku = max(constraint, target);\n            k[u] = ku;\n            L += 2 * ku;\n            if (L > LIM) break;\n        }\n        if (L <= LIM) lo = mid;\n        else hi = mid;\n    }\n    \n    // Final evaluation with lo\n    long long Ltot = 0;\n    for (int u : order) {\n        if (u == root) continue;\n        long long sumc = 0;\n        for (int w : children[u]) sumc += k[w];\n        long long constraint = (sumc + B - 1) / B;\n        long long target = (long long)(lo * dval[u]);\n        if (target < 1) target = 1;\n        long long ku = max(constraint, target);\n        k[u] = ku;\n        Ltot += 2 * ku;\n    }\n    \n    // Build schedule (top-down)\n    vector<vector<vector<int>>> sched(V);\n    vector<int> bfs = order;\n    reverse(bfs.begin(), bfs.end()); // root first\n    \n    for (int u : bfs) {\n        if (children[u].empty()) {\n            sched[u].assign((size_t)k[u], {});\n            continue;\n        }\n        vector<int> exc;\n        exc.reserve(10000);\n        for (int w : children[u]) {\n            for (long long i = 0; i < k[w]; ++i) exc.push_back(w);\n        }\n        sched[u].assign((size_t)k[u], {});\n        for (size_t i = 0; i < exc.size(); ++i) {\n            int slot = (int)(i % k[u]);\n            sched[u][slot].push_back(exc[i]);\n        }\n    }\n    \n    // Generate walk\n    string ans;\n    ans.reserve((size_t)LIM);\n    vector<size_t> cur(V, 0);\n    \n    auto getc = [&](int u, int v)->char {\n        for (auto [to, c] : adj[u]) if (to == v) return c;\n        return '?';\n    };\n    \n    function<void(int)> visit = [&](int u) {\n        size_t slot = cur[u]++;\n        for (int w : sched[u][slot]) {\n            ans.push_back(getc(u, w));\n            visit(w);\n            ans.push_back(getc(w, u));\n        }\n    };\n    \n    for (size_t slot = 0; slot < (size_t)k[root]; ++slot) {\n        for (int w : sched[root][slot]) {\n            ans.push_back(getc(root, w));\n            visit(w);\n            ans.push_back(getc(w, root));\n        }\n    }\n    \n    if ((long long)ans.size() > LIM) ans.resize((size_t)LIM);\n    cout << ans << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint calc_overlap(const string& a, const string& b) {\n    int max_k = min((int)a.length(), (int)b.length());\n    for (int k = max_k; k > 0; --k) {\n        if (a.compare(a.length() - k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nstring greedy_scs(vector<string>& strs, mt19937& rng) {\n    if (strs.empty()) return \"\";\n    if (strs.size() == 1) return strs[0];\n    \n    vector<string> pool = strs;\n    shuffle(pool.begin(), pool.end(), rng);\n    \n    while (pool.size() > 1) {\n        int m = pool.size();\n        int best_ov = -1, best_i = -1, best_j = -1;\n        \n        for (int i = 0; i < m; ++i) {\n            for (int j = i + 1; j < m; ++j) {\n                int ov1 = calc_overlap(pool[i], pool[j]);\n                int ov2 = calc_overlap(pool[j], pool[i]);\n                if (ov1 > best_ov) {\n                    best_ov = ov1; best_i = i; best_j = j;\n                }\n                if (ov2 > best_ov) {\n                    best_ov = ov2; best_i = j; best_j = i;\n                }\n            }\n        }\n        \n        string merged = pool[best_i] + pool[best_j].substr(best_ov);\n        if (best_i > best_j) swap(best_i, best_j);\n        pool.erase(pool.begin() + best_j);\n        pool.erase(pool.begin() + best_i);\n        pool.push_back(std::move(merged));\n    }\n    \n    return pool[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    int si, sj;\n    cin >> N >> M >> si >> sj;\n    \n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n    \n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) cin >> targets[i];\n    \n    // Remove substrings\n    vector<bool> removed(M, false);\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            if (i != j && !removed[j] && targets[j].find(targets[i]) != string::npos) {\n                removed[i] = true;\n                break;\n            }\n        }\n    }\n    \n    vector<string> filtered;\n    for (int i = 0; i < M; ++i) \n        if (!removed[i]) filtered.push_back(targets[i]);\n    \n    random_device rd;\n    mt19937 rng(rd());\n    \n    string best_U;\n    int best_len = INT_MAX;\n    \n    // Try 10 iterations for better superstring\n    for (int iter = 0; iter < 10; ++iter) {\n        string U = greedy_scs(filtered, rng);\n        if ((int)U.size() < best_len) {\n            best_len = U.size();\n            best_U = U;\n        }\n    }\n    \n    const string& U = best_U;\n    int L = U.size();\n    \n    // Positions for each character\n    vector<vector<int>> pos(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            pos[grid[i][j] - 'A'].push_back(i * N + j);\n    \n    const int V = N * N;\n    vector<vector<int>> dist(V, vector<int>(V));\n    for (int i = 0; i < V; ++i) {\n        int i1 = i / N, j1 = i % N;\n        for (int j = i; j < V; ++j) {\n            int i2 = j / N, j2 = j % N;\n            int d = abs(i1 - i2) + abs(j1 - j2);\n            dist[i][j] = dist[j][i] = d;\n        }\n    }\n    \n    const int INF = 1e9;\n    vector<int> dp_prev(V, INF), dp_curr(V, INF);\n    vector<vector<short>> parent(L, vector<short>(V, -1));\n    \n    int first_c = U[0] - 'A';\n    int start = si * N + sj;\n    for (int v : pos[first_c])\n        dp_curr[v] = dist[start][v] + 1;\n    \n    for (int step = 1; step < L; ++step) {\n        dp_prev.swap(dp_curr);\n        fill(dp_curr.begin(), dp_curr.end(), INF);\n        \n        int curr_c = U[step] - 'A';\n        int prev_c = U[step - 1] - 'A';\n        \n        for (int v : pos[curr_c]) {\n            int best = INF;\n            short best_u = -1;\n            for (int u : pos[prev_c]) {\n                int c = dp_prev[u] + dist[u][v] + 1;\n                if (c < best) {\n                    best = c;\n                    best_u = u;\n                }\n            }\n            dp_curr[v] = best;\n            parent[step][v] = best_u;\n        }\n    }\n    \n    int best_v = -1, best_cost = INF;\n    for (int v = 0; v < V; ++v) {\n        if (dp_curr[v] < best_cost) {\n            best_cost = dp_curr[v];\n            best_v = v;\n        }\n    }\n    \n    vector<pair<int, int>> path;\n    path.reserve(L);\n    int cur = best_v;\n    for (int step = L - 1; step >= 0; --step) {\n        path.push_back({cur / N, cur % N});\n        if (step > 0) cur = parent[step][cur];\n    }\n    reverse(path.begin(), path.end());\n    \n    for (auto [i, j] : path)\n        cout << i << \" \" << j << \"\\n\";\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    \n    // Read and ignore shapes (we'll just drill everything)\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int a, b; cin >> a >> b;\n        }\n    }\n    \n    vector<int> oil_cells;\n    \n    // Drill all cells\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << \"q 1 \" << i << \" \" << j << \"\\n\";\n            cout.flush();\n            int v; \n            if (!(cin >> v)) return 0;\n            if (v > 0) oil_cells.push_back(i * N + j);\n        }\n    }\n    \n    // Answer\n    cout << \"a \" << oil_cells.size();\n    for (int idx : oil_cells) {\n        cout << \" \" << idx / N << \" \" << idx % N;\n    }\n    cout << \"\\n\";\n    cout.flush();\n    \n    int resp; \n    cin >> resp;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nlong long solve_instance(int W, int D, int N, const vector<vector<int>>& a,\n                        mt19937& rng, double time_limit,\n                        vector<vector<int>>& out_h, vector<vector<int>>& out_y) {\n    uniform_int_distribution<int> day_dist(0, D-1);\n    uniform_int_distribution<int> strip_dist(0, N-1);\n    \n    // Greedy initialization\n    vector<vector<int>> h(D, vector<int>(N, 1));\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> needs;\n        for (int k = 0; k < N; k++) {\n            int need = (a[d][k] + W - 1) / W;\n            needs.push_back({need, k});\n        }\n        sort(needs.rbegin(), needs.rend());\n        int remaining = W - N;\n        for (auto &[need, k] : needs) {\n            int give = min(remaining, max(0, need - 1));\n            h[d][k] = 1 + give;\n            remaining -= give;\n        }\n        int idx = 0;\n        while (remaining > 0) {\n            h[d][idx % N]++;\n            remaining--;\n            idx++;\n        }\n    }\n    \n    // Build y\n    vector<vector<int>> y(D, vector<int>(N+1));\n    for (int d = 0; d < D; d++) {\n        y[d][0] = 0;\n        for (int k = 0; k < N; k++) y[d][k+1] = y[d][k] + h[d][k];\n    }\n    \n    auto strip_cost = [&](int d, int k, int height) -> long long {\n        long long area = 1LL * height * W;\n        if (area < a[d][k]) return 100LL * (a[d][k] - area);\n        return 0;\n    };\n    \n    auto compute_cost = [&]() -> long long {\n        long long cost = 0;\n        for (int d = 0; d < D; d++) {\n            for (int k = 0; k < N; k++) {\n                cost += strip_cost(d, k, h[d][k]);\n            }\n        }\n        for (int d = 1; d < D; d++) {\n            for (int k = 1; k < N; k++) {\n                if (y[d][k] != y[d-1][k]) cost += 2LL * W;\n            }\n        }\n        return cost;\n    };\n    \n    long long current_cost = compute_cost();\n    long long best_cost = current_cost;\n    auto best_h = h, best_y = y;\n    \n    clock_t start = clock();\n    int no_improve = 0;\n    \n    while (true) {\n        double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;\n        if (elapsed > time_limit) break;\n        \n        double progress = elapsed / time_limit;\n        // Even slower cooling for more exploration\n        double T = 500000.0 * pow(0.0001, progress) + 0.1;\n        \n        int d = day_dist(rng);\n        int i = strip_dist(rng);\n        int j = strip_dist(rng);\n        if (i == j) continue;\n        if (h[d][i] <= 1) continue;\n        \n        int l = min(i, j) + 1;\n        int r = max(i, j);\n        int delta = (i < j) ? -1 : +1;\n        \n        long long da = strip_cost(d, i, h[d][i]-1) - strip_cost(d, i, h[d][i])\n                     + strip_cost(d, j, h[d][j]+1) - strip_cost(d, j, h[d][j]);\n        \n        long long dp = 0;\n        for (int k = l; k <= r; k++) {\n            int old_y = y[d][k], new_y = old_y + delta;\n            if (d > 0) {\n                bool oeq = (old_y == y[d-1][k]), neq = (new_y == y[d-1][k]);\n                if (oeq && !neq) dp += 2*W;\n                else if (!oeq && neq) dp -= 2*W;\n            }\n            if (d < D-1) {\n                bool oeq = (old_y == y[d+1][k]), neq = (new_y == y[d+1][k]);\n                if (oeq && !neq) dp += 2*W;\n                else if (!oeq && neq) dp -= 2*W;\n            }\n        }\n        \n        long long dc = da + dp;\n        \n        bool accept = (dc < 0);\n        if (!accept && T > 0.01) {\n            accept = (uniform_real_distribution<double>(0,1)(rng) < exp(-(double)dc / T));\n        }\n        \n        if (accept) {\n            h[d][i]--;\n            h[d][j]++;\n            for (int k = l; k <= r; k++) y[d][k] += delta;\n            current_cost += dc;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_h = h;\n                best_y = y;\n                no_improve = 0;\n            }\n        }\n        \n        if (++no_improve >= 25000) {\n            h = best_h;\n            y = best_y;\n            current_cost = best_cost;\n            no_improve = 0;\n        }\n    }\n    \n    out_h = best_h;\n    out_y = best_y;\n    return best_cost;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    const double TIME_LIMIT = 2.95;\n    clock_t global_start = clock();\n    \n    vector<vector<int>> best_h, best_y;\n    long long best_cost = LLONG_MAX;\n    \n    // Multiple runs with different seeds\n    for (int run = 0; ; run++) {\n        double elapsed = (double)(clock() - global_start) / CLOCKS_PER_SEC;\n        double remaining = TIME_LIMIT - elapsed;\n        if (remaining < 0.5) break;\n        \n        // Allocate decreasing time for each run\n        double run_time = min(remaining / 1.5, 1.0);\n        \n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count() + run * 10007);\n        \n        vector<vector<int>> h, y;\n        long long cost = solve_instance(W, D, N, a, rng, run_time, h, y);\n        \n        if (cost < best_cost) {\n            best_cost = cost;\n            best_h = h;\n            best_y = y;\n        }\n    }\n    \n    // Output best\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << best_y[d][k] << \" 0 \" << best_y[d][k+1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m, p, q;\n    int pos[9];\n    int val[9];\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int tc = 0; tc < 150; ++tc) {\n        int n, m, k;\n        if (!(cin >> n >> m >> k)) return 0;\n        \n        vector<long long> grid(n * n);\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cin >> grid[i * n + j];\n            }\n        }\n        \n        int stamp_vals[20][3][3];\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                for (int l = 0; l < 3; ++l) {\n                    cin >> stamp_vals[i][j][l];\n                }\n            }\n        }\n        \n        // Precompute all 980 operations\n        vector<Op> ops;\n        ops.reserve(m * (n-2) * (n-2));\n        for (int mi = 0; mi < m; ++mi) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    Op op;\n                    op.m = mi; op.p = p; op.q = q;\n                    int cnt = 0;\n                    for (int i = 0; i < 3; ++i) {\n                        for (int j = 0; j < 3; ++j) {\n                            op.pos[cnt] = (p + i) * n + (q + j);\n                            op.val[cnt] = stamp_vals[mi][i][j];\n                            cnt++;\n                        }\n                    }\n                    ops.push_back(op);\n                }\n            }\n        }\n        \n        const int NUM_OPS = ops.size();\n        vector<int> sol;\n        sol.reserve(k);\n        \n        mt19937 rng(tc + 12345);\n        \n        auto calc_delta = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv + op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto calc_delta_remove = [&](const Op& op) -> long long {\n            long long d = 0;\n            for (int i = 0; i < 9; ++i) {\n                long long oldv = grid[op.pos[i]];\n                long long newv = oldv - op.val[i];\n                d += (newv % MOD) - (oldv % MOD);\n            }\n            return d;\n        };\n        \n        auto apply_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] += op.val[i];\n        };\n        \n        auto remove_op = [&](const Op& op) {\n            for (int i = 0; i < 9; ++i) grid[op.pos[i]] -= op.val[i];\n        };\n        \n        // Greedy construction\n        for (int iter = 0; iter < k; ++iter) {\n            long long best_d = 0;\n            int best_idx = -1;\n            \n            // Random shuffle to break ties and add diversity\n            vector<int> order(NUM_OPS);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            \n            for (int idx : order) {\n                long long d = calc_delta(ops[idx]);\n                if (d > best_d) {\n                    best_d = d;\n                    best_idx = idx;\n                }\n            }\n            \n            if (best_idx == -1) break;\n            apply_op(ops[best_idx]);\n            sol.push_back(best_idx);\n        }\n        \n        // Simulated Annealing\n        const int SA_ITER = 30000;\n        double temp = 1e9;\n        double alpha = pow(0.1 / temp, 1.0 / SA_ITER);\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < SA_ITER; ++iter) {\n            if (sol.empty()) {\n                int idx = rng() % NUM_OPS;\n                long long d = calc_delta(ops[idx]);\n                apply_op(ops[idx]);\n                sol.push_back(idx);\n            } else if ((int)sol.size() >= k) {\n                int sidx = rng() % sol.size();\n                const Op& op = ops[sol[sidx]];\n                long long d = calc_delta_remove(op);\n                if (d > 0 || exp(d / temp) > dist(rng)) {\n                    remove_op(op);\n                    sol[sidx] = sol.back();\n                    sol.pop_back();\n                }\n            } else {\n                int type = rng() % 3;\n                if (type == 0) {\n                    int idx = rng() % NUM_OPS;\n                    long long d = calc_delta(ops[idx]);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        apply_op(ops[idx]);\n                        sol.push_back(idx);\n                    }\n                } else if (type == 1) {\n                    int sidx = rng() % sol.size();\n                    const Op& op = ops[sol[sidx]];\n                    long long d = calc_delta_remove(op);\n                    if (d > 0 || exp(d / temp) > dist(rng)) {\n                        remove_op(op);\n                        sol[sidx] = sol.back();\n                        sol.pop_back();\n                    }\n                } else {\n                    // Replace\n                    int sidx = rng() % sol.size();\n                    int new_idx = rng() % NUM_OPS;\n                    const Op& old_op = ops[sol[sidx]];\n                    \n                    long long d_rem = calc_delta_remove(old_op);\n                    remove_op(old_op);\n                    \n                    const Op& new_op = ops[new_idx];\n                    long long d_add = calc_delta(new_op);\n                    \n                    long long total = d_rem + d_add;\n                    if (total > 0 || exp(total / temp) > dist(rng)) {\n                        apply_op(new_op);\n                        sol[sidx] = new_idx;\n                    } else {\n                        apply_op(old_op);\n                    }\n                }\n            }\n            temp *= alpha;\n        }\n        \n        cout << sol.size() << '\\n';\n        for (int idx : sol) {\n            cout << ops[idx].m << ' ' << ops[idx].p << ' ' << ops[idx].q << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) \n        for (int j = 0; j < N; j++) \n            cin >> A[i][j];\n    \n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<int> recv_ptr(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        grid[i][0] = A[i][0];\n        recv_ptr[i] = 1;\n    }\n    \n    int cr = 0, cc = 0;\n    bool holding = false;\n    int held_id = -1;\n    \n    vector<string> ops(N);\n    int turn = 0;\n    \n    auto add_op = [&](int crane, char c) {\n        if ((int)ops[crane].size() <= turn) \n            ops[crane].push_back(c);\n        else \n            ops[crane][turn] = c;\n    };\n    \n    auto do_receiving = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][0] == -1 && recv_ptr[i] < N) {\n                grid[i][0] = A[i][recv_ptr[i]];\n                recv_ptr[i]++;\n            }\n        }\n    };\n    \n    auto do_dispatch = [&]() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    };\n    \n    auto end_turn = [&]() {\n        do_dispatch();\n        do_receiving();\n        turn++;\n    };\n    \n    add_op(0, '.');\n    for (int i = 1; i < N; i++) add_op(i, 'B');\n    end_turn();\n    \n    vector<int> dispatched(N, 0);\n    vector<int> taken_from_gate(N, 0);\n    \n    auto move_to = [&](int tr, int tc) {\n        while (cr != tr) {\n            add_op(0, cr < tr ? 'D' : 'U');\n            cr += (cr < tr) ? 1 : -1;\n            end_turn();\n        }\n        while (cc != tc) {\n            add_op(0, cc < tc ? 'R' : 'L');\n            cc += (cc < tc) ? 1 : -1;\n            end_turn();\n        }\n    };\n    \n    auto pickup = [&]() {\n        add_op(0, 'P');\n        held_id = grid[cr][cc];\n        grid[cr][cc] = -1;\n        holding = true;\n        end_turn();\n    };\n    \n    auto drop = [&]() {\n        add_op(0, 'Q');\n        grid[cr][cc] = held_id;\n        holding = false;\n        held_id = -1;\n        end_turn();\n    };\n    \n    auto find_any_parking = [&]() -> pair<int, int> {\n        // Prefer target row, then any row, cols 2,3,1 first, then 0\n        for (int r = 0; r < N; r++) {\n            for (int c : {2, 3, 1}) {\n                if (grid[r][c] == -1) return {r, c};\n            }\n        }\n        for (int r = 0; r < N; r++) {\n            if (grid[r][0] == -1) return {r, 0};\n        }\n        return {-1, -1};\n    };\n    \n    auto park_container = [&](int container_id, int current_row) {\n        int target_row = container_id / N;\n        \n        // Try target row first\n        for (int c : {2, 3, 1, 0}) {\n            if (grid[target_row][c] == -1) {\n                move_to(target_row, c);\n                drop();\n                return;\n            }\n        }\n        \n        // Try alternative row\n        for (int c : {2, 3, 1, 0}) {\n            if (grid[current_row][c] == -1) {\n                move_to(current_row, c);\n                drop();\n                return;\n            }\n        }\n        \n        // Emergency: any row\n        auto [pr, pc] = find_any_parking();\n        if (pc != -1) {\n            move_to(pr, pc);\n            drop();\n        } else {\n            // Should never happen, but dispatch at target row gate to avoid crash\n            // This is wrong but prevents crash\n            move_to(target_row, N-1);\n            drop();\n        }\n    };\n    \n    for (int target = 0; target < N; target++) {\n        auto try_dispatch = [&]() -> bool {\n            if (!holding) return false;\n            int need = target * N + dispatched[target];\n            if (held_id == need) {\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n                return true;\n            }\n            return false;\n        };\n        \n        while (taken_from_gate[target] < N) {\n            int cid = A[target][taken_from_gate[target]];\n            move_to(target, 0);\n            pickup();\n            taken_from_gate[target]++;\n            \n            if (!try_dispatch()) {\n                park_container(cid, target);\n            }\n        }\n        \n        for (int g = 0; g < N; g++) {\n            if (g == target) continue;\n            \n            while (taken_from_gate[g] < N) {\n                int cid = A[g][taken_from_gate[g]];\n                if (cid / N != target) break;\n                \n                while (taken_from_gate[g] < N && A[g][taken_from_gate[g]] != cid) {\n                    int blk = A[g][taken_from_gate[g]];\n                    move_to(g, 0);\n                    pickup();\n                    taken_from_gate[g]++;\n                    park_container(blk, target);\n                }\n                \n                move_to(g, 0);\n                pickup();\n                taken_from_gate[g]++;\n                \n                if (!try_dispatch()) {\n                    park_container(cid, target);\n                }\n            }\n        }\n        \n        while (dispatched[target] < N) {\n            int need = target * N + dispatched[target];\n            int fc = -1;\n            for (int c = 0; c < N-1; c++) {\n                if (grid[target][c] == need) {\n                    fc = c;\n                    break;\n                }\n            }\n            if (fc != -1) {\n                move_to(target, fc);\n                pickup();\n                move_to(target, N-1);\n                drop();\n                dispatched[target]++;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    size_t max_len = 0;\n    for (auto &s : ops) max_len = max(max_len, s.size());\n    for (auto &s : ops) {\n        while (s.size() < max_len) s.push_back('.');\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int r = 0, c = 0;\n    long long load = 0;\n    \n    auto dist = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n    \n    auto step_toward = [&](int tr, int tc) {\n        const int dr[] = {-1, 1, 0, 0};\n        const int dc[] = {0, 0, -1, 1};\n        const char* name = \"UDLR\";\n        \n        int best_score = -1e9;\n        int best_dir = -1;\n        \n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            \n            int score = 0;\n            int progress = dist(r, c, tr, tc) - dist(nr, nc, tr, tc);\n            score += progress * 1000;\n            \n            if (load == 0 && h[nr][nc] > 0) {\n                score += h[nr][nc] * 10;\n            } else if (load > 0 && h[nr][nc] < 0) {\n                int can_take = min((long long)(-h[nr][nc]), load);\n                score += can_take * 10;\n                if (can_take == load) score += 500;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = k;\n            }\n        }\n        \n        if (best_dir == -1) return false;\n        \n        r += dr[best_dir];\n        c += dc[best_dir];\n        ops.emplace_back(string(1, name[best_dir]));\n        \n        if (load == 0 && h[r][c] > 0) {\n            ops.emplace_back(\"+\" + to_string(h[r][c]));\n            load += h[r][c];\n            h[r][c] = 0;\n        } else if (load > 0 && h[r][c] < 0) {\n            int amt = (int)min(load, (long long)(-h[r][c]));\n            if (amt > 0) {\n                ops.emplace_back(\"-\" + to_string(amt));\n                load -= amt;\n                h[r][c] += amt;\n            }\n        }\n        \n        return true;\n    };\n    \n    auto move_to = [&](int tr, int tc) {\n        while (r != tr || c != tc) {\n            if (!step_toward(tr, tc)) break;\n        }\n    };\n    \n    while (true) {\n        bool any_pos = false, any_neg = false;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (h[i][j] > 0) any_pos = true;\n                if (h[i][j] < 0) any_neg = true;\n            }\n        }\n        if (!any_pos && !any_neg) break;\n        \n        if (load == 0) {\n            if (!any_pos) break;\n            \n            // BFS for sink distances\n            vector<vector<int>> sink_dist(N, vector<int>(N, 1e9));\n            queue<pair<int,int>> q;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] < 0) {\n                        sink_dist[i][j] = 0;\n                        q.push({i, j});\n                    }\n                }\n            }\n            const int d4r[] = {-1,1,0,0}, d4c[] = {0,0,-1,1};\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + d4r[k], nc = cc + d4c[k];\n                    if (nr>=0 && nr<N && nc>=0 && nc<N && sink_dist[nr][nc]==1e9) {\n                        sink_dist[nr][nc] = sink_dist[cr][cc] + 1;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n            \n            long long best_cost = (1LL<<60);\n            pair<int,int> target = {-1,-1};\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] > 0) {\n                        int d_empty = dist(r,c,i,j);\n                        int d_sink = sink_dist[i][j];\n                        if (d_sink == 1e9) d_sink = 0;\n                        long long cost = 100LL*d_empty + (100LL+h[i][j])*d_sink;\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            target = {i,j};\n                        }\n                    }\n                }\n            }\n            \n            move_to(target.first, target.second);\n            if (h[r][c] > 0) {\n                ops.emplace_back(\"+\" + to_string(h[r][c]));\n                load += h[r][c];\n                h[r][c] = 0;\n            }\n        } else {\n            if (!any_neg) break;\n            \n            // Nearest sink, with tie-breaker for larger capacity\n            int best_dist = 1e9;\n            int best_capacity = -1;\n            pair<int,int> target = {-1,-1};\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] < 0) {\n                        int d = dist(r,c,i,j);\n                        int cap = min((long long)(-h[i][j]), load);\n                        if (d < best_dist || (d == best_dist && cap > best_capacity)) {\n                            best_dist = d;\n                            best_capacity = cap;\n                            target = {i,j};\n                        }\n                    }\n                }\n            }\n            \n            move_to(target.first, target.second);\n            if (h[r][c] < 0) {\n                int amt = (int)min(load, (long long)(-h[r][c]));\n                if (amt > 0) {\n                    ops.emplace_back(\"-\" + to_string(amt));\n                    load -= amt;\n                    h[r][c] += amt;\n                }\n            }\n        }\n    }\n    \n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Solver {\n    int N, M, T;\n    int SEED_COUNT;\n    struct Seed {\n        vector<int> x;\n        int sum;\n        int mx;\n    };\n    vector<Seed> seeds;\n    mt19937 rng;\n    chrono::steady_clock::time_point start_time;\n    const double TIME_LIMIT = 1.985;\n\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        start_time = chrono::steady_clock::now();\n    }\n\n    double getTime() {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - start_time).count();\n    }\n\n    void solveOneTurn(int turn, int total_turns) {\n        double turn_start = getTime();\n        double time_budget = (TIME_LIMIT - turn_start) / (total_turns - turn) * 0.998;\n        double turn_end = turn_start + time_budget;\n\n        // Select seeds\n        vector<pair<ll, int>> candidates;\n        for (int i = 0; i < SEED_COUNT; i++) {\n            ll score = seeds[i].sum + 5LL * seeds[i].mx;\n            candidates.push_back({score, i});\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        vector<int> selected;\n        for (int i = 0; i < N * N; i++) {\n            selected.push_back(candidates[i].second);\n        }\n\n        int S = N * N;\n        \n        // Precompute edge scores\n        vector<vector<ll>> edgeScore(S, vector<ll>(S));\n        for (int i = 0; i < S; i++) {\n            for (int j = i; j < S; j++) {\n                int a = selected[i];\n                int b = selected[j];\n                ll s = 0;\n                for (int l = 0; l < M; l++) {\n                    s += max(seeds[a].x[l], seeds[b].x[l]);\n                }\n                edgeScore[i][j] = edgeScore[j][i] = s;\n            }\n        }\n\n        // Position info\n        vector<pair<int,int>> idx2pos(S);\n        vector<vector<int>> neighbors(S);\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        \n        vector<pair<int, pair<int,int>>> posList;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int deg = (i>0) + (i<N-1) + (j>0) + (j<N-1);\n                posList.push_back({deg, {i, j}});\n            }\n        }\n        sort(posList.rbegin(), posList.rend());\n        \n        for (int k = 0; k < S; k++) {\n            idx2pos[k] = posList[k].second;\n        }\n        \n        vector<vector<int>> pos2idx(N, vector<int>(N, -1));\n        for (int k = 0; k < S; k++) {\n            auto [i, j] = idx2pos[k];\n            pos2idx[i][j] = k;\n        }\n        \n        for (int k = 0; k < S; k++) {\n            auto [i, j] = idx2pos[k];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    neighbors[k].push_back(pos2idx[ni][nj]);\n                }\n            }\n        }\n\n        auto calcCell = [&](int idx, const vector<int>& p) -> ll {\n            ll s = 0;\n            for (int nb : neighbors[idx]) {\n                s += edgeScore[p[idx]][p[nb]];\n            }\n            return s;\n        };\n\n        auto calcTotal = [&](const vector<int>& p) -> ll {\n            ll s = 0;\n            for (int i = 0; i < S; i++) s += calcCell(i, p);\n            return s / 2;\n        };\n\n        // Greedy construction considering edge scores\n        vector<int> placement(S, -1);\n        vector<bool> used(S, false);\n        \n        for (int posIdx = 0; posIdx < S; posIdx++) {\n            ll bestGain = -1;\n            int bestSeed = -1;\n            \n            // Try candidates in order of quality\n            for (int s = 0; s < S && (bestSeed == -1 || s < 30); s++) {\n                if (used[s]) continue;\n                ll gain = 0;\n                for (int nb : neighbors[posIdx]) {\n                    if (placement[nb] != -1) {\n                        gain += edgeScore[s][placement[nb]];\n                    }\n                }\n                // Bonus for good seeds\n                gain += candidates[s].first / 10;\n                \n                if (gain > bestGain) {\n                    bestGain = gain;\n                    bestSeed = s;\n                }\n            }\n            \n            placement[posIdx] = bestSeed;\n            used[bestSeed] = true;\n        }\n\n        // Quick local improvement of initial solution\n        for (int round = 0; round < 150 && getTime() < turn_end; round++) {\n            bool improved = false;\n            for (int i = 0; i < S && getTime() < turn_end; i++) {\n                for (int j = i + 1; j < S; j++) {\n                    ll old = calcCell(i, placement) + calcCell(j, placement);\n                    swap(placement[i], placement[j]);\n                    ll nw = calcCell(i, placement) + calcCell(j, placement);\n                    if (nw > old) {\n                        improved = true;\n                    } else {\n                        swap(placement[i], placement[j]);\n                    }\n                }\n            }\n            if (!improved) break;\n        }\n\n        // Calculate score\n        ll currentScore = 0;\n        for (int i = 0; i < S; i++) currentScore += calcCell(i, placement);\n        currentScore /= 2;\n        \n        vector<int> bestPlacement = placement;\n        ll bestScore = currentScore;\n\n        // Simulated Annealing with adaptive reheating\n        double temp = 600.0;\n        const double cooling = 0.99998;\n        int iter = 0;\n        int lastImprove = 0;\n        \n        while (getTime() < turn_end - 0.005) {\n            // Adaptive reheating\n            if (iter - lastImprove > 12000) {\n                temp = 300.0;\n                placement = bestPlacement;\n                currentScore = bestScore;\n                lastImprove = iter;\n            }\n\n            int i = rng() % S;\n            int j = rng() % S;\n            if (i == j) continue;\n\n            ll oldVal = calcCell(i, placement) + calcCell(j, placement);\n            swap(placement[i], placement[j]);\n            ll newVal = calcCell(i, placement) + calcCell(j, placement);\n            ll delta = newVal - oldVal;\n\n            if (delta > 0) {\n                currentScore += delta;\n                lastImprove = iter;\n                if (currentScore > bestScore) {\n                    bestScore = currentScore;\n                    bestPlacement = placement;\n                }\n            } else if (exp(delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore += delta;\n            } else {\n                swap(placement[i], placement[j]);\n            }\n\n            temp = max(temp * cooling, 0.0001);\n            iter++;\n        }\n\n        placement = bestPlacement;\n\n        // Final intensive local search - use remaining time\n        while (getTime() < turn_end) {\n            bool improved = false;\n            for (int i = 0; i < S && getTime() < turn_end; i++) {\n                for (int j = i + 1; j < S; j++) {\n                    ll oldVal = calcCell(i, placement) + calcCell(j, placement);\n                    swap(placement[i], placement[j]);\n                    ll newVal = calcCell(i, placement) + calcCell(j, placement);\n                    if (newVal > oldVal) {\n                        improved = true;\n                    } else {\n                        swap(placement[i], placement[j]);\n                    }\n                }\n            }\n            if (!improved) break;\n        }\n\n        // Output\n        vector<vector<int>> output(N, vector<int>(N));\n        for (int idx = 0; idx < S; idx++) {\n            auto [i, j] = idx2pos[idx];\n            output[i][j] = selected[placement[idx]];\n        }\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j > 0) cout << ' ';\n                cout << output[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n    }\n\n    void solve() {\n        cin >> N >> M >> T;\n        SEED_COUNT = 2 * N * (N - 1);\n        seeds.resize(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].x.resize(M);\n            seeds[i].sum = 0;\n            seeds[i].mx = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].x[j];\n                seeds[i].sum += seeds[i].x[j];\n                seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n            }\n        }\n\n        for (int turn = 0; turn < T; turn++) {\n            solveOneTurn(turn, T);\n\n            for (int i = 0; i < SEED_COUNT; i++) {\n                seeds[i].sum = 0;\n                seeds[i].mx = 0;\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i].x[j];\n                    seeds[i].sum += seeds[i].x[j];\n                    seeds[i].mx = max(seeds[i].mx, seeds[i].x[j]);\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V_limit;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nvector<int> hungarian(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    \n    for (int i=1; i<=n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(m+1, INT_MAX);\n        vector<char> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INT_MAX, j1 = 0;\n            for (int j=1; j<=m; j++) {\n                if (!used[j]) {\n                    int cur = cost[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n            }\n            for (int j=0; j<=m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    \n    vector<int> match(n);\n    for (int j=1; j<=m; j++) {\n        if (p[j] != 0) match[p[j]-1] = j-1;\n    }\n    return match;\n}\n\nint evaluate_order(const vector<int>& order, \n                   const vector<pair<pair<int,int>, pair<int,int>>>& pairs,\n                   int start_x, int start_y) {\n    const int L = 1;\n    int total = 0;\n    int rx = start_x, ry = start_y;\n    int dir = 0;\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    for (int idx : order) {\n        int sx = pairs[idx].first.first, sy = pairs[idx].first.second;\n        int best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = sx - dx[d] * L;\n            int ny = sy - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manh = manhattan(rx, ry, nx, ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            best_cost = min(best_cost, max(manh, rot));\n        }\n        total += best_cost + 1;\n        \n        int best_d = 0;\n        best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = sx - dx[d] * L;\n            int ny = sy - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manh = manhattan(rx, ry, nx, ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manh, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        rx = sx - dx[best_d] * L;\n        ry = sy - dy[best_d] * L;\n        dir = best_d;\n        \n        int dx_ = pairs[idx].second.first, dy_ = pairs[idx].second.second;\n        best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = dx_ - dx[d] * L;\n            int ny = dy_ - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manh = manhattan(rx, ry, nx, ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            best_cost = min(best_cost, max(manh, rot));\n        }\n        total += best_cost + 1;\n        \n        best_d = 0;\n        best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = dx_ - dx[d] * L;\n            int ny = dy_ - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manh = manhattan(rx, ry, nx, ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manh, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        rx = dx_ - dx[best_d] * L;\n        ry = dy_ - dy[best_d] * L;\n        dir = best_d;\n    }\n    \n    return total;\n}\n\nvector<int> greedy_order(function<int(int, int, int, int, int, int)> score_fn,\n                         const vector<pair<pair<int,int>, pair<int,int>>>& pairs,\n                         const vector<int>& indeg_in,\n                         const vector<vector<int>>& adj) {\n    int M = pairs.size();\n    vector<int> order;\n    vector<bool> processed(M, false);\n    vector<int> indeg = indeg_in;\n    \n    int cur_x = 0, cur_y = 0;\n    {\n        vector<int> xs, ys;\n        for (int i=0; i<M; i++) {\n            if (indeg[i] == 0) {\n                xs.push_back(pairs[i].first.first);\n                ys.push_back(pairs[i].first.second);\n            }\n        }\n        if (!xs.empty()) {\n            sort(xs.begin(), xs.end());\n            sort(ys.begin(), ys.end());\n            cur_x = xs[xs.size()/2];\n            cur_y = ys[ys.size()/2];\n        }\n    }\n    \n    for (int iter=0; iter<M; iter++) {\n        int best_i = -1;\n        int best_score = INT_MAX;\n        \n        for (int i=0; i<M; i++) {\n            if (processed[i] || indeg[i] > 0) continue;\n            \n            int sx = pairs[i].first.first, sy = pairs[i].first.second;\n            int dx = pairs[i].second.first, dy = pairs[i].second.second;\n            int score = score_fn(cur_x, cur_y, sx, sy, dx, dy);\n            \n            if (score < best_score) {\n                best_score = score;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        processed[best_i] = true;\n        order.push_back(best_i);\n        cur_x = pairs[best_i].second.first;\n        cur_y = pairs[best_i].second.second;\n        \n        for (int nb : adj[best_i]) {\n            indeg[nb]--;\n        }\n    }\n    \n    return order;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> V_limit;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i=0; i<N; i++) cin >> s_grid[i];\n    for (int i=0; i<N; i++) cin >> t_grid[i];\n\n    vector<pair<int,int>> sources, targets;\n    for (int i=0; i<N; i++) {\n        for (int j=0; j<N; j++) {\n            if (s_grid[i][j] == '1') sources.push_back({i, j});\n            if (t_grid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    vector<vector<int>> cost(M, vector<int>(M));\n    for (int i=0; i<M; i++) {\n        for (int j=0; j<M; j++) {\n            cost[i][j] = manhattan(sources[i].first, sources[i].second, \n                                   targets[j].first, targets[j].second);\n        }\n    }\n    \n    vector<int> match = hungarian(cost);\n    \n    vector<pair<pair<int,int>, pair<int,int>>> pairs;\n    for (int i=0; i<M; i++) {\n        pairs.push_back({sources[i], targets[match[i]]});\n    }\n\n    map<pair<int,int>, int> src_to_idx;\n    for (int i=0; i<M; i++) src_to_idx[pairs[i].first] = i;\n    \n    vector<vector<int>> adj(M);\n    vector<int> indeg(M, 0);\n    vector<set<int>> must_precede(M);\n    \n    for (int i=0; i<M; i++) {\n        auto it = src_to_idx.find(pairs[i].second);\n        if (it != src_to_idx.end()) {\n            int j = it->second;\n            if (i != j) {\n                adj[j].push_back(i);\n                indeg[i]++;\n                must_precede[i].insert(j);\n            }\n        }\n    }\n    \n    for (int k=0; k<M; k++) {\n        for (int i=0; i<M; i++) {\n            if (must_precede[i].count(k)) {\n                for (int j : must_precede[k]) must_precede[i].insert(j);\n            }\n        }\n    }\n\n    vector<function<int(int, int, int, int, int, int)>> strategies = {\n        [](int cx, int cy, int sx, int sy, int, int) { return manhattan(cx, cy, sx, sy); },\n        [](int cx, int cy, int sx, int sy, int dx, int dy) { \n            return manhattan(cx, cy, sx, sy) + manhattan(sx, sy, dx, dy); },\n        [](int cx, int cy, int sx, int sy, int dx, int dy) { \n            return manhattan(cx, cy, sx, sy) * 1000 + manhattan(sx, sy, dx, dy); },\n        [](int cx, int cy, int sx, int sy, int dx, int dy) { \n            return manhattan(cx, cy, sx, sy) * 1000 + manhattan(cx, cy, dx, dy); },\n        [](int cx, int cy, int sx, int sy, int dx, int dy) { \n            return manhattan(cx, cy, sx, sy) + manhattan(sx, sy, dx, dy) * 2; }\n    };\n\n    vector<int> best_order;\n    int best_eval = INT_MAX;\n    int best_start_x = 0, best_start_y = 0;\n    \n    for (auto& strat : strategies) {\n        vector<int> ord = greedy_order(strat, pairs, indeg, adj);\n        if ((int)ord.size() != M) continue;\n        \n        vector<pair<int,int>> starts;\n        \n        {\n            vector<int> xs, ys;\n            for (auto& p : sources) { xs.push_back(p.first); ys.push_back(p.second); }\n            sort(xs.begin(), xs.end()); sort(ys.begin(), ys.end());\n            starts.push_back({xs[xs.size()/2], ys[ys.size()/2]});\n        }\n        \n        {\n            vector<int> xs, ys;\n            int sample = min((int)ord.size(), 30);\n            for (int i=0; i<sample; i++) {\n                xs.push_back(pairs[ord[i]].first.first);\n                ys.push_back(pairs[ord[i]].first.second);\n            }\n            sort(xs.begin(), xs.end()); sort(ys.begin(), ys.end());\n            starts.push_back({xs[xs.size()/2], ys[ys.size()/2]});\n        }\n        \n        starts.push_back({pairs[ord[0]].first.first, pairs[ord[0]].first.second});\n        \n        sort(starts.begin(), starts.end());\n        starts.erase(unique(starts.begin(), starts.end()), starts.end());\n        \n        for (auto& [sx, sy] : starts) {\n            int ev = evaluate_order(ord, pairs, sx, sy);\n            if (ev < best_eval) {\n                best_eval = ev;\n                best_order = ord;\n                best_start_x = sx;\n                best_start_y = sy;\n            }\n        }\n    }\n\n    // Multiple-pass local search\n    for (int pass=0; pass<3; pass++) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i=0; i<(int)best_order.size()-1; i++) {\n                int a = best_order[i], b = best_order[i+1];\n                \n                if (must_precede[a].count(b) || must_precede[b].count(a)) continue;\n                \n                swap(best_order[i], best_order[i+1]);\n                int new_eval = evaluate_order(best_order, pairs, best_start_x, best_start_y);\n                \n                if (new_eval < best_eval) {\n                    best_eval = new_eval;\n                    improved = true;\n                } else {\n                    swap(best_order[i], best_order[i+1]);\n                }\n            }\n        }\n    }\n\n    // Optimize start position for final order\n    {\n        vector<pair<int,int>> candidates;\n        \n        // Median of first sources\n        {\n            vector<int> xs, ys;\n            int sample = min((int)best_order.size(), 30);\n            for (int i=0; i<sample; i++) {\n                xs.push_back(pairs[best_order[i]].first.first);\n                ys.push_back(pairs[best_order[i]].first.second);\n            }\n            sort(xs.begin(), xs.end()); sort(ys.begin(), ys.end());\n            candidates.push_back({xs[xs.size()/2], ys[ys.size()/2]});\n        }\n        \n        // Try nearby positions\n        int cx = candidates[0].first, cy = candidates[0].second;\n        for (int dx=-2; dx<=2; dx++) {\n            for (int dy=-2; dy<=2; dy++) {\n                int nx = cx + dx, ny = cy + dy;\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    candidates.push_back({nx, ny});\n                }\n            }\n        }\n        \n        for (auto& [sx, sy] : candidates) {\n            int ev = evaluate_order(best_order, pairs, sx, sy);\n            if (ev < best_eval) {\n                best_eval = ev;\n                best_start_x = sx;\n                best_start_y = sy;\n            }\n        }\n    }\n\n    vector<pair<pair<int,int>, pair<int,int>>> ordered;\n    for (int idx : best_order) ordered.push_back(pairs[idx]);\n\n    cout << 2 << \"\\n\";\n    cout << \"0 1\\n\";\n    cout << best_start_x << \" \" << best_start_y << \"\\n\";\n\n    const int L = 1;\n    int rx = best_start_x, ry = best_start_y;\n    int dir = 0;\n    const int dx[4] = {0, 1, 0, -1};\n    const int dy[4] = {1, 0, -1, 0};\n    \n    auto move_to = [&](int tx, int ty) {\n        int best_d = 0, best_cost = INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx = tx - dx[d] * L;\n            int ny = ty - dy[d] * L;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int manh = manhattan(rx, ry, nx, ny);\n            int rot = min((dir - d + 4) % 4, (d - dir + 4) % 4);\n            int cost = max(manh, rot);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        \n        int nx = tx - dx[best_d] * L;\n        int ny = ty - dy[best_d] * L;\n        \n        while (rx != nx || ry != ny || dir != best_d) {\n            string cmd(4, '.');\n            if (rx < nx) { cmd[0] = 'D'; rx++; }\n            else if (rx > nx) { cmd[0] = 'U'; rx--; }\n            else if (ry < ny) { cmd[0] = 'R'; ry++; }\n            else if (ry > ny) { cmd[0] = 'L'; ry--; }\n            \n            if (dir != best_d) {\n                int diff = (best_d - dir + 4) % 4;\n                if (diff == 1) { cmd[1] = 'R'; dir = (dir + 1) % 4; }\n                else if (diff == 3) { cmd[1] = 'L'; dir = (dir + 3) % 4; }\n                else if (diff == 2) { cmd[1] = 'R'; dir = (dir + 1) % 4; }\n            }\n            cout << cmd << \"\\n\";\n        }\n    };\n    \n    auto perform_action = [&]() {\n        string cmd(4, '.');\n        cmd[3] = 'P';\n        cout << cmd << \"\\n\";\n    };\n\n    for (auto& [src, dst] : ordered) {\n        move_to(src.first, src.second);\n        perform_action();\n        move_to(dst.first, dst.second);\n        perform_action();\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NEG_INF = -1e9;\nconst int CANDIDATES = 1000;\nconst int MAX_JUMP = 10;  // Increased from 5\n\nstruct SegTree {\n    struct Node {\n        int sum = 0;\n        int mx = 0;\n        int pref = 0;\n        int suff = 0;\n        int mx_l = 0, mx_r = 0;\n        int pref_r = 0;\n        int suff_l = 0;\n    };\n    \n    int n, real_n;\n    vector<Node> tree;\n    \n    SegTree(int sz) {\n        real_n = sz;\n        n = 1;\n        while (n < real_n) n <<= 1;\n        tree.resize(2 * n);\n        build(1, 0, n - 1);\n    }\n    \n    void build(int v, int l, int r) {\n        if (l == r) {\n            tree[v].mx_l = tree[v].mx_r = l;\n            tree[v].pref_r = l;\n            tree[v].suff_l = r;\n            if (l >= real_n) {\n                tree[v].mx = tree[v].pref = tree[v].suff = NEG_INF;\n            }\n            return;\n        }\n        int m = (l + r) >> 1;\n        build(v << 1, l, m);\n        build(v << 1 | 1, m + 1, r);\n        pull(v, v << 1, v << 1 | 1);\n    }\n    \n    void pull(int v, int L, int R) {\n        auto &res = tree[v];\n        auto &ln = tree[L];\n        auto &rn = tree[R];\n        \n        res.sum = ln.sum + rn.sum;\n        \n        if (ln.pref >= ln.sum + rn.pref) {\n            res.pref = ln.pref;\n            res.pref_r = ln.pref_r;\n        } else {\n            res.pref = ln.sum + rn.pref;\n            res.pref_r = rn.pref_r;\n        }\n        \n        if (rn.suff >= rn.sum + ln.suff) {\n            res.suff = rn.suff;\n            res.suff_l = rn.suff_l;\n        } else {\n            res.suff = rn.sum + ln.suff;\n            res.suff_l = ln.suff_l;\n        }\n        \n        res.mx = ln.mx;\n        res.mx_l = ln.mx_l;\n        res.mx_r = ln.mx_r;\n        \n        if (rn.mx > res.mx) {\n            res.mx = rn.mx;\n            res.mx_l = rn.mx_l;\n            res.mx_r = rn.mx_r;\n        }\n        \n        int cross = ln.suff + rn.pref;\n        if (cross > res.mx) {\n            res.mx = cross;\n            res.mx_l = ln.suff_l;\n            res.mx_r = rn.pref_r;\n        }\n    }\n    \n    void update(int pos, int val) { update(1, 0, n - 1, pos, val); }\n    \n    void update(int v, int l, int r, int pos, int val) {\n        if (l == r) {\n            tree[v].sum += val;\n            tree[v].mx += val;\n            tree[v].pref += val;\n            tree[v].suff += val;\n            return;\n        }\n        int m = (l + r) >> 1;\n        if (pos <= m) update(v << 1, l, m, pos, val);\n        else update(v << 1 | 1, m + 1, r, pos, val);\n        pull(v, v << 1, v << 1 | 1);\n    }\n    \n    const Node& root() const { return tree[1]; }\n};\n\nstruct Result {\n    int score = 0;\n    int x1 = 0, x2 = 1, y1 = 0, y2 = 1;\n};\n\nResult solve(const vector<int>& xcands, const map<int, vector<pair<int, int>>>& by_x, \n             const vector<int>& ys, int Y) {\n    Result res;\n    int X = xcands.size();\n    \n    for (int i = 0; i < X; ++i) {\n        SegTree fresh_seg(Y);\n        for (int j = i; j < X; ++j) {\n            int x = xcands[j];\n            auto it = by_x.find(x);\n            if (it != by_x.end()) {\n                for (auto &[yi, delta] : it->second) {\n                    fresh_seg.update(yi, delta);\n                }\n            }\n            \n            const auto &node = fresh_seg.root();\n            if (node.mx > res.score) {\n                if (0 <= node.mx_l && node.mx_l < Y && 0 <= node.mx_r && node.mx_r < Y) {\n                    res.score = node.mx;\n                    res.x1 = xcands[i];\n                    res.x2 = x;\n                    res.y1 = ys[node.mx_l];\n                    res.y2 = ys[node.mx_r];\n                    if (res.y1 > res.y2) swap(res.y1, res.y2);\n                }\n            }\n        }\n    }\n    return res;\n}\n\nResult solveTransposed(const vector<int>& ycands, const map<int, vector<pair<int, int>>>& by_y,\n                       const vector<int>& xs, int X) {\n    Result res;\n    int Y = ycands.size();\n    \n    for (int i = 0; i < Y; ++i) {\n        SegTree fresh_seg(X);\n        for (int j = i; j < Y; ++j) {\n            int y = ycands[j];\n            auto it = by_y.find(y);\n            if (it != by_y.end()) {\n                for (auto &[xi, delta] : it->second) {\n                    fresh_seg.update(xi, delta);\n                }\n            }\n            \n            const auto &node = fresh_seg.root();\n            if (node.mx > res.score) {\n                if (0 <= node.mx_l && node.mx_l < X && 0 <= node.mx_r && node.mx_r < X) {\n                    res.score = node.mx;\n                    res.y1 = ycands[i];\n                    res.y2 = y;\n                    res.x1 = xs[node.mx_l];\n                    res.x2 = xs[node.mx_r];\n                    if (res.x1 > res.x2) swap(res.x1, res.x2);\n                }\n            }\n        }\n    }\n    return res;\n}\n\nint calcScore(int x1, int x2, int y1, int y2, \n              const vector<pair<int, int>>& mack, \n              const vector<pair<int, int>>& sard) {\n    int score = 0;\n    for (auto &[x, y] : mack) {\n        if (x1 <= x && x <= x2 && y1 <= y && y <= y2) score++;\n    }\n    for (auto &[x, y] : sard) {\n        if (x1 <= x && x <= x2 && y1 <= y && y <= y2) score--;\n    }\n    return score;\n}\n\n// Multi-step look-ahead for expansion and shrinking\nResult optimizeEdges(Result res, \n                     const vector<int>& all_x, const vector<int>& all_y,\n                     const vector<pair<int, int>>& mack,\n                     const vector<pair<int, int>>& sard) {\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        \n        int xi1 = lower_bound(all_x.begin(), all_x.end(), res.x1) - all_x.begin();\n        int xi2 = lower_bound(all_x.begin(), all_x.end(), res.x2) - all_x.begin();\n        int yi1 = lower_bound(all_y.begin(), all_y.end(), res.y1) - all_y.begin();\n        int yi2 = lower_bound(all_y.begin(), all_y.end(), res.y2) - all_y.begin();\n        \n        // Look-ahead expansion: find best move\n        int bestScore = res.score;\n        int bestMove = 0; // 0=none, 1=left, 2=right, 3=down, 4=up\n        int bestPos = -1;\n        \n        // Expand left (decreasing xi1)\n        for (int step = 1; step <= MAX_JUMP && xi1 - step >= 0; ++step) {\n            int newScore = calcScore(all_x[xi1 - step], all_x[xi2], res.y1, res.y2, mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 1;\n                bestPos = xi1 - step;\n            }\n        }\n        \n        // Expand right (increasing xi2)\n        for (int step = 1; step <= MAX_JUMP && xi2 + step < (int)all_x.size(); ++step) {\n            int newScore = calcScore(all_x[xi1], all_x[xi2 + step], res.y1, res.y2, mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 2;\n                bestPos = xi2 + step;\n            }\n        }\n        \n        // Expand down (decreasing yi1)\n        for (int step = 1; step <= MAX_JUMP && yi1 - step >= 0; ++step) {\n            int newScore = calcScore(res.x1, res.x2, all_y[yi1 - step], all_y[yi2], mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 3;\n                bestPos = yi1 - step;\n            }\n        }\n        \n        // Expand up (increasing yi2)\n        for (int step = 1; step <= MAX_JUMP && yi2 + step < (int)all_y.size(); ++step) {\n            int newScore = calcScore(res.x1, res.x2, all_y[yi1], all_y[yi2 + step], mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 4;\n                bestPos = yi2 + step;\n            }\n        }\n        \n        // Shrink left (increasing xi1, but check boundary)\n        for (int step = 1; step <= MAX_JUMP && xi1 + step < xi2; ++step) {\n            int newScore = calcScore(all_x[xi1 + step], all_x[xi2], res.y1, res.y2, mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 5;\n                bestPos = xi1 + step;\n            }\n        }\n        \n        // Shrink right (decreasing xi2)\n        for (int step = 1; step <= MAX_JUMP && xi2 - step > xi1; ++step) {\n            int newScore = calcScore(all_x[xi1], all_x[xi2 - step], res.y1, res.y2, mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 6;\n                bestPos = xi2 - step;\n            }\n        }\n        \n        // Shrink down (increasing yi1)\n        for (int step = 1; step <= MAX_JUMP && yi1 + step < yi2; ++step) {\n            int newScore = calcScore(res.x1, res.x2, all_y[yi1 + step], all_y[yi2], mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 7;\n                bestPos = yi1 + step;\n            }\n        }\n        \n        // Shrink up (decreasing yi2)\n        for (int step = 1; step <= MAX_JUMP && yi2 - step > yi1; ++step) {\n            int newScore = calcScore(res.x1, res.x2, all_y[yi1], all_y[yi2 - step], mack, sard);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestMove = 8;\n                bestPos = yi2 - step;\n            }\n        }\n        \n        // Apply best move\n        if (bestMove != 0) {\n            improved = true;\n            res.score = bestScore;\n            switch (bestMove) {\n                case 1: res.x1 = all_x[bestPos]; break;\n                case 2: res.x2 = all_x[bestPos]; break;\n                case 3: res.y1 = all_y[bestPos]; break;\n                case 4: res.y2 = all_y[bestPos]; break;\n                case 5: res.x1 = all_x[bestPos]; break;\n                case 6: res.x2 = all_x[bestPos]; break;\n                case 7: res.y1 = all_y[bestPos]; break;\n                case 8: res.y2 = all_y[bestPos]; break;\n            }\n        }\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<pair<int, int>> mack(N), sard(N);\n    vector<int> xs, ys;\n    xs.reserve(2 * N);\n    ys.reserve(2 * N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mack[i].first >> mack[i].second;\n        xs.push_back(mack[i].first);\n        ys.push_back(mack[i].second);\n    }\n    for (int i = 0; i < N; ++i) {\n        cin >> sard[i].first >> sard[i].second;\n        xs.push_back(sard[i].first);\n        ys.push_back(sard[i].second);\n    }\n    \n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    int Y = ys.size();\n    \n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    int X_all = xs.size();\n    \n    map<int, vector<pair<int, int>>> by_x;\n    map<int, vector<pair<int, int>>> by_y;\n    \n    for (auto &[x, y] : mack) {\n        int yi = lower_bound(ys.begin(), ys.end(), y) - ys.begin();\n        int xi = lower_bound(xs.begin(), xs.end(), x) - xs.begin();\n        by_x[x].push_back({yi, +1});\n        by_y[y].push_back({xi, +1});\n    }\n    for (auto &[x, y] : sard) {\n        int yi = lower_bound(ys.begin(), ys.end(), y) - ys.begin();\n        int xi = lower_bound(xs.begin(), xs.end(), x) - xs.begin();\n        by_x[x].push_back({yi, -1});\n        by_y[y].push_back({xi, -1});\n    }\n    \n    Result best;\n    \n    if (X_all <= CANDIDATES && Y <= CANDIDATES) {\n        best = solve(xs, by_x, ys, Y);\n        best = optimizeEdges(best, xs, ys, mack, sard);\n    } else {\n        // X-sweep with top densest x\n        vector<pair<int, int>> dens_x;\n        for (int x : xs) {\n            auto it = by_x.find(x);\n            int cnt = (it == by_x.end()) ? 0 : it->second.size();\n            dens_x.push_back({-cnt, x});\n        }\n        sort(dens_x.begin(), dens_x.end());\n        vector<int> xcands;\n        for (int i = 0; i < min(CANDIDATES, (int)dens_x.size()); ++i) \n            xcands.push_back(dens_x[i].second);\n        sort(xcands.begin(), xcands.end());\n        \n        Result rx = solve(xcands, by_x, ys, Y);\n        rx = optimizeEdges(rx, xs, ys, mack, sard);\n        \n        // Y-sweep with top densest y\n        vector<pair<int, int>> dens_y;\n        for (int y : ys) {\n            auto it = by_y.find(y);\n            int cnt = (it == by_y.end()) ? 0 : it->second.size();\n            dens_y.push_back({-cnt, y});\n        }\n        sort(dens_y.begin(), dens_y.end());\n        vector<int> ycands;\n        for (int i = 0; i < min(CANDIDATES, (int)dens_y.size()); ++i) \n            ycands.push_back(dens_y[i].second);\n        sort(ycands.begin(), ycands.end());\n        \n        Result ry = solveTransposed(ycands, by_y, xs, X_all);\n        ry = optimizeEdges(ry, xs, ys, mack, sard);\n        \n        best = (rx.score > ry.score) ? rx : ry;\n    }\n    \n    if (best.x1 == best.x2) {\n        if (best.x2 < 100000) best.x2++;\n        else best.x1--;\n    }\n    if (best.y1 == best.y2) {\n        if (best.y2 < 100000) best.y2++;\n        else best.y1--;\n    }\n    \n    cout << 4 << \"\\n\";\n    cout << best.x1 << \" \" << best.y1 << \"\\n\";\n    cout << best.x2 << \" \" << best.y1 << \"\\n\";\n    cout << best.x2 << \" \" << best.y2 << \"\\n\";\n    cout << best.x1 << \" \" << best.y2 << \"\\n\";\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    const double LR = 0.3;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    normal_distribution<double> noise(0, sigma / 3.0);\n    \n    // Working buffers\n    vector<double> x(N), y(N), cw(N), ch(N);\n    vector<double> xs(N), ys(N), cws(N), chs(N);\n    vector<int> cand_r(N), cand_d(N), cand_b(N);\n    \n    // Best sequence found\n    vector<int> best_r, best_d, best_b;\n    double best_score = 1e300;\n    \n    auto run_greedy = [&](vector<double>& w_in, vector<double>& h_in, \n                          bool record, double& outW, double& outH) -> double {\n        double curW = 0, curH = 0;\n        for (int i = 0; i < N; i++) {\n            double bestSc = 1e300;\n            int bestR = 0, bestD = 0, bestB = -1;\n            double bestX = 0, bestY = 0;\n            double wi0 = w_in[i], hi0 = h_in[i];\n            \n            for (int r = 0; r < 2; r++) {\n                double wi = r ? hi0 : wi0;\n                double hi = r ? wi0 : hi0;\n                for (int d = 0; d < 2; d++) {\n                    for (int b = -1; b < i; b++) {\n                        double xi, yi;\n                        if (d == 0) { // U\n                            xi = (b == -1) ? 0 : (x[b] + cw[b]);\n                            yi = 0;\n                            for (int j = 0; j < i; j++) {\n                                if (xi < x[j] + cw[j] && xi + wi > x[j]) {\n                                    yi = max(yi, y[j] + ch[j]);\n                                }\n                            }\n                        } else { // L\n                            yi = (b == -1) ? 0 : (y[b] + ch[b]);\n                            xi = 0;\n                            for (int j = 0; j < i; j++) {\n                                if (yi < y[j] + ch[j] && yi + hi > y[j]) {\n                                    xi = max(xi, x[j] + cw[j]);\n                                }\n                            }\n                        }\n                        double nW = max(curW, xi + wi);\n                        double nH = max(curH, yi + hi);\n                        double sc = nW + nH;\n                        if (sc < bestSc) {\n                            bestSc = sc;\n                            bestR = r; bestD = d; bestB = b;\n                            bestX = xi; bestY = yi;\n                        }\n                    }\n                }\n            }\n            \n            if (record) {\n                cand_r[i] = bestR;\n                cand_d[i] = bestD;\n                cand_b[i] = bestB;\n            }\n            x[i] = bestX; y[i] = bestY;\n            cw[i] = bestR ? hi0 : wi0;\n            ch[i] = bestR ? wi0 : hi0;\n            curW = max(curW, bestX + cw[i]);\n            curH = max(curH, bestY + ch[i]);\n        }\n        outW = curW; outH = curH;\n        return curW + curH;\n    };\n    \n    auto simulate_sequence = [&](vector<int>& seq_r, vector<int>& seq_d, vector<int>& seq_b,\n                                double& outW, double& outH) -> double {\n        double curW = 0, curH = 0;\n        for (int i = 0; i < N; i++) {\n            int r = seq_r[i];\n            double wi = r ? h[i] : w[i];\n            double hi = r ? w[i] : h[i];\n            int b = seq_b[i];\n            \n            if (seq_d[i] == 0) { // U\n                xs[i] = (b == -1) ? 0 : (xs[b] + cws[b]);\n                ys[i] = 0;\n                for (int j = 0; j < i; j++) {\n                    if (xs[i] < xs[j] + cws[j] && xs[i] + wi > xs[j]) {\n                        ys[i] = max(ys[i], ys[j] + chs[j]);\n                    }\n                }\n            } else { // L\n                ys[i] = (b == -1) ? 0 : (ys[b] + chs[b]);\n                xs[i] = 0;\n                for (int j = 0; j < i; j++) {\n                    if (ys[i] < ys[j] + chs[j] && ys[i] + hi > ys[j]) {\n                        xs[i] = max(xs[i], xs[j] + cws[j]);\n                    }\n                }\n            }\n            cws[i] = wi; chs[i] = hi;\n            curW = max(curW, xs[i] + wi);\n            curH = max(curH, ys[i] + hi);\n        }\n        outW = curW; outH = curH;\n        return curW + curH;\n    };\n    \n    for (int turn = 0; turn < T; turn++) {\n        double bestW = 0, bestH = 0;\n        int choice = 0; // 0=greedy, 1=best_seq, 2=perturbed\n        \n        // Candidate 1: Greedy with current estimates\n        double g1W, g1H;\n        double s1 = run_greedy(w, h, true, g1W, g1H);\n        bestW = g1W; bestH = g1H;\n        \n        // Save greedy result\n        vector<int> gr_r = cand_r, gr_d = cand_d, gr_b = cand_b;\n        vector<double> gr_x = x, gr_y = y, gr_cw = cw, gr_ch = ch;\n        \n        // Candidate 2: Simulate stored best sequence\n        if (!best_r.empty()) {\n            double s2W, s2H;\n            double s2 = simulate_sequence(best_r, best_d, best_b, s2W, s2H);\n            if (s2 < s1) {\n                s1 = s2;\n                choice = 1;\n                bestW = s2W; bestH = s2H;\n                // Copy simulation results to output buffers\n                x = xs; y = ys;\n                cw = cws; ch = chs;\n                cand_r = best_r; cand_d = best_d; cand_b = best_b;\n            }\n        }\n        \n        // Candidate 3: Greedy with perturbed estimates (exploration)\n        if (turn < T - 1) { // Don't explore on last turn\n            vector<double> wp = w, hp = h;\n            for (int i = 0; i < N; i++) {\n                wp[i] += noise(rng);\n                hp[i] += noise(rng);\n                if (wp[i] < 1) wp[i] = 1;\n                if (hp[i] < 1) hp[i] = 1;\n            }\n            double g3W, g3H;\n            double s3 = run_greedy(wp, hp, true, g3W, g3H);\n            if (s3 < s1) {\n                choice = 2;\n                bestW = g3W; bestH = g3H;\n                // The perturbed greedy used perturbed sizes for decisions,\n                // but we need to re-simulate with true sizes to get valid positions\n                // Actually, run_greedy used wp/hp for decisions, but we need\n                // to re-run with w,h to get correct positions... \n                // For simplicity, just use the sequence, re-simulate with true sizes\n                simulate_sequence(cand_r, cand_d, cand_b, bestW, bestH);\n                x = xs; y = ys;\n                cw = cws; ch = chs;\n            }\n        }\n        \n        // Update best sequence if improved\n        double cur_score = bestW + bestH;\n        if (cur_score < best_score) {\n            best_score = cur_score;\n            if (choice == 0) {\n                best_r = gr_r; best_d = gr_d; best_b = gr_b;\n            } else if (choice == 2) {\n                best_r = cand_r; best_d = cand_d; best_b = cand_b;\n            }\n            // choice == 1: already stored\n        }\n        \n        // Output\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++) {\n            cout << i << \" \" << cand_r[i] << \" \" << (cand_d[i] == 0 ? 'U' : 'L') << \" \" << cand_b[i] << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read feedback and update estimates\n        double Wp, Hp;\n        cin >> Wp >> Hp;\n        \n        for (int i = 0; i < N; i++) {\n            double right_edge = x[i] + cw[i];\n            double bottom_edge = y[i] + ch[i];\n            int r = cand_r[i];\n            \n            if (right_edge >= bestW - 1e-6) {\n                double target = max(1.0, Wp - x[i]);\n                if (r) h[i] = (1.0 - LR) * h[i] + LR * target;\n                else w[i] = (1.0 - LR) * w[i] + LR * target;\n            }\n            if (bottom_edge >= bestH - 1e-6) {\n                double target = max(1.0, Hp - y[i]);\n                if (r) w[i] = (1.0 - LR) * w[i] + LR * target;\n                else h[i] = (1.0 - LR) * h[i] + LR * target;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> parent;\n    vector<int> depth;\n    vector<long long> sub_sum;\n    vector<int> height;\n    vector<vector<int>> children;\n    vector<char> attached;\n    \n    void input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; i++) cin >> A[i];\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v; cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        for (int i = 0; i < N; i++) {\n            int x, y; cin >> x >> y;\n        }\n    }\n    \n    bool is_ancestor_fast(int u, int v) {\n        int steps = 0;\n        while (v != -1 && steps <= H) {\n            if (v == u) return true;\n            v = parent[v];\n            steps++;\n        }\n        return false;\n    }\n    \n    long long compute_score() {\n        long long res = 0;\n        for (int i = 0; i < N; i++) {\n            res += (long long)(depth[i] + 1) * A[i];\n        }\n        return res;\n    }\n    \n    void solve_once(mt19937& rng, vector<int>& best_parent, long long& best_score, bool beauty_first) {\n        parent.assign(N, -1);\n        depth.assign(N, -1);\n        sub_sum.resize(N);\n        height.resize(N);\n        children.assign(N, {});\n        attached.assign(N, 0);\n        \n        for (int i = 0; i < N; i++) {\n            sub_sum[i] = A[i];\n            height[i] = 0;\n        }\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        if (beauty_first) {\n            sort(order.begin(), order.end(), [&](int i, int j) {\n                return A[i] > A[j];\n            });\n        } else {\n            shuffle(order.begin(), order.end(), rng);\n        }\n        \n        int attached_count = 0;\n        \n        while (attached_count < N) {\n            long long best_gain = -1;\n            int best_r = -1, best_u = -1;\n            int best_depth = -1;\n            \n            for (int r : order) {\n                if (attached[r]) continue;\n                \n                for (int u : adj[r]) {\n                    if (!attached[u]) continue;\n                    if (depth[u] + 1 + height[r] > H) continue;\n                    \n                    long long gain = (long long)(depth[u] + 1) * sub_sum[r];\n                    if (gain > best_gain || (gain == best_gain && depth[u] > best_depth)) {\n                        best_gain = gain;\n                        best_r = r;\n                        best_u = u;\n                        best_depth = depth[u];\n                    }\n                }\n            }\n            \n            if (best_gain < 0) {\n                for (int v : order) {\n                    if (!attached[v]) {\n                        parent[v] = -1;\n                        depth[v] = 0;\n                        attached[v] = 1;\n                        attached_count++;\n                        break;\n                    }\n                }\n            } else {\n                parent[best_r] = best_u;\n                children[best_u].push_back(best_r);\n                depth[best_r] = depth[best_u] + 1;\n                attached[best_r] = 1;\n                attached_count++;\n                \n                queue<int> q;\n                q.push(best_r);\n                while (!q.empty()) {\n                    int v = q.front(); q.pop();\n                    for (int c : children[v]) {\n                        depth[c] = depth[v] + 1;\n                        q.push(c);\n                    }\n                }\n                \n                int x = best_u;\n                while (x != -1) {\n                    sub_sum[x] += sub_sum[best_r];\n                    int new_h = 0;\n                    for (int c : children[x]) {\n                        new_h = max(new_h, height[c] + 1);\n                    }\n                    height[x] = new_h;\n                    x = parent[x];\n                }\n            }\n        }\n        \n        // Phase 1: Steepest ascent local search\n        for (int iter = 0; iter < 100; iter++) {\n            long long best_move_gain = 0;\n            int best_v = -1, best_new_parent = -1, best_old_parent = -1;\n            \n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                \n                int cur_p = parent[v];\n                int cur_d = depth[v];\n                long long cur_sub = sub_sum[v];\n                \n                for (int u : adj[v]) {\n                    if (u == cur_p) continue;\n                    if (is_ancestor_fast(v, u)) continue;\n                    \n                    int new_d = depth[u] + 1;\n                    if (new_d <= cur_d) continue;\n                    if (new_d + height[v] > H) continue;\n                    \n                    long long gain = (long long)(new_d - cur_d) * cur_sub;\n                    if (gain > best_move_gain) {\n                        best_move_gain = gain;\n                        best_v = v;\n                        best_new_parent = u;\n                        best_old_parent = cur_p;\n                    }\n                }\n            }\n            \n            if (best_v == -1) break;\n            \n            apply_move(best_v, best_new_parent, best_old_parent);\n        }\n        \n        // Phase 2: Randomized local search for diversification\n        for (int iter = 0; iter < 50; iter++) {\n            vector<int> candidates;\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                candidates.push_back(v);\n            }\n            shuffle(candidates.begin(), candidates.end(), rng);\n            \n            bool improved = false;\n            for (int v : candidates) {\n                int cur_p = parent[v];\n                int cur_d = depth[v];\n                \n                vector<pair<int, long long>> moves;\n                for (int u : adj[v]) {\n                    if (u == cur_p) continue;\n                    if (is_ancestor_fast(v, u)) continue;\n                    \n                    int new_d = depth[u] + 1;\n                    if (new_d <= cur_d) continue;\n                    if (new_d + height[v] > H) continue;\n                    \n                    long long gain = (long long)(new_d - cur_d) * sub_sum[v];\n                    moves.push_back({u, gain});\n                }\n                \n                if (moves.empty()) continue;\n                \n                // Pick best move for this vertex\n                auto best = *max_element(moves.begin(), moves.end(), \n                    [](auto& a, auto& b) { return a.second < b.second; });\n                \n                if (best.second > 0) {\n                    apply_move(v, best.first, cur_p);\n                    improved = true;\n                    break;\n                }\n            }\n            if (!improved) break;\n        }\n        \n        long long score = compute_score();\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n    \n    void apply_move(int v, int u, int old_p) {\n        long long sub_v = sub_sum[v];\n        \n        auto& vec = children[old_p];\n        vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n        \n        int x = old_p;\n        while (x != -1) {\n            sub_sum[x] -= sub_v;\n            x = parent[x];\n        }\n        \n        x = old_p;\n        while (x != -1) {\n            int new_h = 0;\n            for (int c : children[x]) {\n                new_h = max(new_h, height[c] + 1);\n            }\n            if (new_h == height[x]) break;\n            height[x] = new_h;\n            x = parent[x];\n        }\n        \n        parent[v] = u;\n        children[u].push_back(v);\n        depth[v] = depth[u] + 1;\n        \n        queue<int> qq;\n        qq.push(v);\n        while (!qq.empty()) {\n            int cur = qq.front(); qq.pop();\n            for (int c : children[cur]) {\n                depth[c] = depth[cur] + 1;\n                qq.push(c);\n            }\n        }\n        \n        x = u;\n        while (x != -1) {\n            sub_sum[x] += sub_v;\n            int new_h = 0;\n            for (int c : children[x]) {\n                new_h = max(new_h, height[c] + 1);\n            }\n            height[x] = new_h;\n            x = parent[x];\n        }\n    }\n    \n    void solve() {\n        input();\n        \n        vector<int> best_parent;\n        long long best_score = -1;\n        \n        for (int attempt = 0; attempt < 6; attempt++) {\n            mt19937 rng(chrono::steady_clock::now().time_since_epoch().count() + attempt * 10007);\n            solve_once(rng, best_parent, best_score, true);\n        }\n        \n        for (int attempt = 0; attempt < 6; attempt++) {\n            mt19937 rng(chrono::steady_clock::now().time_since_epoch().count() + attempt * 20011);\n            solve_once(rng, best_parent, best_score, false);\n        }\n        \n        parent = best_parent;\n        \n        for (int i = 0; i < N; i++) {\n            if (i) cout << \" \";\n            cout << parent[i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<vector<bool>> initial_oni, is_fuku;\nvector<int> max_up, min_down, max_left, min_right;\nvector<vector<array<bool, 4>>> valid_dirs;\n\nstruct State {\n    vector<vector<bool>> oni;\n    vector<pair<char, int>> ops;\n    int cost;\n};\n\nvector<vector<int>> compute_dirs(const vector<vector<bool>>& oni) {\n    vector<vector<int>> res(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (oni[i][j]) {\n                for (int d = 0; d < 4; d++) if (valid_dirs[i][j][d]) res[i][j]++;\n            }\n        }\n    }\n    return res;\n}\n\nState solve(double w, double forced_bonus, int urgency_pow, bool count_total_urgency) {\n    State s;\n    s.oni = initial_oni;\n    s.cost = 0;\n    \n    while (true) {\n        auto dirs = compute_dirs(s.oni);\n        int rem = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (s.oni[i][j]) rem++;\n        if (rem == 0) break;\n        \n        bool has_forced = false;\n        for (int i = 0; i < N && !has_forced; i++) \n            for (int j = 0; j < N; j++) \n                if (s.oni[i][j] && dirs[i][j] == 1) { has_forced = true; break; }\n        \n        double best_sc = -1e300;\n        char bd = 0; \n        int bi = 0, bl = 0, bc = 0;\n        \n        auto upd = [&](double sc, char d, int i, int l, int c) {\n            if (sc > best_sc || (sc == best_sc && c < bc)) {\n                best_sc = sc; bd = d; bi = i; bl = l; bc = c;\n            }\n        };\n        \n        auto urg_fn = [&](int d) -> double {\n            if (d <= 0) return 0;\n            if (urgency_pow == 0) return 1.0;\n            if (urgency_pow == 1) return 1.0 / d;\n            if (urgency_pow == 2) return 1.0 / (d * d);\n            return 1.0 / sqrt(d);\n        };\n        \n        // Up\n        for (int j = 0; j < N; j++) {\n            if (max_up[j] < 0) continue;\n            int hi = -1, cnt = 0; \n            double urg = 0;\n            int forced_cnt = 0;\n            for (int i = 0; i <= max_up[j]; i++) if (s.oni[i][j]) {\n                cnt++; hi = i; \n                urg += urg_fn(dirs[i][j]);\n                if (dirs[i][j] == 1) forced_cnt++;\n            }\n            if (cnt) {\n                int c = 2 * (hi + 1);\n                double eff = (double)cnt / c;\n                double score = eff;\n                if (count_total_urgency) score += w * urg;\n                else score += w * urg / c;\n                if (has_forced && forced_cnt > 0) score += forced_bonus * forced_cnt / c;\n                upd(score, 'U', j, hi, c);\n            }\n        }\n        \n        // Down\n        for (int j = 0; j < N; j++) {\n            if (min_down[j] >= N) continue;\n            int lo = N, cnt = 0; \n            double urg = 0;\n            int forced_cnt = 0;\n            for (int i = min_down[j]; i < N; i++) if (s.oni[i][j]) {\n                cnt++; lo = i; \n                urg += urg_fn(dirs[i][j]);\n                if (dirs[i][j] == 1) forced_cnt++;\n            }\n            if (cnt) {\n                int c = 2 * (N - lo);\n                double eff = (double)cnt / c;\n                double score = eff;\n                if (count_total_urgency) score += w * urg;\n                else score += w * urg / c;\n                if (has_forced && forced_cnt > 0) score += forced_bonus * forced_cnt / c;\n                upd(score, 'D', j, lo, c);\n            }\n        }\n        \n        // Left\n        for (int i = 0; i < N; i++) {\n            if (max_left[i] < 0) continue;\n            int ri = -1, cnt = 0; \n            double urg = 0;\n            int forced_cnt = 0;\n            for (int j = 0; j <= max_left[i]; j++) if (s.oni[i][j]) {\n                cnt++; ri = j; \n                urg += urg_fn(dirs[i][j]);\n                if (dirs[i][j] == 1) forced_cnt++;\n            }\n            if (cnt) {\n                int c = 2 * (ri + 1);\n                double eff = (double)cnt / c;\n                double score = eff;\n                if (count_total_urgency) score += w * urg;\n                else score += w * urg / c;\n                if (has_forced && forced_cnt > 0) score += forced_bonus * forced_cnt / c;\n                upd(score, 'L', i, ri, c);\n            }\n        }\n        \n        // Right\n        for (int i = 0; i < N; i++) {\n            if (min_right[i] >= N) continue;\n            int le = N, cnt = 0; \n            double urg = 0;\n            int forced_cnt = 0;\n            for (int j = min_right[i]; j < N; j++) if (s.oni[i][j]) {\n                cnt++; le = j; \n                urg += urg_fn(dirs[i][j]);\n                if (dirs[i][j] == 1) forced_cnt++;\n            }\n            if (cnt) {\n                int c = 2 * (N - le);\n                double eff = (double)cnt / c;\n                double score = eff;\n                if (count_total_urgency) score += w * urg;\n                else score += w * urg / c;\n                if (has_forced && forced_cnt > 0) score += forced_bonus * forced_cnt / c;\n                upd(score, 'R', i, le, c);\n            }\n        }\n        \n        if (bd == 0) break;\n        \n        if (bd == 'U') {\n            int j = bi, h = bl;\n            for (int k = 0; k <= h; k++) s.ops.push_back({'U', j});\n            for (int k = 0; k <= h; k++) s.ops.push_back({'D', j});\n            for (int i = 0; i <= h; i++) s.oni[i][j] = false;\n            s.cost += 2 * (h + 1);\n        } else if (bd == 'D') {\n            int j = bi, l = bl, t = N - l;\n            for (int k = 0; k < t; k++) s.ops.push_back({'D', j});\n            for (int k = 0; k < t; k++) s.ops.push_back({'U', j});\n            for (int i = l; i < N; i++) s.oni[i][j] = false;\n            s.cost += 2 * t;\n        } else if (bd == 'L') {\n            int i = bi, r = bl;\n            for (int k = 0; k <= r; k++) s.ops.push_back({'L', i});\n            for (int k = 0; k <= r; k++) s.ops.push_back({'R', i});\n            for (int j = 0; j <= r; j++) s.oni[i][j] = false;\n            s.cost += 2 * (r + 1);\n        } else {\n            int i = bi, l = bl, t = N - l;\n            for (int k = 0; k < t; k++) s.ops.push_back({'R', i});\n            for (int k = 0; k < t; k++) s.ops.push_back({'L', i});\n            for (int j = l; j < N; j++) s.oni[i][j] = false;\n            s.cost += 2 * t;\n        }\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    vector<string> C(N);\n    for (int i = 0; i < N; i++) cin >> C[i];\n    \n    initial_oni = vector<vector<bool>>(N, vector<bool>(N));\n    is_fuku = vector<vector<bool>>(N, vector<bool>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (C[i][j] == 'x') initial_oni[i][j] = true;\n            else if (C[i][j] == 'o') is_fuku[i][j] = true;\n        }\n    }\n    \n    max_up = vector<int>(N, N - 1);\n    min_down = vector<int>(N, 0);\n    max_left = vector<int>(N, N - 1);\n    min_right = vector<int>(N, 0);\n    \n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) if (is_fuku[i][j]) { max_up[j] = i - 1; break; }\n        for (int i = N - 1; i >= 0; i--) if (is_fuku[i][j]) { min_down[j] = i + 1; break; }\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) if (is_fuku[i][j]) { max_left[i] = j - 1; break; }\n        for (int j = N - 1; j >= 0; j--) if (is_fuku[i][j]) { min_right[i] = j + 1; break; }\n    }\n    \n    valid_dirs = vector<vector<array<bool, 4>>>(N, vector<array<bool, 4>>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            valid_dirs[i][j] = {i <= max_up[j], i >= min_down[j], j <= max_left[i], j >= min_right[i]};\n        }\n    }\n    \n    State best;\n    best.cost = 1e9;\n    \n    // Very extensive search\n    for (int up = -1; up <= 2; up++) {\n        for (double w = 0.0; w <= 10.0; w += 0.5) {\n            for (double fb = 0.0; fb <= 50.0; fb += 5.0) {\n                for (int ctu = 0; ctu <= 1; ctu++) {\n                    auto s = solve(w, fb, up, ctu);\n                    if (s.cost < best.cost) best = move(s);\n                }\n            }\n        }\n    }\n    \n    // Fine search around best regions\n    for (double w = 0.0; w <= 5.0; w += 0.1) {\n        for (double fb = 0.0; fb <= 30.0; fb += 2.0) {\n            auto s = solve(w, fb, 1, false);\n            if (s.cost < best.cost) best = move(s);\n        }\n    }\n    \n    for (auto& [d, p] : best.ops) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const auto START = chrono::steady_clock::now();\n    const int TL_MS = 1995;\n    auto elapsed = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n            chrono::steady_clock::now() - START).count();\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_err = (1LL << 60);\n    \n    auto evaluate = [&](const vector<int>& a, const vector<int>& b, vector<int>& cnt) -> long long {\n        fill(cnt.begin(), cnt.end(), 0);\n        int cur = 0;\n        for (int week = 0; week < L; ++week) {\n            cnt[cur]++;\n            if (week == L - 1) break;\n            cur = (cnt[cur] & 1) ? a[cur] : b[cur];\n        }\n        long long err = 0;\n        for (int i = 0; i < N; ++i) err += llabs((long long)cnt[i] - T[i]);\n        return err;\n    };\n    \n    // Greedy init with deterministic fallback\n    auto greedy_init = [&](int seed) {\n        mt19937 gen(seed);\n        vector<int> a(N), b(N);\n        vector<long long> rem(N);\n        for (int i = 0; i < N; ++i) rem[i] = T[i];\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), gen);\n        \n        for (int idx : order) {\n            // Find max remaining with tie-breaking\n            long long mx = *max_element(rem.begin(), rem.end());\n            vector<int> cands;\n            for (int j = 0; j < N; ++j) \n                if (rem[j] == mx) cands.push_back(j);\n            int ja = cands[uniform_int_distribution<int>(0, cands.size()-1)(gen)];\n            a[idx] = ja;\n            rem[ja] -= (T[idx] + 1) / 2;\n            \n            mx = *max_element(rem.begin(), rem.end());\n            cands.clear();\n            for (int j = 0; j < N; ++j) \n                if (rem[j] == mx) cands.push_back(j);\n            int jb = cands[uniform_int_distribution<int>(0, cands.size()-1)(gen)];\n            b[idx] = jb;\n            rem[jb] -= T[idx] / 2;\n        }\n        return make_pair(a, b);\n    };\n    \n    // Flow-based init\n    auto flow_init = [&](int seed) {\n        mt19937 gen(seed);\n        vector<int> a(N), b(N);\n        vector<long long> load(N, 0);\n        \n        vector<tuple<int, int, bool>> items;\n        for (int i = 0; i < N; ++i) {\n            items.push_back({(T[i] + 1) / 2, i, true});\n            items.push_back({T[i] / 2, i, false});\n        }\n        sort(items.rbegin(), items.rend());\n        \n        // Shuffle ties\n        for (int i = 0; i < (int)items.size(); ) {\n            int j = i;\n            while (j < (int)items.size() && get<0>(items[j]) == get<0>(items[i])) j++;\n            shuffle(items.begin() + i, items.begin() + j, gen);\n            i = j;\n        }\n        \n        for (auto& [w, from, is_a] : items) {\n            long long max_def = (long long)T[0] - load[0];\n            int best = 0;\n            for (int j = 1; j < N; ++j) {\n                long long def = (long long)T[j] - load[j];\n                if (def > max_def) {\n                    max_def = def;\n                    best = j;\n                }\n            }\n            if (is_a) a[from] = best;\n            else b[from] = best;\n            load[best] += w;\n        }\n        return make_pair(a, b);\n    };\n    \n    // Adaptive local search with SA-like acceptance early on\n    auto local_search = [&](vector<int> a, vector<int> b, int seed, int deadline, bool use_sa) {\n        mt19937 gen(seed);\n        vector<int> cnt(N);\n        long long cur = evaluate(a, b, cnt);\n        \n        auto upd_best = [&]() {\n            if (cur < best_err) {\n                best_err = cur;\n                best_a = a;\n                best_b = b;\n            }\n        };\n        upd_best();\n        \n        double temp = max(cur / 20.0, 100.0);\n        const double cooling = 0.99998;\n        int iter = 0, last_improve = 0;\n        \n        while (elapsed() < deadline) {\n            ++iter;\n            \n            // Large perturbation restart\n            if (!use_sa && iter - last_improve > 8000) {\n                a = best_a;\n                b = best_b;\n                // Strong perturbation\n                for (int k = 0; k < N/10 + 3; ++k) {\n                    int i = uniform_int_distribution<int>(0, N-1)(gen);\n                    int t = uniform_int_distribution<int>(0, 2)(gen);\n                    if (t == 0) a[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                    else if (t == 1) b[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                    else swap(a[i], b[i]);\n                }\n                cur = evaluate(a, b, cnt);\n                last_improve = iter;\n                upd_best();\n                continue;\n            }\n            \n            vector<int> na = a, nb = b;\n            \n            // Error-based analysis\n            vector<pair<int, long long>> errs;\n            for (int i = 0; i < N; ++i)\n                errs.push_back({i, llabs((long long)cnt[i] - T[i])});\n            sort(errs.begin(), errs.end(),\n                 [](auto& x, auto& y) { return x.second > y.second; });\n            \n            int move_type = uniform_int_distribution<int>(0, 99)(gen);\n            \n            if (move_type < 40) {\n                // Pure random\n                int i = uniform_int_distribution<int>(0, N-1)(gen);\n                int t = uniform_int_distribution<int>(0, 2)(gen);\n                if (t == 0) na[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else if (t == 1) nb[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else swap(na[i], nb[i]);\n            } else if (move_type < 60) {\n                // 2-swap\n                int i = uniform_int_distribution<int>(0, N-1)(gen);\n                int j = uniform_int_distribution<int>(0, N-1)(gen);\n                if (i == j) j = (j + 1) % N;\n                int t = uniform_int_distribution<int>(0, 3)(gen);\n                if (t == 0) swap(na[i], na[j]);\n                else if (t == 1) swap(nb[i], nb[j]);\n                else if (t == 2) swap(na[i], nb[j]);\n                else swap(nb[i], na[j]);\n            } else if (move_type < 75) {\n                // Focus on high-error nodes\n                int i = errs[uniform_int_distribution<int>(0, min(4, N-1))(gen)].first;\n                int t = uniform_int_distribution<int>(0, 2)(gen);\n                if (t == 0) na[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else if (t == 1) nb[i] = uniform_int_distribution<int>(0, N-1)(gen);\n                else swap(na[i], nb[i]);\n            } else {\n                // Smart targeted\n                int worst = errs[0].first;\n                long long diff = (long long)cnt[worst] - T[worst];\n                \n                if (diff > 0) {\n                    // Surplus - redirect away\n                    vector<pair<int, bool>> inc;\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] == worst) inc.push_back({i, true});\n                        if (b[i] == worst) inc.push_back({i, false});\n                    }\n                    if (!inc.empty()) {\n                        auto [from, is_a] = inc[uniform_int_distribution<int>(0, inc.size()-1)(gen)];\n                        // Prefer deficit nodes\n                        int to = -1;\n                        for (int k = 0; k < 5 && to == -1; ++k) {\n                            int cand = errs[min((int)errs.size()-1, k)].first;\n                            if (cnt[cand] < T[cand]) to = cand;\n                        }\n                        if (to == -1) to = uniform_int_distribution<int>(0, N-1)(gen);\n                        if (is_a) na[from] = to;\n                        else nb[from] = to;\n                    }\n                } else if (diff < 0) {\n                    // Deficit - attract\n                    vector<pair<int, bool>> non_inc;\n                    for (int i = 0; i < N; ++i) {\n                        if (a[i] != worst) non_inc.push_back({i, true});\n                        if (b[i] != worst) non_inc.push_back({i, false});\n                    }\n                    if (!non_inc.empty()) {\n                        auto [from, is_a] = non_inc[uniform_int_distribution<int>(0, non_inc.size()-1)(gen)];\n                        if (is_a) na[from] = worst;\n                        else nb[from] = worst;\n                    }\n                } else {\n                    // Balanced but high variance - try 2-swap with another high-error node\n                    int i = worst;\n                    int j = errs[min((int)errs.size()-1, 1)].first;\n                    if (i != j) swap(na[i], na[j]);\n                }\n            }\n            \n            vector<int> ncnt(N);\n            long long nerr = evaluate(na, nb, ncnt);\n            \n            bool accept = false;\n            if (nerr < cur) accept = true;\n            else if (use_sa && nerr < cur + temp * 2) {\n                double prob = exp((cur - nerr) / temp);\n                if (uniform_real_distribution<double>(0, 1)(gen) < prob) accept = true;\n            }\n            \n            if (accept) {\n                if (nerr < cur) last_improve = iter;\n                a = na; b = nb; cur = nerr; cnt = ncnt;\n                upd_best();\n            }\n            \n            if (use_sa) temp = max(0.001, temp * cooling);\n        }\n    };\n    \n    // Quick initial search to find good baseline\n    vector<int> seeds = {42, 123, 456, 789, 1011, 1213, 1415, 1617, 1819, 2021, 2223, 2425, 2627, 2829};\n    \n    // Fast greedy passes\n    for (int s : seeds) {\n        if (elapsed() > TL_MS * 0.15) break;\n        auto [a, b] = greedy_init(s);\n        local_search(a, b, s, elapsed() + 80, false);\n    }\n    \n    // Fast flow passes\n    for (int s : seeds) {\n        if (elapsed() > TL_MS * 0.25) break;\n        auto [a, b] = flow_init(s);\n        local_search(a, b, s + 1000000, elapsed() + 60, false);\n    }\n    \n    // Intensive hill climbing from best\n    local_search(best_a, best_b, 77777, TL_MS * 0.6, false);\n    \n    // SA refinement phases\n    auto a = best_a, b = best_b;\n    mt19937 pgen(99999);\n    for (int phase = 0; phase < 3 && elapsed() < TL_MS - 50; ++phase) {\n        // Moderate perturbation\n        for (int i = 0; i < N/20 + phase; ++i) {\n            int idx = uniform_int_distribution<int>(0, N-1)(pgen);\n            if (uniform_int_distribution<int>(0, 1)(pgen) == 0)\n                a[idx] = uniform_int_distribution<int>(0, N-1)(pgen);\n            else\n                b[idx] = uniform_int_distribution<int>(0, N-1)(pgen);\n        }\n        int end_time = min(TL_MS - 10, (int)(elapsed() + (TL_MS - elapsed()) / (3 - phase)));\n        local_search(a, b, 88888 + phase, end_time, phase == 0);\n        a = best_a; b = best_b;\n    }\n    \n    // Final intensive cleanup\n    if (elapsed() < TL_MS) {\n        local_search(best_a, best_b, 66666, TL_MS, false);\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nlong long hilbertOrder(int x, int y, int pow = 16, int rot = 0) {\n    if (pow == 0) return 0;\n    int h = 1 << (pow - 1);\n    int seg = (x < h ? (y < h ? 0 : 3) : (y < h ? 1 : 2));\n    seg = (seg + rot) & 3;\n    static const int rotateDelta[4] = {3, 0, 0, 1};\n    int nx = x & (h - 1), ny = y & (h - 1);\n    int nrot = (rot + rotateDelta[seg]) & 3;\n    long long subSquareSize = 1LL << (2 * pow - 2);\n    long long ord = seg * subSquareSize;\n    long long add = hilbertOrder(nx, ny, pow - 1, nrot);\n    ord += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);\n    return ord;\n}\n\nstruct DSU {\n    vector<int> p;\n    DSU(int n) { p.resize(n); iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        p[y] = x;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    \n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n    \n    // Group assignment via recursive bisection\n    vector<vector<int>> groups(M);\n    function<void(vector<int>&, int, int, int)> partition = [&](vector<int>& ids, int gl, int gr, int depth) {\n        if (gl + 1 == gr) {\n            for (int id : ids) groups[gl].push_back(id);\n            return;\n        }\n        int gmid = (gl + gr) / 2;\n        int leftSize = 0;\n        for (int i = gl; i < gmid; ++i) leftSize += G[i];\n        \n        if (depth % 2 == 0) sort(ids.begin(), ids.end(), [&](int a, int b) { return cx[a] < cx[b]; });\n        else sort(ids.begin(), ids.end(), [&](int a, int b) { return cy[a] < cy[b]; });\n        \n        vector<int> left(ids.begin(), ids.begin() + leftSize);\n        vector<int> right(ids.begin() + leftSize, ids.end());\n        partition(left, gl, gmid, depth + 1);\n        partition(right, gmid, gr, depth + 1);\n    };\n    \n    vector<int> allIds(N);\n    iota(allIds.begin(), allIds.end(), 0);\n    partition(allIds, 0, M, 0);\n    \n    vector<int> groupOf(N, -1);\n    for (int i = 0; i < M; ++i) for (int v : groups[i]) groupOf[v] = i;\n    \n    // Collect edges\n    set<pair<int, int>> edgeSet;\n    vector<tuple<long long, int, int>> edges; // (estDist^2, u, v)\n    \n    auto addEdge = [&](int u, int v) {\n        if (u > v) swap(u, v);\n        if (edgeSet.count({u, v})) return;\n        edgeSet.insert({u, v});\n        long long dx = cx[u] - cx[v];\n        long long dy = cy[u] - cy[v];\n        edges.push_back({dx*dx + dy*dy, u, v});\n    };\n    \n    int queriesUsed = 0;\n    \n    // Phase 1: Sliding window backbone (ensures connectivity)\n    for (int gi = 0; gi < M && queriesUsed < Q; ++gi) {\n        auto &grp = groups[gi];\n        int gsize = grp.size();\n        if (gsize <= 1) continue;\n        \n        sort(grp.begin(), grp.end(), [&](int a, int b) {\n            return hilbertOrder(cx[a], cy[a]) < hilbertOrder(cx[b], cy[b]);\n        });\n        \n        for (int i = 0; i < gsize - 1 && queriesUsed < Q; i += L - 1) {\n            int batchSize = min(L, gsize - i);\n            cout << \"? \" << batchSize;\n            for (int j = 0; j < batchSize; ++j) cout << ' ' << grp[i + j];\n            cout << '\\n';\n            cout.flush();\n            ++queriesUsed;\n            \n            for (int j = 0; j < batchSize - 1; ++j) {\n                int a, b; cin >> a >> b;\n                addEdge(a, b);\n            }\n        }\n    }\n    \n    // Phase 2: Fill gaps with local anchor queries\n    // Find cities that appear in few edges\n    vector<int> edgeCount(N, 0);\n    for (auto& [d, u, v] : edges) {\n        edgeCount[u]++;\n        edgeCount[v]++;\n    }\n    \n    // Priority: cities with few edges\n    vector<pair<int, int>> priority; // (edgeCount, city)\n    for (int i = 0; i < N; ++i) priority.push_back({edgeCount[i], i});\n    sort(priority.begin(), priority.end());\n    \n    for (auto& [ecnt, v] : priority) {\n        if (queriesUsed >= Q) break;\n        if (ecnt >= 2) continue; // Already well connected\n        \n        int gi = groupOf[v];\n        if (gi < 0 || groups[gi].size() <= 1) continue;\n        \n        // Query v with its nearest neighbors\n        vector<pair<long long, int>> dists;\n        for (int u : groups[gi]) {\n            if (u == v) continue;\n            long long dx = cx[v] - cx[u];\n            long long dy = cy[v] - cy[u];\n            dists.push_back({dx*dx + dy*dy, u});\n        }\n        if (dists.empty()) continue;\n        \n        sort(dists.begin(), dists.end());\n        int k = min(L - 1, (int)dists.size());\n        \n        vector<int> querySet = {v};\n        for (int i = 0; i < k; ++i) querySet.push_back(dists[i].second);\n        \n        cout << \"? \" << (int)querySet.size();\n        for (int x : querySet) cout << ' ' << x;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < (int)querySet.size() - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Phase 3: Random local sampling with remaining queries\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    while (queriesUsed < Q) {\n        vector<int> weights;\n        for (int i = 0; i < M; ++i) weights.push_back(groups[i].size());\n        discrete_distribution<int> dist(weights.begin(), weights.end());\n        int gi = dist(rng);\n        \n        if (groups[gi].size() < 2) continue;\n        \n        int anchor = groups[gi][rng() % groups[gi].size()];\n        \n        vector<pair<long long, int>> dists;\n        for (int u : groups[gi]) {\n            if (u == anchor) continue;\n            long long dx = cx[anchor] - cx[u];\n            long long dy = cy[anchor] - cy[u];\n            dists.push_back({dx*dx + dy*dy, u});\n        }\n        if (dists.empty()) continue;\n        \n        sort(dists.begin(), dists.end());\n        int k = min(L - 1, (int)dists.size());\n        \n        vector<int> querySet = {anchor};\n        for (int i = 0; i < k; ++i) querySet.push_back(dists[i].second);\n        \n        cout << \"? \" << (int)querySet.size();\n        for (int x : querySet) cout << ' ' << x;\n        cout << '\\n';\n        cout.flush();\n        ++queriesUsed;\n        \n        for (int i = 0; i < (int)querySet.size() - 1; ++i) {\n            int a, b; cin >> a >> b;\n            addEdge(a, b);\n        }\n    }\n    \n    // Build MST\n    sort(edges.begin(), edges.end());\n    DSU dsu(N);\n    vector<vector<pair<int,int>>> groupEdges(M);\n    \n    for (auto& [d, u, v] : edges) {\n        if (dsu.unite(u, v)) {\n            groupEdges[groupOf[u]].push_back({u, v});\n        }\n    }\n    \n    // Output\n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; ++gi) {\n        for (int i = 0; i < (int)groups[gi].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[gi][i];\n        }\n        cout << '\\n';\n        for (auto& [a, b] : groupEdges[gi]) {\n            cout << a << ' ' << b << '\\n';\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.emplace_back(r, c);\n    }\n    \n    vector<pair<char,char>> ans;\n    auto add_move = [&](char d, int cnt) {\n        for (int i = 0; i < cnt; i++) ans.emplace_back('M', d);\n    };\n    auto add_slide = [&](char d) {\n        ans.emplace_back('S', d);\n    };\n    \n    int cr = r0, cc = c0;\n    const int MAXC = N - 1; // 19\n    \n    for (auto [tr, tc] : targets) {\n        int dr = tr - cr;\n        int dc = tc - cc;\n        int abs_dr = abs(dr);\n        int abs_dc = abs(dc);\n        \n        // Direct Manhattan\n        int best_cost = abs_dr + abs_dc;\n        int strategy = 0; // 0=direct, 1=top, 2=bot, 3=left, 4=right, 5=corner\n        \n        // Via Top: slide up to row 0, walk horiz, walk down to tr\n        int cost_top = 1 + abs_dc + tr;\n        if (cost_top < best_cost) {\n            best_cost = cost_top;\n            strategy = 1;\n        }\n        \n        // Via Bottom: slide down to row 19, walk horiz, walk up to tr\n        int cost_bot = 1 + abs_dc + (MAXC - tr);\n        if (cost_bot < best_cost) {\n            best_cost = cost_bot;\n            strategy = 2;\n        }\n        \n        // Via Left: slide left to col 0, walk vert, walk right to tc\n        int cost_left = 1 + abs_dr + tc;\n        if (cost_left < best_cost) {\n            best_cost = cost_left;\n            strategy = 3;\n        }\n        \n        // Via Right: slide right to col 19, walk vert, walk left to tc\n        int cost_right = 1 + abs_dr + (MAXC - tc);\n        if (cost_right < best_cost) {\n            best_cost = cost_right;\n            strategy = 4;\n        }\n        \n        // Via Corner: 2 slides to a corner, then walk\n        int dist_from_corner = min(tr, MAXC - tr) + min(tc, MAXC - tc);\n        int cost_corner = 2 + dist_from_corner;\n        if (cost_corner < best_cost) {\n            best_cost = cost_corner;\n            strategy = 5;\n        }\n        \n        if (strategy == 0) {\n            // Direct: move vertical then horizontal (order doesn't matter)\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n        } else if (strategy == 1) {\n            // Via top\n            add_slide('U');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('D', tr); // down from row 0 to tr\n        } else if (strategy == 2) {\n            // Via bottom\n            add_slide('D');\n            if (dc > 0) add_move('R', dc);\n            else if (dc < 0) add_move('L', -dc);\n            add_move('U', MAXC - tr); // up from row 19 to tr\n        } else if (strategy == 3) {\n            // Via left\n            add_slide('L');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('R', tc); // right from col 0 to tc\n        } else if (strategy == 4) {\n            // Via right\n            add_slide('R');\n            if (dr > 0) add_move('D', dr);\n            else if (dr < 0) add_move('U', -dr);\n            add_move('L', MAXC - tc); // left from col 19 to tc\n        } else if (strategy == 5) {\n            // Via best corner\n            // Determine which corner is best (gives min walking distance)\n            int best_corner = 0; // 0:TL, 1:TR, 2:BL, 3:BR\n            int best_corner_cost = 1000;\n            // TL (0,0): walk down tr, right tc. Cost: tr + tc\n            if (tr + tc < best_corner_cost) { best_corner_cost = tr + tc; best_corner = 0; }\n            // TR (0,19): down tr, left (19-tc)\n            if (tr + (MAXC - tc) < best_corner_cost) { best_corner_cost = tr + (MAXC - tc); best_corner = 1; }\n            // BL (19,0): up (19-tr), right tc\n            if ((MAXC - tr) + tc < best_corner_cost) { best_corner_cost = (MAXC - tr) + tc; best_corner = 2; }\n            // BR (19,19): up (19-tr), left (19-tc)\n            if ((MAXC - tr) + (MAXC - tc) < best_corner_cost) { best_corner_cost = (MAXC - tr) + (MAXC - tc); best_corner = 3; }\n            \n            if (best_corner == 0) {\n                add_slide('U');\n                add_slide('L');\n                add_move('D', tr);\n                add_move('R', tc);\n            } else if (best_corner == 1) {\n                add_slide('U');\n                add_slide('R');\n                add_move('D', tr);\n                add_move('L', MAXC - tc);\n            } else if (best_corner == 2) {\n                add_slide('D');\n                add_slide('L');\n                add_move('U', MAXC - tr);\n                add_move('R', tc);\n            } else {\n                add_slide('D');\n                add_slide('R');\n                add_move('U', MAXC - tr);\n                add_move('L', MAXC - tc);\n            }\n        }\n        \n        cr = tr;\n        cc = tc;\n    }\n    \n    for (auto [a, d] : ans) {\n        cout << a << ' ' << d << \"\\n\";\n    }\n    \n    return 0;\n}"}}}