{"model_name":"mimo-v2.5","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r, idx;\n};\n\nint main() {\n    int n;\n    cin >> n;\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].idx = i;\n    }\n\n    // sort by x coordinate\n    sort(companies.begin(), companies.end(),\n         [](const Company& a, const Company& b) { return a.x < b.x; });\n\n    // extract sorted data\n    vector<int> xs(n), ys(n), rs(n);\n    for (int i = 0; i < n; ++i) {\n        xs[i] = companies[i].x;\n        ys[i] = companies[i].y;\n        rs[i] = companies[i].r;\n    }\n\n    // precompute satisfaction for each possible width (1..10000) for each company\n    vector<vector<double>> sat(n, vector<double>(10001, 0.0));\n    for (int i = 0; i < n; ++i) {\n        long long r = rs[i];\n        for (int w = 1; w <= 10000; ++w) {\n            // height = round(r / w) clamped to [1, 10000]\n            long long h = (r + w / 2) / w;  // integer rounding\n            if (h > 10000) h = 10000;\n            if (h < 1) h = 1;\n            long long s = w * h;\n            double ratio = min(r, s) / (double)max(r, s);\n            sat[i][w] = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        }\n    }\n\n    // initial widths: must cover xi and be at least ceil(r/10000)\n    vector<int> w(n);\n    long long cur_start = 0;\n    for (int i = 0; i < n; ++i) {\n        long long w_min_cov = max(1LL, (long long)xs[i] - cur_start + 1);\n        long long w_min_area = (rs[i] + 9999) / 10000; // ceil(r/10000)\n        w[i] = max(w_min_cov, w_min_area);\n        cur_start += w[i];\n    }\n\n    long long total_width = cur_start;\n    long long excess = total_width - 10000;\n\n    // reduce widths if total exceeds 10000\n    while (excess > 0) {\n        // recompute current starts\n        vector<long long> start_pos(n);\n        cur_start = 0;\n        for (int i = 0; i < n; ++i) {\n            start_pos[i] = cur_start;\n            cur_start += w[i];\n        }\n\n        int best_i = -1;\n        double best_loss = 1e18;\n        for (int i = 0; i < n; ++i) {\n            long long w_min_cov = max(1LL, (long long)xs[i] - start_pos[i] + 1);\n            if (w[i] <= w_min_cov) continue; // cannot reduce without losing point\n            double p_curr = sat[i][w[i]];\n            double p_red = sat[i][w[i] - 1];\n            double loss = p_curr - p_red;\n            if (loss < best_loss) {\n                best_loss = loss;\n                best_i = i;\n            }\n        }\n        if (best_i == -1) break; // no reduction possible\n        w[best_i]--;\n        excess--;\n    }\n\n    // compute final heights and output rectangles\n    vector<int> a(n), b(n), c(n), d(n);\n    cur_start = 0;\n    for (int i = 0; i < n; ++i) {\n        int wi = w[i];\n        long long h = (rs[i] + wi / 2) / wi;\n        if (h > 10000) h = 10000;\n        if (h < 1) h = 1;\n        int ai = cur_start;\n        int ci = ai + wi;\n        int bi = max(0, ys[i] - (int)h + 1);\n        int di = bi + (int)h;\n\n        // store in original order\n        int idx = companies[i].idx;\n        a[idx] = ai;\n        b[idx] = bi;\n        c[idx] = ci;\n        d[idx] = di;\n\n        cur_start += wi;\n    }\n\n    // output\n    for (int i = 0; i < n; ++i) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <random>\n#include <tuple>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> tile(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tile[i][j];\n        }\n    }\n\n    vector<vector<int>> value(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> value[i][j];\n        }\n    }\n\n    // Find total number of tiles (M)\n    int M = 0;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            M = max(M, tile[i][j] + 1);\n        }\n    }\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n    // Timestamp technique to avoid resetting visited array each trial\n    vector<int> visited_tiles(M, 0);\n    int cur_timestamp = 0;\n\n    random_device rd;\n    mt19937 gen(rd());\n\n    string best_path = \"\";\n    int best_score = -1;\n\n    const int num_trials = 20000; // will be plus one greedy trial\n    for (int trial = 0; trial <= num_trials; ++trial) {\n        ++cur_timestamp;\n        int policy; // 0: uniform random, 1: weighted random, 2: greedy\n        if (trial == num_trials) {\n            policy = 2; // greedy at the end\n        } else {\n            policy = (gen() % 2); // 50% uniform, 50% weighted\n        }\n\n        int cur_r = si, cur_c = sj;\n        visited_tiles[tile[cur_r][cur_c]] = cur_timestamp;\n        int score = value[cur_r][cur_c];\n        string path = \"\";\n\n        while (true) {\n            // Collect unvisited neighbors\n            vector<tuple<int, int, int, char>> candidates; // value, nr, nc, tid, dir\n            for (int d = 0; d < 4; ++d) {\n                int nr = cur_r + dr[d];\n                int nc = cur_c + dc[d];\n                if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n                int tid = tile[nr][nc];\n                if (visited_tiles[tid] == cur_timestamp) continue;\n                candidates.emplace_back(value[nr][nc], nr, nc, tid, dir_char[d]);\n            }\n            if (candidates.empty()) break;\n\n            int chosen_idx = 0;\n            if (policy == 2) {\n                // Greedy: choose the candidate with maximum value\n                for (int i = 1; i < (int)candidates.size(); ++i) {\n                    if (get<0>(candidates[i]) > get<0>(candidates[chosen_idx])) {\n                        chosen_idx = i;\n                    }\n                }\n            } else {\n                if (policy == 0) {\n                    // Uniform random\n                    chosen_idx = gen() % candidates.size();\n                } else {\n                    // Weighted random (weights = value)\n                    int total = 0;\n                    for (const auto& cand : candidates) {\n                        total += get<0>(cand);\n                    }\n                    if (total == 0) {\n                        chosen_idx = gen() % candidates.size();\n                    } else {\n                        int r = gen() % total;\n                        int cum = 0;\n                        for (int i = 0; i < (int)candidates.size(); ++i) {\n                            cum += get<0>(candidates[i]);\n                            if (cum > r) {\n                                chosen_idx = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Execute the chosen move\n            auto [val, nr, nc, tid, dir] = candidates[chosen_idx];\n            path += dir;\n            cur_r = nr;\n            cur_c = nc;\n            visited_tiles[tid] = cur_timestamp;\n            score += val;\n        }\n\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n        }\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    const int N = 30;\n    vector<vector<double>> est_h(N, vector<double>(N-1, 5000.0)); // horizontal edges\n    vector<vector<double>> est_v(N-1, vector<double>(N, 5000.0)); // vertical edges\n\n    double lr = 0.1;                     // learning rate\n    int total_updates = 0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        int start = si * N + sj;\n        int target = ti * N + tj;\n\n        // ---------- Dijkstra ----------\n        const double INF = 1e18;\n        vector<double> dist(N * N, INF);\n        vector<int> prev(N * N, -1);\n        vector<char> prev_move(N * N); // direction that led to this node\n\n        dist[start] = 0.0;\n        priority_queue<pair<double, int>,\n                       vector<pair<double, int>>,\n                       greater<pair<double, int>>> pq;\n        pq.emplace(0.0, start);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            int ui = u / N, uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = (ui - 1) * N + uj;\n                double w = est_v[ui - 1][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'U';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // down\n            if (ui < N - 1) {\n                int v = (ui + 1) * N + uj;\n                double w = est_v[ui][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'D';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = ui * N + (uj - 1);\n                double w = est_h[ui][uj - 1];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'L';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // right\n            if (uj < N - 1) {\n                int v = ui * N + (uj + 1);\n                double w = est_h[ui][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'R';\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        // ---------- Reconstruct path ----------\n        vector<char> moves;\n        struct Edge { bool hor; int i; int j; };\n        vector<Edge> path_edges;\n\n        int cur = target;\n        while (cur != start) {\n            int p = prev[cur];\n            char dir = prev_move[cur];\n            moves.push_back(dir);\n\n            int pi = p / N, pj = p % N;\n            int ci = cur / N, cj = cur % N;\n\n            if (pi == ci) { // horizontal move\n                int j = min(pj, cj);\n                path_edges.push_back({true, pi, j});\n            } else { // vertical move\n                int i = min(pi, ci);\n                path_edges.push_back({false, i, pj});\n            }\n            cur = p;\n        }\n        reverse(moves.begin(), moves.end());\n        reverse(path_edges.begin(), path_edges.end());\n\n        // ---------- Output ----------\n        for (char c : moves) cout << c;\n        cout << endl;\n\n        // ---------- Read feedback ----------\n        int res;\n        cin >> res;\n\n        // ---------- Compute predicted length ----------\n        double L_est = 0.0;\n        for (auto& e : path_edges) {\n            if (e.hor) L_est += est_h[e.i][e.j];\n            else       L_est += est_v[e.i][e.j];\n        }\n        int len = path_edges.size();\n        double delta = lr * (res - L_est) / len;\n\n        // ---------- Update estimates ----------\n        for (auto& e : path_edges) {\n            if (e.hor) {\n                est_h[e.i][e.j] += delta;\n                est_h[e.i][e.j] = max(1000.0, min(9000.0, est_h[e.i][e.j]));\n            } else {\n                est_v[e.i][e.j] += delta;\n                est_v[e.i][e.j] = max(1000.0, min(9000.0, est_v[e.i][e.j]));\n            }\n        }\n\n        total_updates += len;\n        lr *= 0.999;   // decay learning rate\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int BASE = 131;\n\nstruct SubInfo {\n    int start;\n    int k;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n    \n    // Hash each string\n    auto compute_hash_string = [](const string &s) -> uint64_t {\n        uint64_t h = 0;\n        for (char ch : s) {\n            h = h * BASE + (ch - 'A' + 1);\n        }\n        return h;\n    };\n    vector<uint64_t> str_hash(M);\n    unordered_map<uint64_t, int> hash_to_str;\n    for (int i = 0; i < M; ++i) {\n        str_hash[i] = compute_hash_string(strs[i]);\n        hash_to_str[str_hash[i]] = i;\n    }\n    \n    // Precompute for each cell the list of row/column substrings that contain it\n    vector<vector<SubInfo>> cell_row_info(N * N);\n    vector<vector<SubInfo>> cell_col_info(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cell = r * N + c;\n            for (int k = 2; k <= 12; ++k) {\n                // row substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (c >= s && c < s + k) in = true;\n                    } else {\n                        if (c >= s || c < (s + k) % N) in = true;\n                    }\n                    if (in) cell_row_info[cell].push_back({s, k});\n                }\n                // column substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (r >= s && r < s + k) in = true;\n                    } else {\n                        if (r >= s || r < (s + k) % N) in = true;\n                    }\n                    if (in) cell_col_info[cell].push_back({s, k});\n                }\n            }\n        }\n    }\n    \n    // Initialize random grid\n    vector<vector<char>> grid(N, vector<char>(N));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_letter(0, 7);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + dist_letter(rng);\n        }\n    }\n    \n    // Helper functions for row/column hash using the current grid\n    auto compute_hash_row = [&](int r, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int col = (start + i) % N;\n            h = h * BASE + (grid[r][col] - 'A' + 1);\n        }\n        return h;\n    };\n    auto compute_hash_col = [&](int c, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int row = (start + i) % N;\n            h = h * BASE + (grid[row][c] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    // Initialize count map for all substring hashes\n    unordered_map<uint64_t, int> cnt;\n    for (int r = 0; r < N; ++r) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_row(r, s, k)]++;\n            }\n        }\n    }\n    for (int c = 0; c < N; ++c) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_col(c, s, k)]++;\n            }\n        }\n    }\n    \n    // Initial satisfaction\n    vector<bool> satisfied(M, false);\n    int c_sat = 0;\n    for (int i = 0; i < M; ++i) {\n        if (cnt[str_hash[i]] > 0) {\n            satisfied[i] = true;\n            ++c_sat;\n        }\n    }\n    \n    // Simulated annealing parameters\n    const int iterations = 200000;\n    double temp = 10.0;\n    const double cooling = 0.99995;\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    uniform_int_distribution<int> dist_cell(0, N - 1);\n    uniform_int_distribution<int> dist_newchar(0, 7);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int r = dist_cell(rng);\n        int col = dist_cell(rng);\n        int cell = r * N + col;\n        char old_char = grid[r][col];\n        char new_char = 'A' + dist_newchar(rng);\n        if (new_char == old_char) continue;\n        \n        // Collect old hashes for row and column substrings through this cell\n        vector<uint64_t> old_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            old_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            old_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        \n        // Temporarily change the cell to compute new hashes\n        grid[r][col] = new_char;\n        vector<uint64_t> new_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            new_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            new_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        grid[r][col] = old_char;  // revert\n        \n        // Compute net changes in hash counts\n        unordered_map<uint64_t, int> delta_count;\n        for (size_t i = 0; i < old_hashes.size(); ++i) {\n            if (old_hashes[i] != new_hashes[i]) {\n                delta_count[old_hashes[i]]--;\n                delta_count[new_hashes[i]]++;\n            }\n        }\n        \n        // Estimate change in number of satisfied strings\n        int delta_c = 0;\n        for (auto &[hash, d] : delta_count) {\n            int old_cnt = cnt[hash];\n            int new_cnt = old_cnt + d;\n            if (old_cnt == 0 && new_cnt > 0) delta_c++;\n            if (old_cnt > 0 && new_cnt == 0) delta_c--;\n        }\n        \n        // Acceptance probability\n        bool accept = false;\n        if (delta_c > 0) {\n            accept = true;\n        } else if (temp > 1e-6) {\n            double prob = exp(delta_c / temp);\n            if (prob > dist_real(rng)) accept = true;\n        }\n        \n        if (accept) {\n            grid[r][col] = new_char;\n            for (auto &[hash, d] : delta_count) {\n                int old_cnt = cnt[hash];\n                cnt[hash] = old_cnt + d;\n                if (old_cnt == 0 && cnt[hash] > 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = true;\n                        ++c_sat;\n                    }\n                }\n                if (old_cnt > 0 && cnt[hash] == 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = false;\n                        --c_sat;\n                    }\n                }\n            }\n        }\n        \n        temp *= cooling;\n        if (c_sat == M) break;  // early exit if all satisfied\n    }\n    \n    // Output the matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n};\n\n// Hopcroft\u2013Karp for bipartite matching\nint hopcroft_karp(const vector<vector<int>>& adj, int L, int R,\n                  vector<int>& matchL, vector<int>& matchR) {\n    vector<int> dist(L, -1);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            dist[u] = 0;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (matchR[v] != -1 && dist[matchR[v]] == -1) {\n                dist[matchR[v]] = dist[u] + 1;\n                q.push(matchR[v]);\n            }\n        }\n    }\n    function<bool(int)> dfs = [&](int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 ||\n                (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n    int matching = 0;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1 && dfs(u)) ++matching;\n    }\n    return matching;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; ++i) cin >> grid_str[i];\n\n    // Convert grid: -1 for obstacle, otherwise cost (5-9)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Point> roads;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid_str[i][j];\n            if (c != '#') {\n                grid[i][j] = c - '0';\n                roads.push_back({i, j});\n            }\n        }\n    }\n\n    // ---------- row segments ----------\n    vector<vector<int>> row_seg(N, vector<int>(N, -1));\n    int L = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != -1) {\n                int start = j;\n                while (j < N && grid[i][j] != -1) ++j;\n                int end = j - 1;\n                for (int k = start; k <= end; ++k) row_seg[i][k] = L;\n                ++L;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ---------- column segments ----------\n    vector<vector<int>> col_seg(N, vector<int>(N, -1));\n    int R = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != -1) {\n                int start = i;\n                while (i < N && grid[i][j] != -1) ++i;\n                int end = i - 1;\n                for (int k = start; k <= end; ++k) col_seg[k][j] = R;\n                ++R;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ---------- bipartite graph (row segments vs column segments) ----------\n    vector<vector<int>> adj(L);\n    vector<vector<pair<int, int>>> edge_coord(L); // for each row segment: (col_segment, (i,j))\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        adj[u].push_back(v);\n        edge_coord[u].push_back({v, {p.i, p.j}});\n    }\n\n    // ---------- minimum vertex cover (via maximum matching) ----------\n    vector<int> matchL(L, -1), matchR(R, -1);\n    hopcroft_karp(adj, L, R, matchL, matchR);\n\n    vector<bool> visL(L, false), visR(R, false);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            visL[u] = true;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (!visR[v]) {\n                visR[v] = true;\n                if (matchR[v] != -1 && !visL[matchR[v]]) {\n                    visL[matchR[v]] = true;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n    }\n    vector<bool> selected_row(L, false), selected_col(R, false);\n    for (int u = 0; u < L; ++u) selected_row[u] = !visL[u];\n    for (int v = 0; v < R; ++v) selected_col[v] = visR[v];\n\n    // ---------- selected segments ----------\n    vector<int> sel_row_list, sel_col_list;\n    for (int u = 0; u < L; ++u) if (selected_row[u]) sel_row_list.push_back(u);\n    for (int v = 0; v < R; ++v) if (selected_col[v]) sel_col_list.push_back(v);\n    int L2 = sel_row_list.size(), R2 = sel_col_list.size();\n    map<int, int> row_idx, col_idx;\n    for (int i = 0; i < L2; ++i) row_idx[sel_row_list[i]] = i;\n    for (int i = 0; i < R2; ++i) col_idx[sel_col_list[i]] = i;\n\n    // ---------- induced graph on selected segments ----------\n    vector<vector<int>> adj2(L2);\n    vector<vector<int>> radj2(R2);\n    vector<vector<pair<int, int>>> edge_coord2(L2); // (col_idx, (i,j))\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        if (selected_row[u] && selected_col[v]) {\n            int u2 = row_idx[u];\n            int v2 = col_idx[v];\n            adj2[u2].push_back(v2);\n            radj2[v2].push_back(u2);\n            edge_coord2[u2].push_back({v2, {p.i, p.j}});\n        }\n    }\n\n    // ---------- minimum edge cover on induced graph ----------\n    vector<int> matchL2(L2, -1), matchR2(R2, -1);\n    hopcroft_karp(adj2, L2, R2, matchL2, matchR2);\n\n    vector<Point> S; // squares to visit\n    vector<bool> row_covered(L2, false), col_covered(R2, false);\n\n    // 1. take all matching edges\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (matchL2[u2] != -1) {\n            int v2 = matchL2[u2];\n            for (auto& e : edge_coord2[u2]) {\n                if (e.first == v2) {\n                    S.push_back({e.second.first, e.second.second});\n                    break;\n                }\n            }\n            row_covered[u2] = true;\n            col_covered[v2] = true;\n        }\n    }\n\n    // 2. cover unmatched rows\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (!row_covered[u2]) {\n            if (!adj2[u2].empty()) {\n                int v2 = adj2[u2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back({e.second.first, e.second.second});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n                col_covered[v2] = true;\n            } else { // isolated row segment\n                int u_orig = sel_row_list[u2];\n                for (auto& p : roads) {\n                    if (row_seg[p.i][p.j] == u_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n            }\n        }\n    }\n\n    // 3. cover unmatched columns\n    for (int v2 = 0; v2 < R2; ++v2) {\n        if (!col_covered[v2]) {\n            if (!radj2[v2].empty()) {\n                int u2 = radj2[v2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back({e.second.first, e.second.second});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            } else { // isolated column segment\n                int v_orig = sel_col_list[v2];\n                for (auto& p : roads) {\n                    if (col_seg[p.i][p.j] == v_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            }\n        }\n    }\n\n    // ---------- nodes for TSP (start + S without duplicates) ----------\n    vector<Point> nodes;\n    nodes.push_back({si, sj});\n    set<pair<int, int>> visited_set;\n    for (auto& p : S) {\n        if (p.i == si && p.j == sj) continue;\n        if (visited_set.insert({p.i, p.j}).second) {\n            nodes.push_back(p);\n        }\n    }\n    int n = nodes.size();\n\n    // ---------- Dijkstra from each node, build distance matrix and predecessors ----------\n    const int INF = 1e9;\n    vector<vector<int>> dist_mat(n, vector<int>(n, INF));\n    vector<vector<vector<char>>> pred(n, vector<vector<char>>(N, vector<char>(N, 0)));\n\n    auto dijkstra = [&](int src_idx) {\n        int si = nodes[src_idx].i, sj = nodes[src_idx].j;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        dist[si][sj] = 0;\n        pred[src_idx][si][sj] = 0; // 0 marks the source\n        priority_queue<pair<int, pair<int, int>>,\n                       vector<pair<int, pair<int, int>>>,\n                       greater<>> pq;\n        pq.push({0, {si, sj}});\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dir[4] = {'U', 'D', 'L', 'R'};\n        while (!pq.empty()) {\n            auto [d, pos] = pq.top(); pq.pop();\n            int i = pos.first, j = pos.second;\n            if (d != dist[i][j]) continue;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid[ni][nj] == -1) continue;\n                int nd = d + grid[ni][nj];\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    pred[src_idx][ni][nj] = dir[k];\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n        for (int t = 0; t < n; ++t) {\n            int ti = nodes[t].i, tj = nodes[t].j;\n            dist_mat[src_idx][t] = dist[ti][tj];\n        }\n    };\n    for (int s = 0; s < n; ++s) dijkstra(s);\n\n    // ---------- TSP heuristic (nearest neighbour + 2\u2011opt) ----------\n    vector<int> tour;\n    vector<bool> vis(n, false);\n    tour.push_back(0); // start at index 0\n    vis[0] = true;\n    int cur = 0;\n    for (int iter = 0; iter < n - 1; ++iter) {\n        int nxt = -1, best = INF;\n        for (int v = 0; v < n; ++v) {\n            if (!vis[v] && dist_mat[cur][v] < best) {\n                best = dist_mat[cur][v];\n                nxt = v;\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = true;\n        cur = nxt;\n    }\n    tour.push_back(0); // return to start\n\n    // 2\u2011opt\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 0; i < sz - 2; ++i) {\n            for (int j = i + 2; j < sz - 1; ++j) {\n                int a = tour[i], b = tour[i+1], c = tour[j], d = tour[j+1];\n                int cur_cost = dist_mat[a][b] + dist_mat[c][d];\n                // cost of original segment b->...->c\n                int seg_orig = 0;\n                for (int k = i+1; k < j; ++k) seg_orig += dist_mat[tour[k]][tour[k+1]];\n                // new cost if we reverse segment i+1..j\n                int new_cost = dist_mat[a][c] + dist_mat[b][d];\n                int seg_rev = 0;\n                for (int k = j; k > i+1; --k) seg_rev += dist_mat[tour[k]][tour[k-1]];\n                if (cur_cost + seg_orig > new_cost + seg_rev) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // ---------- build move string ----------\n    string moves;\n    for (int idx = 0; idx < (int)tour.size() - 1; ++idx) {\n        int src_idx = tour[idx];\n        int tgt_idx = tour[idx+1];\n        int ci = nodes[tgt_idx].i, cj = nodes[tgt_idx].j;\n        vector<char> path;\n        while (!(ci == nodes[src_idx].i && cj == nodes[src_idx].j)) {\n            char d = pred[src_idx][ci][cj];\n            path.push_back(d);\n            // move to parent\n            if (d == 'U') ci++;\n            else if (d == 'D') ci--;\n            else if (d == 'L') cj++;\n            else if (d == 'R') cj--;\n        }\n        reverse(path.begin(), path.end());\n        for (char c : path) moves.push_back(c);\n    }\n\n    cout << moves << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            cin >> d[i][k];\n        }\n    }\n\n    vector<vector<int>> children(N);\n    vector<int> prereq_count(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        prereq_count[v]++;\n    }\n\n    // Critical path length L[i]\n    vector<int> L(N, 1);\n    for (int i = N - 1; i >= 0; --i) {\n        for (int v : children[i]) {\n            L[i] = max(L[i], 1 + L[v]);\n        }\n    }\n\n    // Available tasks (prerequisites satisfied)\n    vector<int> avail;\n    for (int i = 0; i < N; ++i) {\n        if (prereq_count[i] == 0) {\n            avail.push_back(i);\n        }\n    }\n\n    // Task status: 0=not started, 1=started, 2=completed\n    vector<int> task_status(N, 0);\n\n    // Team member state\n    vector<int> current_task(M, -1);      // -1 if idle\n    vector<int> start_day(M, -1);\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));  // estimated skill levels\n\n    const double learning_rate = 0.01;\n\n    int cur_day = 1;\n\n    while (true) {\n        // Collect idle members\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // Collect currently available tasks (status 0)\n        vector<int> today_avail;\n        for (int i : avail) {\n            if (task_status[i] == 0) {\n                today_avail.push_back(i);\n            }\n        }\n\n        // Sort by critical path length descending\n        sort(today_avail.begin(), today_avail.end(),\n             [&](int a, int b) { return L[a] > L[b]; });\n\n        vector<pair<int, int>> assignments; // (member, task)\n        vector<bool> member_used(M, false);\n\n        for (int i : today_avail) {\n            if (idle_members.empty()) break;\n\n            int best_j = -1;\n            double best_w = 1e9;\n            for (int j : idle_members) {\n                if (member_used[j]) continue;\n                double w = 0.0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        w += d[i][k] - s_est[j][k];\n                    }\n                }\n                if (w < best_w) {\n                    best_w = w;\n                    best_j = j;\n                }\n            }\n            if (best_j != -1) {\n                assignments.emplace_back(best_j, i);\n                member_used[best_j] = true;\n                task_status[i] = 1; // mark as started\n            }\n        }\n\n        // Output assignments\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        // Read response line\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        istringstream iss(line);\n        int n;\n        iss >> n;\n        vector<int> completing;\n        for (int i = 0; i < n; ++i) {\n            int f;\n            iss >> f;\n            completing.push_back(f - 1); // to 0-index\n        }\n\n        // Process completions\n        for (int j : completing) {\n            int i = current_task[j];\n            if (i == -1) continue; // should not happen\n\n            int t = cur_day - start_day[j] + 1; // actual duration\n\n            // Update skill estimates for member j\n            double w_est = 0.0;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    w_est += d[i][k] - s_est[j][k];\n                }\n            }\n            double error = t - w_est;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    s_est[j][k] -= learning_rate * error;\n                    if (s_est[j][k] < 0.0) s_est[j][k] = 0.0;\n                }\n            }\n\n            // Mark task as completed\n            task_status[i] = 2;\n            current_task[j] = -1;\n\n            // Update dependent tasks\n            for (int v : children[i]) {\n                prereq_count[v]--;\n                if (prereq_count[v] == 0) {\n                    avail.push_back(v);\n                }\n            }\n        }\n\n        ++cur_day;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <cassert>\n\nusing namespace std;\n\nstruct Order {\n    int id; // 0-based index\n    int a, b, c, d;\n};\n\nvector<Order> orders;\n\n// Manhattan distance\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Compute total travel time for a given sequence of order indices\nint total_distance(const vector<int>& seq) {\n    int cur_x = 400, cur_y = 400;\n    int total = 0;\n    for (int idx : seq) {\n        total += dist(cur_x, cur_y, orders[idx].a, orders[idx].b);\n        total += dist(orders[idx].a, orders[idx].b, orders[idx].c, orders[idx].d);\n        cur_x = orders[idx].c;\n        cur_y = orders[idx].d;\n    }\n    total += dist(cur_x, cur_y, 400, 400);\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n\n    // Greedy construction of an initial sequence\n    vector<bool> used(1000, false);\n    vector<int> seq; // sequence of order indices (0-based)\n    int cur_x = 400, cur_y = 400;\n    for (int step = 0; step < 50; ++step) {\n        int best_idx = -1;\n        int best_cost = 1e9;\n        for (int i = 0; i < 1000; ++i) {\n            if (used[i]) continue;\n            int cost = dist(cur_x, cur_y, orders[i].a, orders[i].b) +\n                       dist(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n            }\n        }\n        assert(best_idx != -1);\n        seq.push_back(best_idx);\n        used[best_idx] = true;\n        cur_x = orders[best_idx].c;\n        cur_y = orders[best_idx].d;\n    }\n\n    int total = total_distance(seq);\n\n    // Local search: 2-opt on the order of orders\n    auto start_time = clock();\n    const double time_limit = 1.9 * CLOCKS_PER_SEC; // slightly less than 2 seconds\n\n    while (true) {\n        // Check time\n        if (clock() - start_time > time_limit) break;\n\n        // 2-opt phase\n        bool improved = true;\n        while (improved) {\n            if (clock() - start_time > time_limit) break;\n            improved = false;\n            for (int i = 0; i < seq.size(); ++i) {\n                for (int j = i + 1; j < seq.size(); ++j) {\n                    vector<int> new_seq = seq;\n                    reverse(new_seq.begin() + i, new_seq.begin() + j + 1);\n                    int new_total = total_distance(new_seq);\n                    if (new_total < total) {\n                        seq = new_seq;\n                        total = new_total;\n                        improved = true;\n                    }\n                }\n            }\n        }\n\n        // Order replacement phase\n        improved = true;\n        while (improved) {\n            if (clock() - start_time > time_limit) break;\n            improved = false;\n            for (int pos = 0; pos < seq.size(); ++pos) {\n                for (int i = 0; i < 1000; ++i) {\n                    if (used[i]) continue;\n                    vector<int> new_seq = seq;\n                    new_seq[pos] = i;\n                    int new_total = total_distance(new_seq);\n                    if (new_total < total) {\n                        used[seq[pos]] = false;\n                        used[i] = true;\n                        seq = new_seq;\n                        total = new_total;\n                        improved = true;\n                    }\n                }\n            }\n        }\n\n        // If no improvement in either phase, break\n        // (We could also add a counter to limit iterations)\n        // For simplicity, we break after one full cycle if time remains.\n        break; // optional: remove to allow more cycles\n    }\n\n    // Output the selected orders (1-based indices)\n    cout << 50;\n    for (int idx : seq) {\n        cout << ' ' << idx + 1;\n    }\n    cout << '\\n';\n\n    // Output the route: office, then for each order: restaurant, destination, then office\n    cout << 102; // 1 (start) + 50*2 + 1 (end) = 102\n    cout << \" 400 400\"; // starting office\n    for (int idx : seq) {\n        cout << ' ' << orders[idx].a << ' ' << orders[idx].b;\n        cout << ' ' << orders[idx].c << ' ' << orders[idx].d;\n    }\n    cout << \" 400 400\"; // return to office\n    cout << '\\n';\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, rank;\n    int components;\n    DSU(int n) : parent(n), rank(n, 0), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        components--;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        double dx = x[u[i]] - x[v[i]];\n        double dy = y[u[i]] - y[v[i]];\n        double dist = sqrt(dx * dx + dy * dy);\n        d[i] = (int)round(dist);\n    }\n\n    DSU dsu(N);\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (dsu.find(u[i]) == dsu.find(v[i])) {\n            cout << 0 << endl;\n        } else {\n            int K = dsu.components;\n            int rem = M - i;\n            if (rem <= 2 * K) {\n                cout << 1 << endl;\n                dsu.unite(u[i], v[i]);\n            } else {\n                if (l <= 2 * d[i]) {\n                    cout << 1 << endl;\n                    dsu.unite(u[i], v[i]);\n                } else {\n                    cout << 0 << endl;\n                }\n            }\n        }\n        cout.flush();\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 30;\nint N, M;\nint px[20], py[20], pt[20];\nint hx[10], hy[10];\nbool passable[31][31]; // 1-indexed\n\nbool pet_at[31][31];\nbool human_at[31][31];\nbool adj_to_pet[31][31]; // adjacent to at least one pet at start of turn\n\nbool blocked_this_turn[31][31]; // squares that will be blocked this turn (by humans)\n\nrandom_device rd;\nmt19937 rng(rd());\n\n// BFS function: returns component size and sets pet_count\nint bfs(int sx, int sy, int& pet_count, bool temp_blocked, int tbx, int tby) {\n    static bool visited[31][31];\n    memset(visited, 0, sizeof(visited));\n    queue<pair<int,int>> q;\n    if (passable[sx][sy] && !blocked_this_turn[sx][sy] && !(temp_blocked && sx==tbx && sy==tby)) {\n        q.push({sx, sy});\n        visited[sx][sy] = true;\n    }\n    int size = 0;\n    pet_count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        size++;\n        if (pet_at[x][y]) pet_count++;\n        for (int dx = -1; dx <= 1; dx++) {\n            for (int dy = -1; dy <= 1; dy++) {\n                if (abs(dx) + abs(dy) != 1) continue;\n                int nx = x + dx, ny = y + dy;\n                if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) continue;\n                if (!passable[nx][ny]) continue;\n                if (blocked_this_turn[nx][ny]) continue;\n                if (temp_blocked && nx==tbx && ny==tby) continue;\n                if (visited[nx][ny]) continue;\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return size;\n}\n\nint main() {\n    // Read input\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> px[i] >> py[i] >> pt[i];\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> hx[i] >> hy[i];\n    }\n\n    // Initialize passable grid\n    for (int i = 1; i <= MAXN; i++) {\n        for (int j = 1; j <= MAXN; j++) {\n            passable[i][j] = true;\n        }\n    }\n\n    // Loop for 300 turns\n    for (int turn = 0; turn < 300; turn++) {\n        // Precompute pet_at, human_at, adj_to_pet\n        memset(pet_at, 0, sizeof(pet_at));\n        for (int i = 0; i < N; i++) {\n            pet_at[px[i]][py[i]] = true;\n        }\n        memset(human_at, 0, sizeof(human_at));\n        for (int i = 0; i < M; i++) {\n            human_at[hx[i]][hy[i]] = true;\n        }\n        memset(adj_to_pet, 0, sizeof(adj_to_pet));\n        for (int i = 0; i < N; i++) {\n            int x = px[i], y = py[i];\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    if (abs(dx) + abs(dy) != 1) continue;\n                    int nx = x + dx, ny = y + dy;\n                    if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN) {\n                        adj_to_pet[nx][ny] = true;\n                    }\n                }\n            }\n        }\n\n        // Reset blocked_this_turn\n        memset(blocked_this_turn, 0, sizeof(blocked_this_turn));\n\n        // Random order for humans\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        string actions(M, '.'); // default action\n\n        for (int idx : order) {\n            int x = hx[idx], y = hy[idx];\n            double best_value = -1.0;\n            char best_action = '.';\n\n            // Helper lambda to evaluate an action\n            auto evaluate = [&](char action) -> double {\n                int nx = x, ny = y;\n                bool is_block = false;\n                bool is_move = false;\n                int tbx = -1, tby = -1;\n\n                if (action == '.') {\n                    // stay\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    // block\n                    is_block = true;\n                    if (action == 'u') { nx = x-1; ny = y; }\n                    else if (action == 'd') { nx = x+1; ny = y; }\n                    else if (action == 'l') { nx = x; ny = y-1; }\n                    else if (action == 'r') { nx = x; ny = y+1; }\n                    // Check legality for block\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1.0;\n                    if (!passable[nx][ny]) return -1.0;\n                    if (pet_at[nx][ny]) return -1.0;\n                    if (human_at[nx][ny]) return -1.0;\n                    if (adj_to_pet[nx][ny]) return -1.0;\n                    tbx = nx; tby = ny;\n                } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // move\n                    is_move = true;\n                    if (action == 'U') { nx = x-1; ny = y; }\n                    else if (action == 'D') { nx = x+1; ny = y; }\n                    else if (action == 'L') { nx = x; ny = y-1; }\n                    else if (action == 'R') { nx = x; ny = y+1; }\n                    // Check legality for move\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1.0;\n                    if (!passable[nx][ny]) return -1.0;\n                    if (blocked_this_turn[nx][ny]) return -1.0;\n                } else {\n                    return -1.0;\n                }\n\n                // Now compute component from the human's new position after action\n                int start_x = is_move ? nx : x;\n                int start_y = is_move ? ny : y;\n                int pet_count;\n                int comp_size = bfs(start_x, start_y, pet_count, is_block, tbx, tby);\n                double value = (comp_size / 900.0) * pow(2.0, -pet_count);\n                return value;\n            };\n\n            // Evaluate each possible action\n            vector<char> actions_list = {'.', 'u', 'd', 'l', 'r', 'U', 'D', 'L', 'R'};\n            for (char a : actions_list) {\n                double val = evaluate(a);\n                if (val > best_value) {\n                    best_value = val;\n                    best_action = a;\n                }\n            }\n\n            // If best_value is still -1 (no legal action), stay\n            if (best_value < 0) best_action = '.';\n\n            actions[idx] = best_action;\n\n            // If this human chose to block, add to blocked_this_turn\n            if (best_action == 'u' || best_action == 'd' || best_action == 'l' || best_action == 'r') {\n                int bx = x, by = y;\n                if (best_action == 'u') bx = x-1;\n                else if (best_action == 'd') bx = x+1;\n                else if (best_action == 'l') by = y-1;\n                else if (best_action == 'r') by = y+1;\n                blocked_this_turn[bx][by] = true;\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            // Apply movement\n            for (char c : s) {\n                if (c == 'U') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n                // else '.' do nothing\n            }\n        }\n\n        // Update passable grid based on blocks placed this turn\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'u' || a == 'd' || a == 'l' || a == 'r') {\n                int bx = hx[i], by = hy[i];\n                if (a == 'u') bx = hx[i]-1;\n                else if (a == 'd') bx = hx[i]+1;\n                else if (a == 'l') by = hy[i]-1;\n                else if (a == 'r') by = hy[i]+1;\n                passable[bx][by] = false;\n            }\n        }\n\n        // Update human positions based on moves\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') hx[i]--;\n            else if (a == 'D') hx[i]++;\n            else if (a == 'L') hy[i]--;\n            else if (a == 'R') hy[i]++;\n        }\n\n        // End of turn\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0:U, 1:D, 2:L, 3:R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Precompute next cell for each cell and direction\nvector<vector<vector<pair<int, int>>>> precompute_next(\n    const vector<vector<int>>& h,\n    const vector<vector<int>>& v) {\n    vector<vector<vector<pair<int, int>>>> next(4, vector<vector<pair<int, int>>>(20, vector<pair<int, int>>(20)));\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            // U\n            if (i > 0 && v[i-1][j] == 0)\n                next[0][i][j] = {i-1, j};\n            else\n                next[0][i][j] = {i, j};\n            // D\n            if (i < 19 && v[i][j] == 0)\n                next[1][i][j] = {i+1, j};\n            else\n                next[1][i][j] = {i, j};\n            // L\n            if (j > 0 && h[i][j-1] == 0)\n                next[2][i][j] = {i, j-1};\n            else\n                next[2][i][j] = {i, j};\n            // R\n            if (j < 19 && h[i][j] == 0)\n                next[3][i][j] = {i, j+1};\n            else\n                next[3][i][j] = {i, j};\n        }\n    }\n    return next;\n}\n\n// BFS to find a shortest path from start to target\nstring bfs_path(int si, int sj, int ti, int tj,\n                const vector<vector<int>>& h,\n                const vector<vector<int>>& v) {\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move(20, vector<char>(20, ' '));\n    queue<pair<int, int>> q;\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        // Try four directions\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            // Check walls\n            if (d == 0 && (i == 0 || v[i-1][j] == 1)) continue;\n            if (d == 1 && (i == 19 || v[i][j] == 1)) continue;\n            if (d == 2 && (j == 0 || h[i][j-1] == 1)) continue;\n            if (d == 3 && (j == 19 || h[i][j] == 1)) continue;\n            if (!visited[ni][nj]) {\n                visited[ni][nj] = true;\n                parent[ni][nj] = {i, j};\n                move[ni][nj] = dir_char[d];\n                q.emplace(ni, nj);\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path = \"\";\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        char m = move[i][j];\n        path += m;\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Simulate the stochastic process and compute expected score\ndouble simulate(const string& s,\n                const vector<vector<vector<pair<int, int>>>>& next,\n                int si, int sj, int ti, int tj, double p) {\n    vector<vector<double>> dist(20, vector<double>(20, 0.0));\n    dist[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int t = 1; t <= L; ++t) {\n        char c = s[t-1];\n        int d = -1;\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        vector<vector<double>> new_dist(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob = dist[i][j];\n                if (prob == 0.0) continue;\n                // With probability p, forget and stay\n                new_dist[i][j] += prob * p;\n                // With probability 1-p, try to move\n                auto [ni, nj] = next[d][i][j];\n                if (ni == ti && nj == tj) {\n                    score += prob * (1-p) * (401 - t);\n                } else {\n                    new_dist[ni][nj] += prob * (1-p);\n                }\n            }\n        }\n        dist = new_dist;\n    }\n    return score;\n}\n\n// Generate greedy nominal string (always try to move towards target)\nstring greedy_nominal(int si, int sj, int ti, int tj,\n                      const vector<vector<int>>& h,\n                      const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';  // arbitrary after reaching target\n            continue;\n        }\n        char best = 'R';\n        bool moved = false;\n        // Try right\n        if (cur_c < tj && h[cur_r][cur_c] == 0) {\n            best = 'R';\n            moved = true;\n        }\n        // Try down\n        if (!moved && cur_r < ti && v[cur_r][cur_c] == 0) {\n            best = 'D';\n            moved = true;\n        }\n        // Try left\n        if (!moved && cur_c > tj && (cur_c > 0 && h[cur_r][cur_c-1] == 0)) {\n            best = 'L';\n            moved = true;\n        }\n        // Try up\n        if (!moved && cur_r > ti && (cur_r > 0 && v[cur_r-1][cur_c] == 0)) {\n            best = 'U';\n            moved = true;\n        }\n        // If no move reduces Manhattan distance, try any possible move\n        if (!moved) {\n            if (cur_c < 19 && h[cur_r][cur_c] == 0) best = 'R';\n            else if (cur_r < 19 && v[cur_r][cur_c] == 0) best = 'D';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) best = 'L';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) best = 'U';\n            else best = 'R'; // should not happen\n        }\n        cand += best;\n        // Update nominal position\n        if (best == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (best == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (best == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n        else if (best == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n    }\n    return cand;\n}\n\n// Generate alternating direction string (prioritize down then right)\nstring alternating_string(int si, int sj, int ti, int tj,\n                          const vector<vector<int>>& h,\n                          const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char dir = 'D';\n        if (cur_r > ti) dir = 'U';\n        else if (cur_c < tj) dir = 'R';\n        else if (cur_c > tj) dir = 'L';\n        // else cur_r < ti already set to 'D'\n        bool possible = false;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) possible = true;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) possible = true;\n        if (!possible) {\n            // Try any possible direction\n            if (cur_r < 19 && v[cur_r][cur_c] == 0) dir = 'D';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) dir = 'U';\n            else if (cur_c < 19 && h[cur_r][cur_c] == 0) dir = 'R';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) dir = 'L';\n            else dir = 'R';\n        }\n        cand += dir;\n        // Update nominal position\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n    }\n    return cand;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    vector<vector<int>> h(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 19; ++j) {\n            h[i][j] = line[j] - '0';\n        }\n    }\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 20; ++j) {\n            v[i][j] = line[j] - '0';\n        }\n    }\n\n    // Precompute next cells\n    auto next_cell = precompute_next(h, v);\n\n    // Find a shortest path\n    string shortest_path = bfs_path(si, sj, ti, tj, h, v);\n    int k = shortest_path.size();\n\n    // Generate candidates\n    vector<string> candidates;\n\n    // 1. Shortest path itself\n    if (k > 0) {\n        candidates.push_back(shortest_path);\n    }\n\n    // 2. Repeat the whole path (padded to length 200)\n    if (k > 0) {\n        int t = 200 / k;\n        int rem = 200 % k;\n        string cand = \"\";\n        for (int i = 0; i < t; ++i) cand += shortest_path;\n        cand += shortest_path.substr(0, rem);\n        candidates.push_back(cand);\n    }\n\n    // 3. Repeat each move m times (m = floor(200/k))\n    if (k > 0) {\n        int m = 200 / k;\n        string cand = \"\";\n        for (char c : shortest_path) {\n            for (int i = 0; i < m; ++i) cand += c;\n        }\n        candidates.push_back(cand);\n    }\n\n    // 4. Greedy nominal moves\n    candidates.push_back(greedy_nominal(si, sj, ti, tj, h, v));\n\n    // 5. Alternating direction\n    candidates.push_back(alternating_string(si, sj, ti, tj, h, v));\n\n    // Evaluate each candidate and pick the best\n    double best_score = -1.0;\n    string best_str = \"\";\n    for (const string& cand : candidates) {\n        double score = simulate(cand, next_cell, si, sj, ti, tj, p);\n        if (score > best_score) {\n            best_score = score;\n            best_str = cand;\n        }\n    }\n\n    cout << best_str << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 30;\nconst int STEPS = 100000;\n\n// Tile connectivity table as provided in the problem hint\nconst int to[8][4] = {\n    {1, 0, -1, -1},    // tile 0\n    {3, -1, -1, 0},    // tile 1\n    {-1, -1, 3, 2},    // tile 2\n    {-1, 2, 1, -1},    // tile 3\n    {1, 0, 3, 2},      // tile 4\n    {3, 2, 1, 0},      // tile 5\n    {2, -1, 0, -1},    // tile 6\n    {-1, 3, -1, 1}     // tile 7\n};\n\n// Direction changes: left, up, right, down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Function to compute the length of a loop line starting from (i,j) with incoming direction d\nint compute_loop_length(const vector<string>& tiles, int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (true) {\n        // Get the current tile type\n        int t = tiles[i][j] - '0';\n        \n        // Determine outgoing direction\n        int d2 = to[t][d];\n        if (d2 == -1) return 0;\n        \n        // Move to next tile\n        i += di[d2];\n        j += dj[d2];\n        \n        // Check bounds\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        \n        // Reverse direction for incoming\n        d = (d2 + 2) % 4;\n        length++;\n        \n        // Check if we've returned to start\n        if (i == si && j == sj && d == sd) return length;\n        \n        // Prevent infinite loops with a reasonable limit\n        if (length > 4 * N * N) return 0;\n    }\n}\n\n// Compute all loop lengths in the current configuration\nvector<int> compute_all_loops(const vector<string>& tiles) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\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                if (visited[i][j][d]) continue;\n                \n                int length = compute_loop_length(tiles, i, j, d);\n                if (length > 0) {\n                    loops.push_back(length);\n                    // Mark all positions in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    do {\n                        visited[ci][cj][cd] = true;\n                        int t = tiles[ci][cj] - '0';\n                        int d2 = to[t][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    } while (ci != i || cj != j || cd != d);\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    return loops;\n}\n\n// Compute score from loop lengths\nlong long compute_score(const vector<int>& loops) {\n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\n// Rotate a tile by r steps counterclockwise\nvoid rotate_tile(vector<string>& tiles, int i, int j, int r) {\n    int t = tiles[i][j] - '0';\n    // Apply rotation r times\n    for (int step = 0; step < r; step++) {\n        if (t == 0) t = 1;\n        else if (t == 1) t = 2;\n        else if (t == 2) t = 3;\n        else if (t == 3) t = 0;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else if (t == 7) t = 6;\n    }\n    tiles[i][j] = '0' + t;\n}\n\nint main() {\n    // Read input\n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) {\n        cin >> tiles[i];\n    }\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Current solution (rotations for each tile)\n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n    \n    // Compute initial score\n    vector<int> initial_loops = compute_all_loops(tiles);\n    long long current_score = compute_score(initial_loops);\n    long long best_score = current_score;\n    vector<vector<int>> best_rotations = rotations;\n    \n    // Simulated annealing parameters\n    double temperature = 1000.0;\n    double cooling_rate = 0.99995;\n    \n    for (int step = 0; step < STEPS; step++) {\n        // Randomly select a tile to change\n        int i = rng() % N;\n        int j = rng() % N;\n        int old_rotation = rotations[i][j];\n        int new_rotation = rng() % 4;\n        \n        // Skip if no change\n        if (new_rotation == old_rotation) continue;\n        \n        // Apply rotation\n        int rot_diff = (new_rotation - old_rotation + 4) % 4;\n        rotate_tile(tiles, i, j, rot_diff);\n        rotations[i][j] = new_rotation;\n        \n        // Compute new score\n        vector<int> new_loops = compute_all_loops(tiles);\n        long long new_score = compute_score(new_loops);\n        \n        // Decide whether to accept the change\n        if (new_score > current_score || \n            rng() % 10000 < 10000 * exp((new_score - current_score) / temperature)) {\n            current_score = new_score;\n            \n            // Update best solution\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rotations = rotations;\n            }\n        } else {\n            // Revert the change\n            rotate_tile(tiles, i, j, (4 - rot_diff) % 4);\n            rotations[i][j] = old_rotation;\n        }\n        \n        // Cool down\n        temperature *= cooling_rate;\n    }\n    \n    // Output the best rotations found\n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += '0' + best_rotations[i][j];\n        }\n    }\n    \n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <utility>\n\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opposite[4] = {1, 0, 3, 2};\n\n// compute the size of the largest tree component\nint compute_S() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_vertices = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            if (visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int vertices = 0;\n            int edges = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                vertices++;\n                int mask = board[x][y];\n                for (int d = 0; d < 4; ++d) {\n                    if (!(mask & (1 << d))) continue;\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    int opp_mask = board[nx][ny];\n                    int opp_bit = 1 << opposite[d];\n                    if (opp_mask & opp_bit) {\n                        // count each edge only once (down or right)\n                        if (d == 1 || d == 3) {\n                            edges++;\n                        }\n                        if (!visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            if (edges == vertices - 1) {\n                max_tree_vertices = max(max_tree_vertices, vertices);\n            }\n        }\n    }\n    return max_tree_vertices;\n}\n\n// list of valid moves (U/D/L/R) for the empty cell\nvector<char> get_valid_moves() {\n    vector<char> moves;\n    for (int d = 0; d < 4; ++d) {\n        int ni = empty_i + di[d];\n        int nj = empty_j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            moves.push_back(dir_char[d]);\n        }\n    }\n    return moves;\n}\n\n// apply move in direction d (empty moves in that direction)\nvoid apply_move(int d) {\n    int ni = empty_i + di[d];\n    int nj = empty_j + dj[d];\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\n// undo move by applying the opposite direction\nvoid undo_move(int d) {\n    apply_move(opposite[d]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            board[i][j] = val;\n            if (val == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n\n    int current_S = compute_S();\n    int best_S = current_S;\n    string best_seq = \"\";\n    string current_seq = \"\";\n    string best_full_seq = \"\";   // best sequence that achieves a full tree\n\n    double temp = 1.0;\n    double cooling = 0.998;      // cooling factor per iteration\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n\n    for (int iter = 0; iter < T; ++iter) {\n        vector<char> moves = get_valid_moves();\n        if (moves.empty()) break;\n        char move = moves[gen() % moves.size()];\n        int d;\n        for (int i = 0; i < 4; ++i) {\n            if (dir_char[i] == move) {\n                d = i;\n                break;\n            }\n        }\n        apply_move(d);\n        int new_S = compute_S();\n        double delta = new_S - current_S;\n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            // accept move\n            current_S = new_S;\n            current_seq += move;\n            if (new_S > best_S) {\n                best_S = new_S;\n                best_seq = current_seq;\n            }\n            if (new_S == N * N - 1) {\n                // full tree achieved\n                if (best_full_seq.empty() || current_seq.length() < best_full_seq.length()) {\n                    best_full_seq = current_seq;\n                }\n            }\n        } else {\n            // reject move\n            undo_move(d);\n        }\n        temp *= cooling;\n    }\n\n    // output the best sequence found\n    if (!best_full_seq.empty()) {\n        if (best_seq.empty() || best_full_seq.length() < best_seq.length()) {\n            cout << best_full_seq << endl;\n        } else {\n            cout << best_seq << endl;\n        }\n    } else {\n        cout << best_seq << endl;\n    }\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n#include <set>\nusing namespace std;\n\n// Global arrays\nint a[11]; // a[1]..a[10]\n\n// Compute the score for given vertical lines V and horizontal lines H\nint compute_score(const vector<int>& V, const vector<int>& H, const vector<pair<int,int>>& points) {\n    int p = V.size();\n    int q = H.size();\n    int total_cells = (p+1)*(q+1);\n    vector<int> cell_counts(total_cells, 0);\n    \n    // Create boundary arrays including cake boundaries (-10000 and 10000)\n    vector<int> V_all(p+2), H_all(q+2);\n    V_all[0] = -10000;\n    for (int i=0; i<p; ++i) V_all[i+1] = V[i];\n    V_all[p+1] = 10000;\n    H_all[0] = -10000;\n    for (int i=0; i<q; ++i) H_all[i+1] = H[i];\n    H_all[q+1] = 10000;\n    \n    // For each point, determine its cell\n    for (const auto& pt : points) {\n        int x = pt.first, y = pt.second;\n        // Find vertical interval index i such that V_all[i] < x < V_all[i+1]\n        auto it_x = upper_bound(V_all.begin(), V_all.end(), x);\n        // Since x is strictly between -10000 and 10000, it_x cannot be begin or end\n        int i = (it_x - V_all.begin()) - 1;\n        // Find horizontal interval index j\n        auto it_y = upper_bound(H_all.begin(), H_all.end(), y);\n        int j = (it_y - H_all.begin()) - 1;\n        int cell_idx = i * (q+1) + j;\n        cell_counts[cell_idx]++;\n    }\n    \n    // Compute b_d for d=1..10\n    vector<int> b(11, 0); // index 1..10\n    for (int cnt : cell_counts) {\n        if (1 <= cnt && cnt <= 10) {\n            b[cnt]++;\n        }\n    }\n    int score = 0;\n    for (int d=1; d<=10; ++d) {\n        score += min(a[d], b[d]);\n    }\n    return score;\n}\n\n// Check if a vertical line at position x is valid (does not pass through any point)\nbool is_valid_vertical(int x, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.first == x) return false;\n    }\n    return true;\n}\n\n// Check if a horizontal line at position y is valid\nbool is_valid_horizontal(int y, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.second == y) return false;\n    }\n    return true;\n}\n\n// Find a free integer coordinate for a line, starting from a candidate and exploring nearby integers\nint find_free(int cand, const vector<int>& lines, const vector<pair<int,int>>& points, bool is_vertical) {\n    for (int d=0; ; ++d) {\n        for (int sign : {0, 1, -1}) {\n            int pos = cand + sign * d;\n            if (pos < -10000 || pos > 10000) continue;\n            // Check not already used by another line\n            if (find(lines.begin(), lines.end(), pos) != lines.end()) continue;\n            // Check not on any point\n            if (is_vertical) {\n                if (!is_valid_vertical(pos, points)) continue;\n            } else {\n                if (!is_valid_horizontal(pos, points)) continue;\n            }\n            return pos;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, K;\n    cin >> N >> K;\n    for (int d=1; d<=10; ++d) cin >> a[d];\n    \n    vector<pair<int,int>> points(N);\n    for (int i=0; i<N; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // We'll use p vertical and q horizontal lines with p+q = K\n    // Since K=100, we try p=50, q=50\n    int p = 50, q = K - p;\n    \n    // Extract x and y coordinates for initialization\n    vector<int> xs(N), ys(N);\n    for (int i=0; i<N; ++i) {\n        xs[i] = points[i].first;\n        ys[i] = points[i].second;\n    }\n    sort(xs.begin(), xs.end());\n    sort(ys.begin(), ys.end());\n    \n    // Initialize vertical lines\n    vector<int> V;\n    for (int i=1; i<=p; ++i) {\n        int idx = i * N / (p+1);\n        int cand = xs[idx];\n        int pos = find_free(cand, V, points, true);\n        V.push_back(pos);\n    }\n    sort(V.begin(), V.end());\n    \n    // Initialize horizontal lines\n    vector<int> H;\n    for (int i=1; i<=q; ++i) {\n        int idx = i * N / (q+1);\n        int cand = ys[idx];\n        int pos = find_free(cand, H, points, false);\n        H.push_back(pos);\n    }\n    sort(H.begin(), H.end());\n    \n    // Compute initial score\n    int best_score = compute_score(V, H, points);\n    vector<int> bestV = V, bestH = H;\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_line(0, (p+q)-1); // choose which line to modify\n    uniform_int_distribution<int> dist_offset(-10, 10);\n    \n    const int ITERATIONS = 5000;\n    for (int iter=0; iter<ITERATIONS; ++iter) {\n        // Choose a line to modify\n        int line_idx = dist_line(rng);\n        bool is_vertical = (line_idx < p);\n        int idx = is_vertical ? line_idx : line_idx - p;\n        \n        // Current position\n        int cur_pos = is_vertical ? V[idx] : H[idx];\n        // Generate candidate new position\n        int new_pos = cur_pos + dist_offset(rng);\n        if (new_pos < -10000 || new_pos > 10000) continue;\n        if (new_pos == cur_pos) continue;\n        \n        // Create candidate line sets\n        vector<int> newV = V;\n        vector<int> newH = H;\n        if (is_vertical) {\n            newV[idx] = new_pos;\n            // Check validity and no duplicates\n            if (!is_valid_vertical(new_pos, points)) continue;\n            sort(newV.begin(), newV.end());\n            if (adjacent_find(newV.begin(), newV.end()) != newV.end()) continue;\n        } else {\n            newH[idx] = new_pos;\n            if (!is_valid_horizontal(new_pos, points)) continue;\n            sort(newH.begin(), newH.end());\n            if (adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n        }\n        \n        // Compute new score\n        int new_score = compute_score(newV, newH, points);\n        if (new_score > best_score) {\n            best_score = new_score;\n            bestV = newV;\n            bestH = newH;\n            V = newV;\n            H = newH;\n        }\n    }\n    \n    // Output\n    cout << p + q << '\\n';\n    // Vertical lines\n    for (int x : bestV) {\n        cout << x << \" \" << -10000 << \" \" << x << \" \" << 10000 << '\\n';\n    }\n    // Horizontal lines\n    for (int y : bestH) {\n        cout << -10000 << \" \" << y << \" \" << 10000 << \" \" << y << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <ctime>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\n// Encode a unit segment into a 32-bit integer (canonical order: smaller x first, or if x equal, smaller y first)\nuint32_t encode_seg(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    // N <= 61, so 6 bits per coordinate are enough\n    return (x1 << 18) | (y1 << 12) | (x2 << 6) | y2;\n}\n\n// Check condition 2 for axis-aligned rectangle: no other dots on the perimeter (excluding corners)\nbool check_perimeter_axis(int x1, int y1, int x2, int y2, const vector<vector<bool>>& dot_grid) {\n    // vertical sides\n    for (int y = y1 + 1; y < y2; ++y) {\n        if (dot_grid[x1][y] || dot_grid[x2][y])\n            return false;\n    }\n    // horizontal sides\n    for (int x = x1 + 1; x < x2; ++x) {\n        if (dot_grid[x][y1] || dot_grid[x][y2])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for axis-aligned rectangle: no overlapping segments\nbool check_used_segments_axis(int x1, int y1, int x2, int y2, const unordered_set<uint32_t>& used_segments) {\n    // vertical sides\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x1, y, x1, y + 1)))\n            return false;\n        if (used_segments.count(encode_seg(x2, y, x2, y + 1)))\n            return false;\n    }\n    // horizontal sides\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y1, x + 1, y1)))\n            return false;\n        if (used_segments.count(encode_seg(x, y2, x + 1, y2)))\n            return false;\n    }\n    return true;\n}\n\n// Check condition 2 for 45-degree rectangle\nbool check_perimeter_45(int x, int y, int a, int b, const vector<vector<bool>>& dot_grid) {\n    // side P->C: (x,y) to (x+a, y+a)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + i][y + i])\n            return false;\n    }\n    // side C->Q: (x+a, y+a) to (x+a+b, y+a-b)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + a + i][y + a - i])\n            return false;\n    }\n    // side Q->D: (x+a+b, y+a-b) to (x+b, y-b)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + a + b - i][y + a - b - i])\n            return false;\n    }\n    // side D->P: (x+b, y-b) to (x,y)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + b - i][y - b + i])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for 45-degree rectangle\nbool check_used_segments_45(int x, int y, int a, int b, const unordered_set<uint32_t>& used_segments) {\n    // side P->C\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + i, y + i, x + i + 1, y + i + 1)))\n            return false;\n    }\n    // side C->Q\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + a + i, y + a - i, x + a + i + 1, y + a - i - 1)))\n            return false;\n    }\n    // side Q->D\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + a + b - i, y + a - b - i, x + a + b - i - 1, y + a - b - i - 1)))\n            return false;\n    }\n    // side D->P\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + b - i, y - b + i, x + b - i - 1, y - b + i + 1)))\n            return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    vector<Point> initial(M);\n    vector<vector<bool>> dot_grid(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        cin >> initial[i].x >> initial[i].y;\n        dot_grid[initial[i].x][initial[i].y] = true;\n    }\n\n    vector<Point> dots = initial;  // current list of dots\n    unordered_set<uint32_t> used_segments;\n    vector<array<int, 8>> operations;\n\n    int c = (N - 1) / 2;  // center coordinate\n    clock_t start_time = clock();\n\n    while (true) {\n        // Check time limit (4.5 seconds margin)\n        if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.5)\n            break;\n\n        int best_weight = -1;\n        array<int, 8> best_op;\n        bool found = false;\n\n        int Mcurr = dots.size();\n        for (int i = 0; i < Mcurr; ++i) {\n            for (int j = i + 1; j < Mcurr; ++j) {\n                Point A = dots[i], B = dots[j];\n\n                // ---------- Axis-aligned rectangle ----------\n                int x1 = min(A.x, B.x), x2 = max(A.x, B.x);\n                int y1 = min(A.y, B.y), y2 = max(A.y, B.y);\n                if (x1 < x2 && y1 < y2) {\n                    bool c1 = dot_grid[x1][y1];\n                    bool c2 = dot_grid[x1][y2];\n                    bool c3 = dot_grid[x2][y1];\n                    bool c4 = dot_grid[x2][y2];\n                    int cnt = c1 + c2 + c3 + c4;\n                    if (cnt == 3) {\n                        Point D;\n                        if (!c1) D = {x1, y1};\n                        else if (!c2) D = {x1, y2};\n                        else if (!c3) D = {x2, y1};\n                        else D = {x2, y2};\n\n                        if (check_perimeter_axis(x1, y1, x2, y2, dot_grid) &&\n                            check_used_segments_axis(x1, y1, x2, y2, used_segments)) {\n                            int w = (D.x - c) * (D.x - c) + (D.y - c) * (D.y - c) + 1;\n                            if (w > best_weight) {\n                                best_weight = w;\n                                // Build operation in cyclic order\n                                array<Point, 4> corners = { {x1, y1}, {x1, y2}, {x2, y2}, {x2, y1} };\n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                            }\n                        }\n                    }\n                }\n\n                // ---------- 45-degree rectangle ----------\n                // Try both orders (A as start, then B as start)\n                for (int order = 0; order < 2; ++order) {\n                    Point start = (order == 0) ? A : B;\n                    Point opposite = (order == 0) ? B : A;\n                    int dx = opposite.x - start.x;\n                    int dy = opposite.y - start.y;\n                    int sum_diff = dx + dy;\n                    int sub_diff = dx - dy;\n                    if (sum_diff % 2 != 0 || sub_diff % 2 != 0) continue;\n                    int a = sum_diff / 2;\n                    int b = sub_diff / 2;\n                    if (a <= 0 || b <= 0) continue;\n\n                    // Other two corners\n                    Point C = {start.x + a, start.y + a};\n                    Point D = {start.x + b, start.y - b};\n                    if (C.x < 0 || C.x >= N || C.y < 0 || C.y >= N ||\n                        D.x < 0 || D.x >= N || D.y < 0 || D.y >= N) continue;\n\n                    bool cC = dot_grid[C.x][C.y];\n                    bool cD = dot_grid[D.x][D.y];\n                    if (cC + cD != 1) continue;  // exactly one of C,D is a dot\n\n                    Point missing = cC ? D : C;  // the one that is not a dot\n                    // The four corners in order: start -> C -> opposite -> D\n                    array<Point, 4> corners = {start, C, opposite, D};\n\n                    if (check_perimeter_45(start.x, start.y, a, b, dot_grid) &&\n                        check_used_segments_45(start.x, start.y, a, b, used_segments)) {\n                        int w = (missing.x - c) * (missing.x - c) + (missing.y - c) * (missing.y - c) + 1;\n                        if (w > best_weight) {\n                            best_weight = w;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (!found) break;\n\n        // Perform the operation\n        operations.push_back(best_op);\n        Point new_dot = {best_op[0], best_op[1]};\n        dot_grid[new_dot.x][new_dot.y] = true;\n        dots.push_back(new_dot);\n\n        // Add the four edges of the rectangle to used_segments\n        for (int k = 0; k < 4; ++k) {\n            int k2 = (k + 1) % 4;\n            int x1 = best_op[2*k], y1 = best_op[2*k+1];\n            int x2 = best_op[2*k2], y2 = best_op[2*k2+1];\n            used_segments.insert(encode_seg(x1, y1, x2, y2));\n        }\n    }\n\n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            cout << op[i];\n            if (i < 7) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int SIZE = 10;\nusing Grid = vector<vector<int>>; // 1\u2011indexed, dimensions 11x11\n\n// Apply a tilt in the given direction to the grid and return the new grid.\nGrid apply_tilt(const Grid& grid, char dir) {\n    Grid new_grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n    if (dir == 'L') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][i + 1] = flavors[i];\n        }\n    } else if (dir == 'R') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][SIZE - k + 1 + i] = flavors[i];\n        }\n    } else if (dir == 'F') { // forward = up (towards row 1)\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[i + 1][c] = flavors[i];\n        }\n    } else { // 'B' \u2013 backward = down (towards row 10)\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[SIZE - k + 1 + i][c] = flavors[i];\n        }\n    }\n    return new_grid;\n}\n\n// Compute sum of squares of sizes of connected components (by flavor).\nlong long compute_score(const Grid& grid) {\n    bool visited[SIZE + 1][SIZE + 1] = {false};\n    long long score = 0;\n    const int dr[] = {1, -1, 0, 0};\n    const int dc[] = {0, 0, 1, -1};\n    for (int r = 1; r <= SIZE; ++r) {\n        for (int c = 1; c <= SIZE; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                vector<pair<int, int>> queue = {{r, c}};\n                visited[r][c] = true;\n                int idx = 0;\n                while (idx < queue.size()) {\n                    auto [cr, cc] = queue[idx++];\n                    ++size;\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = cr + dr[d];\n                        int nc = cc + dc[d];\n                        if (nr >= 1 && nr <= SIZE && nc >= 1 && nc <= SIZE &&\n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            queue.push_back({nr, nc});\n                        }\n                    }\n                }\n                score += (long long)size * size;\n            }\n        }\n    }\n    return score;\n}\n\nint main() {\n    vector<int> f(101); // 1\u2011indexed flavors of the 100 candies\n    for (int i = 1; i <= 100; ++i) cin >> f[i];\n\n    Grid grid(SIZE + 1, vector<int>(SIZE + 1, 0)); // initially empty\n\n    for (int t = 1; t <= 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Locate the p\u2011th empty cell (front\u2011to\u2011back, left\u2011to\u2011right).\n        int count = 0;\n        int placed_r = -1, placed_c = -1;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == 0) {\n                    ++count;\n                    if (count == p) {\n                        placed_r = r;\n                        placed_c = c;\n                        break;\n                    }\n                }\n            }\n            if (placed_r != -1) break;\n        }\n        grid[placed_r][placed_c] = f[t]; // place the candy\n\n        if (t == 100) break; // last candy \u2013 no need to tilt or output\n\n        // Evaluate all four directions.\n        char best_dir = 'F';\n        long long best_score = -1;\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid new_grid = apply_tilt(grid, dir);\n            long long score = compute_score(new_grid);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n\n        // Output the chosen direction and update the grid.\n        cout << best_dir << endl;\n        grid = apply_tilt(grid, best_dir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Precompute expected sorted degree lists for each possible a (1..N)\n    vector<vector<double>> exp_sorted(N + 1);\n    for (int a = 1; a <= N; ++a) {\n        vector<double> degs;\n        if (a == N) {\n            double mu = (N - 1) * (1 - epsilon);\n            degs.assign(N, mu);\n        } else {\n            double muA = (a - 1) * (1 - epsilon) + (N - a) * epsilon;\n            double muB = (N - a - 1) * (1 - epsilon) + a * epsilon;\n            for (int i = 0; i < a; ++i) degs.push_back(muA);\n            for (int i = 0; i < N - a; ++i) degs.push_back(muB);\n            sort(degs.begin(), degs.end());\n        }\n        exp_sorted[a] = degs;\n    }\n\n    // Precompute L1 distances between any two a\n    vector<vector<double>> dist(N + 1, vector<double>(N + 1, 0.0));\n    for (int a1 = 1; a1 <= N; ++a1) {\n        for (int a2 = a1 + 1; a2 <= N; ++a2) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(exp_sorted[a1][i] - exp_sorted[a2][i]);\n            }\n            dist[a1][a2] = d;\n            dist[a2][a1] = d;\n        }\n    }\n\n    // Greedy selection of M a values\n    vector<int> selected;\n    selected.push_back(50);  // start with middle to cover the range\n    vector<bool> used(N + 1, false);\n    used[50] = true;\n    for (int step = 1; step < M; ++step) {\n        int best_a = -1;\n        double best_min_dist = -1.0;\n        for (int a = 1; a <= N; ++a) {\n            if (used[a]) continue;\n            double min_dist = 1e18;\n            for (int b : selected) {\n                min_dist = min(min_dist, dist[a][b]);\n            }\n            if (min_dist > best_min_dist) {\n                best_min_dist = min_dist;\n                best_a = a;\n            }\n        }\n        selected.push_back(best_a);\n        used[best_a] = true;\n    }\n\n    // Sort selected a in increasing order for output order\n    sort(selected.begin(), selected.end());\n\n    // Create mapping from a to index\n    vector<int> index_of_a(N + 1, -1);\n    for (int i = 0; i < M; ++i) {\n        index_of_a[selected[i]] = i;\n    }\n\n    // Output N\n    cout << N << endl;\n\n    // Output M graphs\n    for (int a : selected) {\n        string graph;\n        graph.resize(N * (N - 1) / 2, '0');\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool same_clique = false;\n                if (a == N) {\n                    same_clique = true;  // complete graph\n                } else {\n                    if (i < a && j < a) same_clique = true;\n                    else if (i >= a && j >= a) same_clique = true;\n                }\n                if (same_clique) graph[pos] = '1';\n                pos++;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        // Compute degrees\n        vector<int> deg(N, 0);\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[pos] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                pos++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n\n        // Find the a with minimum L1 distance\n        int best_idx = -1;\n        double best_dist = 1e18;\n        for (int a : selected) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(deg[i] - exp_sorted[a][i]);\n            }\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = index_of_a[a];\n            }\n        }\n\n        cout << best_idx << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll INF = 1e18;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<int> u(M), v(M), w(M);\n    vector<vector<int>> edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        edge_idx[u[i]][v[i]] = i;\n        edge_idx[v[i]][u[i]] = i;\n    }\n\n    vector<int> coord_x(N), coord_y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coord_x[i] >> coord_y[i];\n    }\n\n    // midpoints of edges\n    vector<double> mid_x(M), mid_y(M);\n    for (int i = 0; i < M; ++i) {\n        mid_x[i] = (coord_x[u[i]] + coord_x[v[i]]) * 0.5;\n        mid_y[i] = (coord_y[u[i]] + coord_y[v[i]]) * 0.5;\n    }\n\n    // adjacency list\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        adj[u[i]].emplace_back(v[i], w[i]);\n        adj[v[i]].emplace_back(u[i], w[i]);\n    }\n\n    // all-pairs shortest paths and parent selection\n    vector<vector<ll>> dist(N, vector<ll>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n\n    for (int s = 0; s < N; ++s) {\n        dist[s][s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist[s][node]) continue;\n            for (auto [nbr, weight] : adj[node]) {\n                ll nd = d + weight;\n                if (nd < dist[s][nbr]) {\n                    dist[s][nbr] = nd;\n                    parent[s][nbr] = node;\n                    pq.emplace(nd, nbr);\n                } else if (nd == dist[s][nbr] && node < parent[s][nbr]) {\n                    parent[s][nbr] = node;\n                }\n            }\n        }\n    }\n\n    // criticality of each edge (cnt)\n    vector<ll> cnt(M, 0);\n    for (int s = 0; s < N; ++s) {\n        // build shortest\u2011path tree from parent[s]\n        vector<vector<int>> tree(N);\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            tree[p].push_back(v);\n            tree[v].push_back(p);\n        }\n\n        // iterative DFS to get postorder\n        vector<int> order;\n        vector<bool> visited(N, false);\n        stack<int> stk;\n        stk.push(s);\n        visited[s] = true;\n        while (!stk.empty()) {\n            int node = stk.top();\n            stk.pop();\n            order.push_back(node);\n            for (int nbr : tree[node]) {\n                if (!visited[nbr]) {\n                    visited[nbr] = true;\n                    stk.push(nbr);\n                }\n            }\n        }\n\n        // compute subtree sizes (using parent[s] to know children)\n        vector<int> sz(N, 0);\n        for (int i = order.size() - 1; i >= 0; --i) {\n            int node = order[i];\n            sz[node] = 1;\n            for (int nbr : tree[node]) {\n                if (nbr == s) continue;\n                if (parent[s][nbr] == node) {\n                    sz[node] += sz[nbr];\n                }\n            }\n        }\n\n        // add contributions\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            cnt[eidx] += sz[v];\n        }\n    }\n\n    // assign edges to days\n    vector<int> day_assign(M, -1);\n    vector<ll> day_sum(D, 0);\n    vector<int> day_cnt(D, 0);\n    vector<double> sum_mid_x(D, 0), sum_mid_y(D, 0);\n\n    // order edges by decreasing criticality\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n    sort(order_edges.begin(), order_edges.end(),\n         [&](int a, int b) { return cnt[a] > cnt[b]; });\n\n    for (int e : order_edges) {\n        // find minimum day_sum among days with free slots\n        ll min_sum = INF;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K) {\n                min_sum = min(min_sum, day_sum[d]);\n            }\n        }\n\n        // among those with min_sum, choose the one farthest from the edge\n        int best_day = -1;\n        double best_dist2 = -1.0;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K && day_sum[d] == min_sum) {\n                double dist2;\n                if (day_cnt[d] == 0) {\n                    dist2 = 1e18;  // prefer empty days\n                } else {\n                    double avg_x = sum_mid_x[d] / day_cnt[d];\n                    double avg_y = sum_mid_y[d] / day_cnt[d];\n                    double dx = mid_x[e] - avg_x;\n                    double dy = mid_y[e] - avg_y;\n                    dist2 = dx * dx + dy * dy;\n                }\n                if (dist2 > best_dist2) {\n                    best_dist2 = dist2;\n                    best_day = d;\n                }\n            }\n        }\n\n        // assign\n        day_assign[e] = best_day;\n        day_sum[best_day] += cnt[e];\n        day_cnt[best_day]++;\n        sum_mid_x[best_day] += mid_x[e];\n        sum_mid_y[best_day] += mid_y[e];\n    }\n\n    // output\n    for (int i = 0; i < M; ++i) {\n        cout << day_assign[i] + 1;\n        if (i < M - 1) cout << ' ';\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;  // global, needed for canonical shape normalization\n\n// 24 rotation matrices\nvector<array<array<int, 3>, 3>> rotations;\n\n// generate all rotations (determinant = 1)\nvoid generate_rotations() {\n    vector<int> axes = {0, 1, 2};\n    do {\n        // sign of permutation\n        int perm_sign = 1;\n        if (axes[0] == 0 && axes[1] == 1 && axes[2] == 2) perm_sign = 1;\n        else if (axes[0] == 0 && axes[1] == 2 && axes[2] == 1) perm_sign = -1;\n        else if (axes[0] == 1 && axes[1] == 0 && axes[2] == 2) perm_sign = -1;\n        else if (axes[0] == 1 && axes[1] == 2 && axes[2] == 0) perm_sign = 1;\n        else if (axes[0] == 2 && axes[1] == 0 && axes[2] == 1) perm_sign = 1;\n        else perm_sign = -1;\n\n        for (int s0 : {-1, 1}) {\n            for (int s1 : {-1, 1}) {\n                // s2 determined by determinant = s0 * s1 * s2 * perm_sign = 1\n                int s2 = (perm_sign * s0 * s1 == 1) ? 1 : -1;\n                array<array<int, 3>, 3> mat{};\n                mat[0][axes[0]] = s0;\n                mat[1][axes[1]] = s1;\n                mat[2][axes[2]] = s2;\n                rotations.push_back(mat);\n            }\n        }\n    } while (next_permutation(axes.begin(), axes.end()));\n}\n\nusing Point = array<int, 3>;\n\n// canonical shape of a block: normalized to min (0,0,0) and all rotations considered\nvector<Point> canonical_shape(const vector<Point>& cubes) {\n    // find current min\n    Point min = {D, D, D};\n    for (auto& p : cubes) {\n        for (int i = 0; i < 3; ++i) min[i] = min(min[i], p[i]);\n    }\n    vector<Point> rel;\n    for (auto& p : cubes) {\n        rel.push_back({p[0] - min[0], p[1] - min[1], p[2] - min[2]});\n    }\n\n    vector<Point> best = rel;\n    sort(best.begin(), best.end());\n\n    // try all rotations\n    for (const auto& rot : rotations) {\n        vector<Point> rotated;\n        for (auto& p : rel) {\n            Point np;\n            for (int i = 0; i < 3; ++i) {\n                np[i] = 0;\n                for (int j = 0; j < 3; ++j) np[i] += rot[i][j] * p[j];\n            }\n            rotated.push_back(np);\n        }\n        // normalize after rotation\n        Point minr = {D, D, D};\n        for (auto& p : rotated) {\n            for (int i = 0; i < 3; ++i) minr[i] = min(minr[i], p[i]);\n        }\n        vector<Point> norm;\n        for (auto& p : rotated) {\n            norm.push_back({p[0] - minr[0], p[1] - minr[1], p[2] - minr[2]});\n        }\n        sort(norm.begin(), norm.end());\n        if (norm < best) best = norm;\n    }\n    return best;\n}\n\n// a connected component (block)\nstruct Component {\n    vector<Point> cubes;\n    int volume;\n    vector<Point> canon;  // canonical shape\n    int block_id;\n    bool used;  // for matching\n};\n\n// generate minimal object from silhouette pair\nvector<Point> generate_object(const vector<string>& f, const vector<string>& r) {\n    vector<Point> cubes;\n    for (int z = 0; z < D; ++z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (f[z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (r[z][y] == '1') Y.push_back(y);\n        // guaranteed non-empty per problem statement\n        if (X.size() <= Y.size()) {\n            // match each x to a distinct y\n            for (size_t i = 0; i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining y\n            for (size_t i = X.size(); i < Y.size(); ++i) {\n                cubes.push_back({X[0], Y[i], z});\n            }\n        } else {\n            // match each y to a distinct x\n            for (size_t i = 0; i < Y.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining x\n            for (size_t i = Y.size(); i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[0], z});\n            }\n        }\n    }\n    return cubes;\n}\n\n// extract connected components from a set of cubes\nvector<Component> get_components(const vector<Point>& cubes) {\n    // boolean grid\n    vector<vector<vector<bool>>> grid(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (auto& p : cubes) grid[p[0]][p[1]][p[2]] = true;\n\n    vector<bool> visited(D * D * D, false);\n    vector<Component> comps;\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    for (auto& p : cubes) {\n        int idx = p[0] * D * D + p[1] * D + p[2];\n        if (!visited[idx]) {\n            // BFS\n            vector<Point> comp_cubes;\n            queue<Point> q;\n            q.push(p);\n            visited[idx] = true;\n            while (!q.empty()) {\n                Point cur = q.front(); q.pop();\n                comp_cubes.push_back(cur);\n                for (int d = 0; d < 6; ++d) {\n                    int nx = cur[0] + dx[d], ny = cur[1] + dy[d], nz = cur[2] + dz[d];\n                    if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && grid[nx][ny][nz]) {\n                        int nidx = nx * D * D + ny * D + nz;\n                        if (!visited[nidx]) {\n                            visited[nidx] = true;\n                            q.push({nx, ny, nz});\n                        }\n                    }\n                }\n            }\n            Component comp;\n            comp.cubes = comp_cubes;\n            comp.volume = comp_cubes.size();\n            comp.canon = canonical_shape(comp_cubes);\n            comp.used = false;\n            comps.push_back(comp);\n        }\n    }\n    return comps;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D;\n\n    // read silhouettes\n    vector<string> f0(D), r0(D), f1(D), r1(D);\n    for (int i = 0; i < D; ++i) cin >> f0[i];\n    for (int i = 0; i < D; ++i) cin >> r0[i];\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n\n    generate_rotations();\n\n    // minimal objects\n    vector<Point> obj0_cubes = generate_object(f0, r0);\n    vector<Point> obj1_cubes = generate_object(f1, r1);\n\n    // components for each object\n    vector<Component> comp0 = get_components(obj0_cubes);\n    vector<Component> comp1 = get_components(obj1_cubes);\n\n    // sort by volume (largest first) to prioritize matching large blocks\n    sort(comp0.begin(), comp0.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n    sort(comp1.begin(), comp1.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n\n    // map from canonical shape to list of indices in comp1\n    map<vector<Point>, vector<int>> shape_to_idx1;\n    for (size_t i = 0; i < comp1.size(); ++i) {\n        shape_to_idx1[comp1[i].canon].push_back(i);\n    }\n\n    int block_id = 1;\n    // match components with same shape\n    for (size_t i = 0; i < comp0.size(); ++i) {\n        auto it = shape_to_idx1.find(comp0[i].canon);\n        if (it != shape_to_idx1.end() && !it->second.empty()) {\n            int j = it->second.back();\n            it->second.pop_back();\n            comp0[i].block_id = block_id;\n            comp1[j].block_id = block_id;\n            comp0[i].used = true;\n            comp1[j].used = true;\n            ++block_id;\n        }\n    }\n\n    // assign ids to unmatched components\n    for (auto& comp : comp0) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    for (auto& comp : comp1) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    int n = block_id - 1;\n\n    // build output arrays\n    vector<int> b0(D * D * D, 0), b1(D * D * D, 0);\n    for (auto& comp : comp0) {\n        for (auto& p : comp.cubes) {\n            b0[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n    for (auto& comp : comp1) {\n        for (auto& p : comp.cubes) {\n            b1[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n\n    // output\n    cout << n << '\\n';\n    for (size_t i = 0; i < b0.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b0[i];\n    }\n    cout << '\\n';\n    for (size_t i = 0; i < b1.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <map>\n#include <set>\n#include <random>\n#include <climits>\n#include <cassert>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nconst double EPS = 1e-9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // Read edges and build distance matrix\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    for (int i = 0; i < N; ++i) distV[i][i] = 0;\n\n    vector<tuple<int, int, long long>> edges(M);\n    map<pair<int, int>, int> edgeIndex; // (min(u,v), max(u,v)) -> edge index\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[j] = {u, v, w};\n        if (u > v) swap(u, v);\n        edgeIndex[{u, v}] = j;\n        distV[u][v] = min(distV[u][v], w);\n        distV[v][u] = min(distV[v][u], w);\n    }\n\n    // Floyd-Warshall with next matrix for path reconstruction\n    vector<vector<int>> next(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i != j && distV[i][j] < INF) {\n                next[i][j] = j;\n            }\n        }\n    }\n\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][k] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[k][j] == INF) continue;\n                if (distV[i][j] > distV[i][k] + distV[k][j]) {\n                    distV[i][j] = distV[i][k] + distV[k][j];\n                    next[i][j] = next[i][k];\n                }\n            }\n        }\n    }\n\n    // Read residents\n    vector<double> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // Distance from each vertex to each resident\n    vector<vector<double>> distVtoR(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            distVtoR[i][k] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Initial assignment: each resident to nearest vertex\n    vector<int> assign(K);\n    vector<vector<int>> residentList(N);\n    for (int k = 0; k < K; ++k) {\n        int best = 0;\n        for (int i = 1; i < N; ++i) {\n            if (distVtoR[i][k] < distVtoR[best][k] - EPS) {\n                best = i;\n            }\n        }\n        assign[k] = best;\n        residentList[best].push_back(k);\n    }\n\n    // Compute initial P[i]\n    vector<int> P(N, 0);\n    for (int i = 0; i < N; ++i) {\n        if (residentList[i].empty()) {\n            P[i] = 0;\n        } else {\n            double maxDist = 0;\n            for (int k : residentList[i]) {\n                maxDist = max(maxDist, distVtoR[i][k]);\n            }\n            P[i] = (int)ceil(maxDist);\n            // Ensure not exceeding 5000 (though problem guarantees within 5000)\n            if (P[i] > 5000) P[i] = 5000;\n        }\n    }\n\n    // Compute initial sum of squares\n    long long sumSq = 0;\n    for (int i = 0; i < N; ++i) {\n        sumSq += (long long)P[i] * P[i];\n    }\n\n    // Function to compute Steiner tree cost for a set of terminals\n    auto computeSteinerCost = [&](const vector<int>& T) -> long long {\n        int n = T.size();\n        if (n <= 1) return 0;\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        minDist[0] = 0;\n        long long total = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            if (u == -1) break;\n            inMST[u] = true;\n            total += minDist[u];\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[T[u]][T[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                    }\n                }\n            }\n        }\n        return total;\n    };\n\n    // Build initial T (vertex 0 + vertices with P>0)\n    vector<int> currentT;\n    currentT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            currentT.push_back(i);\n        }\n    }\n    long long currentSteinerCost = computeSteinerCost(currentT);\n    long long currentCost = sumSq + currentSteinerCost;\n\n    // Local search\n    int maxIter = 10000;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> residentDist(0, K-1);\n\n    for (int iter = 0; i < maxIter; ++iter) {\n        int k = residentDist(gen);\n        int i = assign[k];\n        bool improved = false;\n        for (int j = 0; j < N; ++j) {\n            if (j == i) continue;\n\n            // Simulate move\n            int oldP_i = P[i], oldP_j = P[j];\n\n            // Compute new lists without scanning entire list each time? We'll copy temporarily.\n            vector<int> newList_i, newList_j;\n            for (int r : residentList[i]) {\n                if (r != k) newList_i.push_back(r);\n            }\n            for (int r : residentList[j]) {\n                newList_j.push_back(r);\n            }\n            newList_j.push_back(k);\n\n            // Compute new P_i and P_j\n            int newP_i = 0, newP_j = 0;\n            if (!newList_i.empty()) {\n                double maxDist = 0;\n                for (int r : newList_i) {\n                    maxDist = max(maxDist, distVtoR[i][r]);\n                }\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!newList_j.empty()) {\n                double maxDist = 0;\n                for (int r : newList_j) {\n                    maxDist = max(maxDist, distVtoR[j][r]);\n                }\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n\n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n\n            // Check if T changes\n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                // Remove i from newT\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                // Add j to newT\n                newT.push_back(j);\n            }\n\n            long long newCost;\n            if (newT == currentT) {\n                newCost = newSumSq + currentSteinerCost;\n            } else {\n                long long newSteinerCost = computeSteinerCost(newT);\n                newCost = newSumSq + newSteinerCost;\n                if (newCost < currentCost - EPS) {\n                    // Accept move\n                    // Update structures\n                    sumSq = newSumSq;\n                    P[i] = newP_i;\n                    P[j] = newP_j;\n                    residentList[i] = newList_i;\n                    residentList[j] = newList_j;\n                    assign[k] = j;\n                    currentT = newT;\n                    currentSteinerCost = newSteinerCost;\n                    currentCost = newCost;\n                    improved = true;\n                    break;\n                }\n            }\n            if (newCost < currentCost - EPS) {\n                // Accept move\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                residentList[i] = newList_i;\n                residentList[j] = newList_j;\n                assign[k] = j;\n                currentT = newT;\n                currentCost = newCost;\n                improved = true;\n                break;\n            }\n        }\n        // If no improvement, continue to next iteration\n    }\n\n    // Final T for output\n    vector<int> finalT;\n    finalT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            finalT.push_back(i);\n        }\n    }\n\n    // Compute Steiner tree edges\n    set<int> onEdges;\n    auto addPath = [&](int u, int v) {\n        while (u != v) {\n            int nxt = next[u][v];\n            int a = u, b = nxt;\n            if (a > b) swap(a, b);\n            onEdges.insert(edgeIndex[{a, b}]);\n            u = nxt;\n        }\n    };\n\n    // Compute MST on metric closure of finalT\n    int n = finalT.size();\n    if (n > 1) {\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[finalT[u]][finalT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        // Reconstruct MST edges\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u != -1) {\n                addPath(finalT[u], finalT[v]);\n            }\n        }\n    }\n\n    // Output P[i]\n    for (int i = 0; i < N; ++i) {\n        cout << P[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    // Output B[j]\n    for (int j = 0; j < M; ++j) {\n        cout << (onEdges.count(j) ? 1 : 0);\n        if (j < M-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2; // 465\n\n// Convert (x,y) to index (row-major order)\nint to_index(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Convert index to (x,y)\npair<int, int> to_coord(int idx) {\n    int x = 0;\n    while (idx >= x + 1) {\n        idx -= (x + 1);\n        x++;\n    }\n    return {x, idx};\n}\n\n// Directions: six neighbors as deltas (dx, dy)\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Check if coordinates are valid\nbool valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y <= x;\n}\n\nint main() {\n    // Read input\n    vector<int> ball(TOTAL);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int b;\n            cin >> b;\n            ball[to_index(x, y)] = b;\n        }\n    }\n\n    // Create sorted list of all ball numbers\n    vector<int> sorted = ball;\n    sort(sorted.begin(), sorted.end());\n\n    // Target: row-major order with sorted numbers\n    vector<int> target(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) {\n        target[i] = sorted[i];\n    }\n\n    // Precompute adjacency list\n    vector<vector<int>> adj(TOTAL);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int u = to_index(x, y);\n            for (int d = 0; d < 6; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (valid(nx, ny)) {\n                    int v = to_index(nx, ny);\n                    adj[u].push_back(v);\n                }\n            }\n        }\n    }\n\n    // Current position of each ball (by number)\n    vector<int> pos(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) {\n        pos[ball[i]] = i;\n    }\n\n    vector<bool> fixed(TOTAL, false);\n    vector<tuple<int, int, int, int>> swaps; // (x1,y1,x2,y2)\n\n    // Helper to perform a swap between two adjacent positions\n    auto do_swap = [&](int i, int j) {\n        // Record the swap\n        auto [x1, y1] = to_coord(i);\n        auto [x2, y2] = to_coord(j);\n        swaps.emplace_back(x1, y1, x2, y2);\n        // Update ball and pos arrays\n        int b1 = ball[i], b2 = ball[j];\n        swap(ball[i], ball[j]);\n        pos[b1] = j;\n        pos[b2] = i;\n    };\n\n    // BFS to find shortest path from src to dest avoiding fixed nodes (except dest)\n    auto bfs = [&](int src, int dest, const vector<bool>& fixed) -> vector<int> {\n        vector<int> parent(TOTAL, -1);\n        vector<bool> visited(TOTAL, false);\n        queue<int> q;\n        q.push(src);\n        visited[src] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            if (u == dest) break;\n            for (int v : adj[u]) {\n                if (!visited[v] && (v == dest || !fixed[v])) {\n                    visited[v] = true;\n                    parent[v] = u;\n                    q.push(v);\n                }\n            }\n        }\n        if (parent[dest] == -1) return {}; // no path\n        vector<int> path;\n        for (int cur = dest; cur != -1; cur = parent[cur]) {\n            path.push_back(cur);\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    // Process positions in row-major order\n    for (int i = 0; i < TOTAL; ++i) {\n        if (fixed[i]) continue;\n        if (ball[i] == target[i]) {\n            fixed[i] = true;\n            continue;\n        }\n        int want = target[i];\n        int src = pos[want];\n        if (src == i) {\n            fixed[i] = true;\n            continue;\n        }\n        // Find path from src to i avoiding fixed nodes (except i)\n        vector<int> path = bfs(src, i, fixed);\n        // In case no path found, we try to relax by allowing fixed nodes temporarily?\n        // For safety, if no path, we simply skip? But should not happen.\n        if (path.empty()) {\n            // Fallback: just swap directly if adjacent? Not necessarily.\n            // We'll try to find any path without avoiding fixed, but that might disturb fixed.\n            // Instead, we can try to find a path that goes through fixed but then we need to re-fix them.\n            // To keep it simple, we assume a path always exists (should be true for connected graph).\n            // If not, we break.\n            continue;\n        }\n        // Perform swaps along the path\n        for (size_t k = 0; k + 1 < path.size(); ++k) {\n            do_swap(path[k], path[k + 1]);\n        }\n        // Now i should have the correct ball\n        fixed[i] = true;\n        // Note: intermediate positions along the path are not fixed, so we leave them.\n    }\n\n    // Output\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nconst int D = 9;\nconst int entrance_i = 0, entrance_j = 4;\n\nint main() {\n    int N;\n    cin >> D >> N;  // D is always 9, but read anyway\n    bool obstacle[D][D] = {false};\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N; // number of containers\n\n    bool occupied[D][D] = {false};\n    int label_of[D][D];\n    int parent_i[D][D], parent_j[D][D];\n    vector<pair<int, int>> children[D][D];\n\n    vector<int> seen_labels;\n\n    // process containers one by one\n    for (int d = 0; d < M; ++d) {\n        int t;\n        cin >> t;\n\n        // BFS from entrance through empty squares\n        int dist[D][D];\n        memset(dist, -1, sizeof(dist));\n        pair<int, int> bfs_parent[D][D];\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            const int di[4] = {1, -1, 0, 0};\n            const int dj[4] = {0, 0, 1, -1};\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                    !obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    bfs_parent[ni][nj] = {i, j};\n                    q.push({ni, nj});\n                }\n            }\n        }\n\n        // collect leaves (empty squares with exactly one empty neighbor)\n        vector<tuple<int, int, int>> leaves; // (distance, i, j)\n        const int di[4] = {1, -1, 0, 0};\n        const int dj[4] = {0, 0, 1, -1};\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == entrance_i && j == entrance_j) continue;\n                if (dist[i][j] == -1) continue;\n                int empty_neighbors = 0;\n                for (int dir = 0; dir < 4; ++dir) {\n                    int ni = i + di[dir], nj = j + dj[dir];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                        !obstacle[ni][nj] && !occupied[ni][nj]) {\n                        empty_neighbors++;\n                    }\n                }\n                if (empty_neighbors == 1) {\n                    leaves.push_back({dist[i][j], i, j});\n                }\n            }\n        }\n\n        // sort leaves by distance (closest first)\n        sort(leaves.begin(), leaves.end());\n\n        // compute quantile of current label among seen labels\n        double quantile;\n        if (seen_labels.empty()) {\n            quantile = 0.0;\n        } else {\n            int count_smaller = 0;\n            for (int lbl : seen_labels) {\n                if (lbl < t) count_smaller++;\n            }\n            quantile = (double)count_smaller / seen_labels.size();\n        }\n\n        // choose leaf according to quantile\n        int L = leaves.size();\n        int idx = (int)round(quantile * (L - 1));\n        idx = max(0, min(L - 1, idx));\n        auto [dist_val, pi, pj] = leaves[idx];\n\n        // output placement\n        cout << pi << \" \" << pj << endl;\n\n        // record placement\n        occupied[pi][pj] = true;\n        label_of[pi][pj] = t;\n        parent_i[pi][pj] = bfs_parent[pi][pj].first;\n        parent_j[pi][pj] = bfs_parent[pi][pj].second;\n        children[parent_i[pi][pj]][parent_j[pi][pj]].push_back({pi, pj});\n\n        seen_labels.push_back(t);\n    }\n\n    // determine and output transport order\n    priority_queue<pair<int, pair<int, int>>,\n                   vector<pair<int, pair<int, int>>>,\n                   greater<>> pq;\n    bool removed[D][D] = {false};\n\n    // initially, containers whose parent is the entrance are removable\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (occupied[i][j] && parent_i[i][j] == entrance_i && parent_j[i][j] == entrance_j) {\n                pq.push({label_of[i][j], {i, j}});\n            }\n        }\n    }\n\n    while (!pq.empty()) {\n        auto [lbl, coords] = pq.top(); pq.pop();\n        int i = coords.first, j = coords.second;\n        cout << i << \" \" << j << endl;\n        removed[i][j] = true;\n\n        // children of the removed container become removable\n        for (auto child : children[i][j]) {\n            int ci = child.first, cj = child.second;\n            pq.push({label_of[ci][cj], {ci, cj}});\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x < p.x || (x == p.x && y < p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\n// BFS to find shortest path between two sets in a graph defined by allowed cells\nvector<Point> bfs_path(const vector<vector<bool>>& allowed, \n                       const set<Point>& start_set, \n                       const set<Point>& end_set,\n                       int n) {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    vector<vector<Point>> prev(n, vector<Point>(n, Point(-1, -1)));\n    queue<Point> q;\n    \n    for (const Point& p : start_set) {\n        visited[p.x][p.y] = true;\n        q.push(p);\n    }\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        if (end_set.count(cur)) {\n            // Reconstruct path\n            vector<Point> path;\n            Point at = cur;\n            while (!(at.x == -1 && at.y == -1)) {\n                path.push_back(at);\n                at = prev[at.x][at.y];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && allowed[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                prev[nx][ny] = cur;\n                q.push(Point(nx, ny));\n            }\n        }\n    }\n    return {}; // No path found\n}\n\n// Check if removing a point disconnects a set of points\nbool is_articulation(const set<Point>& region, const Point& p, int n) {\n    if (!region.count(p)) return false;\n    \n    set<Point> remaining = region;\n    remaining.erase(p);\n    \n    if (remaining.empty()) return false;\n    \n    // Find first point in remaining\n    Point start = *remaining.begin();\n    set<Point> component;\n    queue<Point> q;\n    q.push(start);\n    component.insert(start);\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            Point np(nx, ny);\n            if (remaining.count(np) && !component.count(np)) {\n                component.insert(np);\n                q.push(np);\n            }\n        }\n    }\n    \n    return component.size() != remaining.size();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n = N, m = M;\n    vector<vector<int>> grid(n, vector<int>(n));\n    \n    // Read input\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    // Build adjacency information\n    vector<set<int>> adj_colors(m + 1); // neighbors for each color\n    // For each unordered pair (c,d), store a list of adjacent cell pairs\n    vector<vector<vector<pair<Point, Point>>>> adj_pairs(m + 1, vector<vector<pair<Point, Point>>>(m + 1));\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int color = grid[ni][nj];\n                    if (color != c) {\n                        // Ensure c < color for consistent ordering\n                        if (c < color) {\n                            adj_colors[c].insert(color);\n                            adj_colors[color].insert(c);\n                            adj_pairs[c][color].push_back({Point(i, j), Point(ni, nj)});\n                        } else if (c > color) {\n                            adj_colors[color].insert(c);\n                            adj_colors[c].insert(color);\n                            adj_pairs[color][c].push_back({Point(ni, nj), Point(i, j)});\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Anchor selection: for each edge (c,d), choose one pair\n    vector<set<Point>> anchors(m + 1);\n    \n    for (int c = 1; c <= m; c++) {\n        for (int d : adj_colors[c]) {\n            if (c >= d) continue; // process each edge once\n            \n            // Check if we already have an adjacent pair in anchors\n            bool already_adjacent = false;\n            for (const Point& p1 : anchors[c]) {\n                for (int dir = 0; dir < 4; dir++) {\n                    Point p2(p1.x + dx[dir], p1.y + dy[dir]);\n                    if (anchors[d].count(p2)) {\n                        already_adjacent = true;\n                        break;\n                    }\n                }\n                if (already_adjacent) break;\n            }\n            if (already_adjacent) continue;\n            \n            // Try to find a pair that uses existing anchors\n            bool found = false;\n            for (auto& pr : adj_pairs[c][d]) {\n                Point u = pr.first, v = pr.second;\n                if (anchors[c].count(u)) {\n                    anchors[d].insert(v);\n                    found = true;\n                    break;\n                } else if (anchors[d].count(v)) {\n                    anchors[c].insert(u);\n                    found = true;\n                    break;\n                }\n            }\n            if (!found && !adj_pairs[c][d].empty()) {\n                // Add both cells\n                Point u = adj_pairs[c][d][0].first;\n                Point v = adj_pairs[c][d][0].second;\n                anchors[c].insert(u);\n                anchors[d].insert(v);\n            }\n        }\n    }\n    \n    // For colors with no anchors, add an arbitrary cell\n    for (int c = 1; c <= m; c++) {\n        if (anchors[c].empty()) {\n            // Find any cell of this color\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (grid[i][j] == c) {\n                        anchors[c].insert(Point(i, j));\n                        break;\n                    }\n                }\n                if (!anchors[c].empty()) break;\n            }\n        }\n    }\n    \n    // Build Steiner trees for each color\n    vector<set<Point>> kept(m + 1); // kept cells for each color\n    \n    for (int c = 1; c <= m; c++) {\n        // Create allowed matrix for this color\n        vector<vector<bool>> allowed(n, vector<bool>(n, false));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == c) {\n                    allowed[i][j] = true;\n                }\n            }\n        }\n        \n        set<Point> terminals = anchors[c];\n        set<Point> current = terminals;\n        \n        // Connect components iteratively\n        while (true) {\n            // Find connected components of current\n            vector<set<Point>> components;\n            set<Point> visited;\n            \n            for (const Point& p : current) {\n                if (visited.count(p)) continue;\n                \n                set<Point> comp;\n                queue<Point> q;\n                q.push(p);\n                comp.insert(p);\n                visited.insert(p);\n                \n                while (!q.empty()) {\n                    Point cur = q.front();\n                    q.pop();\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point np(cur.x + dx[d], cur.y + dy[d]);\n                        if (np.x >= 0 && np.x < n && np.y >= 0 && np.y < n && \n                            allowed[np.x][np.y] && current.count(np) && !visited.count(np)) {\n                            comp.insert(np);\n                            visited.insert(np);\n                            q.push(np);\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n            \n            if (components.size() <= 1) break;\n            \n            // Connect first two components\n            set<Point> comp1 = components[0], comp2 = components[1];\n            vector<Point> path = bfs_path(allowed, comp1, comp2, n);\n            \n            if (!path.empty()) {\n                for (const Point& p : path) {\n                    current.insert(p);\n                }\n            } else {\n                // Should not happen since graph is connected\n                break;\n            }\n        }\n        \n        // Prune leaves that are not terminals\n        set<Point> tree = current;\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            vector<Point> to_remove;\n            for (const Point& p : tree) {\n                if (terminals.count(p)) continue;\n                \n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    Point np(p.x + dx[d], p.y + dy[d]);\n                    if (tree.count(np)) deg++;\n                }\n                if (deg <= 1) {\n                    to_remove.push_back(p);\n                }\n            }\n            \n            for (const Point& p : to_remove) {\n                tree.erase(p);\n                changed = true;\n            }\n        }\n        \n        kept[c] = tree;\n    }\n    \n    // Build output grid\n    vector<vector<int>> output(n, vector<int>(n, 0));\n    for (int c = 1; c <= m; c++) {\n        for (const Point& p : kept[c]) {\n            output[p.x][p.y] = c;\n        }\n    }\n    \n    // Check connectivity of 0\n    vector<vector<bool>> visited0(n, vector<bool>(n, false));\n    queue<Point> q0;\n    \n    // Start from boundary 0 cells (connected to outside)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if ((i == 0 || i == n-1 || j == 0 || j == n-1) && output[i][j] == 0) {\n                q0.push(Point(i, j));\n                visited0[i][j] = true;\n            }\n        }\n    }\n    \n    while (!q0.empty()) {\n        Point cur = q0.front();\n        q0.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                output[nx][ny] == 0 && !visited0[nx][ny]) {\n                visited0[nx][ny] = true;\n                q0.push(Point(nx, ny));\n            }\n        }\n    }\n    \n    // If there are unvisited 0 cells, try to fix\n    bool disconnected = false;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0 && !visited0[i][j]) {\n                disconnected = true;\n                break;\n            }\n        }\n        if (disconnected) break;\n    }\n    \n    if (disconnected) {\n        // Try to remove some non-zero cells to connect 0\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] != 0 && !visited0[i][j]) {\n                    int c = output[i][j];\n                    Point p(i, j);\n                    \n                    // Check if this cell can be removed\n                    bool can_remove = true;\n                    \n                    // Check if it's a leaf in its tree and not a terminal\n                    if (kept[c].count(p)) {\n                        int deg = 0;\n                        for (int d = 0; d < 4; d++) {\n                            Point np(i + dx[d], j + dy[d]);\n                            if (kept[c].count(np)) deg++;\n                        }\n                        if (deg > 1) can_remove = false;\n                        \n                        // Check if it's the only anchor for some neighbor\n                        for (int d : adj_colors[c]) {\n                            if (d == 0) continue;\n                            bool has_other = false;\n                            for (const Point& q : kept[c]) {\n                                if (q == p) continue;\n                                for (int dir = 0; dir < 4; dir++) {\n                                    Point nq(q.x + dx[dir], q.y + dy[dir]);\n                                    if (nq.x >= 0 && nq.x < n && nq.y >= 0 && nq.y < n && \n                                        output[nq.x][nq.y] == d) {\n                                        has_other = true;\n                                        break;\n                                    }\n                                }\n                                if (has_other) break;\n                            }\n                            if (!has_other) {\n                                can_remove = false;\n                                break;\n                            }\n                        }\n                    } else {\n                        can_remove = false;\n                    }\n                    \n                    if (can_remove) {\n                        // Change to 0 and update\n                        output[i][j] = 0;\n                        kept[c].erase(p);\n                        \n                        // Re-run BFS for 0 connectivity\n                        fill(visited0.begin(), visited0.end(), vector<bool>(n, false));\n                        queue<Point> q0;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if ((ii == 0 || ii == n-1 || jj == 0 || jj == n-1) && output[ii][jj] == 0) {\n                                    q0.push(Point(ii, jj));\n                                    visited0[ii][jj] = true;\n                                }\n                            }\n                        }\n                        while (!q0.empty()) {\n                            Point cur = q0.front();\n                            q0.pop();\n                            for (int d = 0; d < 4; d++) {\n                                int nx = cur.x + dx[d];\n                                int ny = cur.y + dy[d];\n                                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                                    output[nx][ny] == 0 && !visited0[nx][ny]) {\n                                    visited0[nx][ny] = true;\n                                    q0.push(Point(nx, ny));\n                                }\n                            }\n                        }\n                        \n                        // Check if still disconnected\n                        disconnected = false;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if (output[ii][jj] == 0 && !visited0[ii][jj]) {\n                                    disconnected = true;\n                                    break;\n                                }\n                            }\n                            if (disconnected) break;\n                        }\n                        if (!disconnected) break;\n                    }\n                }\n            }\n            if (!disconnected) break;\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\n// perform a query with given left and right sets, return the comparison result\nchar query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string s;\n    cin >> s;\n    queries_used++;\n    return s[0];\n}\n\n// compare two individual items\nchar compare(int i, int j) {\n    return query({i}, {j});\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    vector<int> items;  // sorted order as much as we know\n\n    // Insert items one by one using binary search with comparisons\n    for (int i = 0; i < N; ++i) {\n        if (queries_used >= Q) {\n            // no queries left, just append\n            items.push_back(i);\n            continue;\n        }\n        int left = 0, right = items.size();\n        while (left < right && queries_used < Q) {\n            int mid = (left + right) / 2;\n            char res = compare(i, items[mid]);\n            if (res == '<') {\n                right = mid;\n            } else {\n                left = mid + 1;\n            }\n        }\n        items.insert(items.begin() + left, i);\n    }\n\n    // Use any remaining queries (dummy comparisons)\n    while (queries_used < Q) {\n        compare(0, 1);  // always valid as N >= 2\n    }\n\n    // Assign items to buckets in snake order according to the (partially) sorted list\n    vector<int> ans(N);\n    for (int i = 0; i < N; ++i) {\n        int item = items[i];\n        int bucket = i % D;\n        if ((i / D) % 2 == 1) {\n            bucket = D - 1 - bucket;\n        }\n        ans[item] = bucket;\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    int h = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    for (int v = 1; v <= n; ++v) {\n        // Find the stack and position of box v\n        int s = -1, pos = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == v) {\n                    s = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (pos == (int)stacks[s].size() - 1) {\n            // v is already on top: remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        } else {\n            // Need to move the boxes above v\n            int T = stacks[s].back();  // top of the group to be moved\n            // Choose destination stack d according to the heuristic\n            int d = -1;\n            bool found_empty = false;\n            int empty_d = -1;\n            int best_d = -1;\n            int best_top = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if (stacks[i].empty()) {\n                    found_empty = true;\n                    if (empty_d == -1) empty_d = i;\n                } else {\n                    int top = stacks[i].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        best_d = i;\n                    }\n                }\n            }\n\n            if (found_empty) {\n                if (best_d == -1 || T > best_top) {\n                    d = empty_d;\n                } else {\n                    d = best_d;\n                }\n            } else {\n                d = best_d;\n            }\n\n            // Move the suffix starting at the box just above v\n            int w = stacks[s][pos + 1];\n            cout << w << \" \" << d + 1 << \"\\n\";\n\n            vector<int> suffix(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[s].erase(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[d].insert(stacks[d].end(), suffix.begin(), suffix.end());\n\n            // Now v is on top, remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        }\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <stack>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\nusing namespace std;\n\nconst int dx[] = {1, -1, 0, 0}; // D, U, R, L\nconst int dy[] = {0, 0, 1, -1};\nconst char dir_char[] = {'D', 'U', 'R', 'L'};\n\nstruct Cell {\n    int i, j, id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n\n    vector<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\n\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    // assign ids\n    vector<vector<int>> id(N, vector<int>(N));\n    vector<Cell> cells(N*N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int idx = i*N + j;\n            id[i][j] = idx;\n            cells[idx] = {i, j, idx};\n        }\n\n    // build graph with directions\n    vector<vector<pair<int, char>>> graph(N*N);\n    auto add_edge = [&](int i1, int j1, int i2, int j2, char dir) {\n        int u = id[i1][j1], v = id[i2][j2];\n        graph[u].emplace_back(v, dir);\n        graph[v].emplace_back(u, dir_char[(string(\"DURL\").find(dir) + 2) % 4]); // opposite direction\n    };\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // down\n            if (i+1 < N && h[i][j] == '0') add_edge(i, j, i+1, j, 'D');\n            // right\n            if (j+1 < N && v[i][j] == '0') add_edge(i, j, i, j+1, 'R');\n        }\n    }\n\n    // target frequencies f_v = round(sqrt(d))\n    vector<int> f(N*N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            f[id[i][j]] = max(1, (int)round(sqrt(d[i][j])));\n\n    // BFS to get spanning tree\n    vector<int> parent(N*N, -1);\n    vector<char> parent_dir(N*N);\n    vector<vector<int>> children(N*N);\n    queue<int> q;\n    q.push(0);\n    parent[0] = -2; // root\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        int ui = cells[u].i, uj = cells[u].j;\n        for (auto [v, dir] : graph[u]) {\n            if (parent[v] == -1) {\n                parent[v] = u;\n                parent_dir[v] = dir;\n                children[u].push_back(v);\n                q.push(v);\n            }\n        }\n    }\n\n    // compute current degree in tree\n    vector<int> deg_cur(N*N, 0);\n    for (int v = 1; v < N*N; ++v) {\n        deg_cur[v]++; // edge to parent\n        deg_cur[parent[v]]++;\n    }\n\n    // adjust f if needed to satisfy 2*f >= deg_cur\n    for (int v = 0; v < N*N; ++v) {\n        while (2 * f[v] < deg_cur[v]) {\n            f[v]++;\n        }\n    }\n\n    // compute deficit\n    vector<int> deficit(N*N);\n    for (int v = 0; v < N*N; ++v) {\n        deficit[v] = 2 * f[v] - deg_cur[v];\n    }\n\n    // post-order traversal to compute extra multiplicities on tree edges\n    vector<int> extra(N*N, 0); // extra copies on edge from child to parent\n    function<void(int)> dfs = [&](int u) {\n        for (int v : children[u]) {\n            dfs(v);\n            extra[v] = deficit[v];\n            deficit[u] += deficit[v];\n            deficit[v] = 0;\n        }\n    };\n    dfs(0);\n\n    // adjust root if necessary\n    if (deficit[0] != 0) {\n        f[0] += deficit[0] / 2;\n        deficit[0] = 0;\n    }\n\n    // build multigraph with multiplicities\n    vector<vector<pair<int, int>>> multigraph(N*N); // neighbor, multiplicity\n    vector<vector<char>> move_dir(N*N); // direction char from this vertex to neighbor (parallel to multigraph)\n    // initialize with tree edges\n    for (int v = 1; v < N*N; ++v) {\n        int u = parent[v];\n        int mul = 1 + extra[v];\n        if (mul > 0) {\n            multigraph[u].emplace_back(v, mul);\n            multigraph[v].emplace_back(u, mul);\n            // store directions: from u to v is parent_dir[v], from v to u is opposite\n            char dir_uv = parent_dir[v];\n            char dir_vu = dir_char[(string(\"DURL\").find(dir_uv) + 2) % 4];\n            // We'll store direction when traversing from u to v or v to u. We'll handle during tour.\n        }\n    }\n\n    // For Eulerian tour, we need to store the direction for each edge in both directions.\n    // We'll create separate adjacency lists for the multigraph that include direction.\n    struct Edge {\n        int to;\n        int mul;\n        char dir; // direction from current vertex to 'to'\n    };\n    vector<vector<Edge>> euler_adj(N*N);\n    for (int v = 1; v < N*N; ++v) {\n        int u = parent[v];\n        int mul = 1 + extra[v];\n        char dir_uv = parent_dir[v];\n        char dir_vu = dir_char[(string(\"DURL\").find(dir_uv) + 2) % 4];\n        euler_adj[u].push_back({v, mul, dir_uv});\n        euler_adj[v].push_back({u, mul, dir_vu});\n    }\n\n    // Hierholzer's algorithm\n    vector<int> circuit;\n    vector<int> ptr(N*N, 0);\n    stack<int> stk;\n    stk.push(0);\n    while (!stk.empty()) {\n        int u = stk.top();\n        if (ptr[u] < (int)euler_adj[u].size()) {\n            Edge &e = euler_adj[u][ptr[u]];\n            if (e.mul > 0) {\n                // traverse edge\n                e.mul--;\n                // find the reverse edge and decrement\n                for (Edge &rev : euler_adj[e.to]) {\n                    if (rev.to == u && rev.mul > 0) {\n                        rev.mul--;\n                        break;\n                    }\n                }\n                stk.push(e.to);\n            } else {\n                ptr[u]++;\n            }\n        } else {\n            circuit.push_back(u);\n            stk.pop();\n        }\n    }\n    reverse(circuit.begin(), circuit.end());\n\n    // Build move string\n    string moves;\n    for (size_t i = 0; i + 1 < circuit.size(); ++i) {\n        int u = circuit[i], v = circuit[i+1];\n        // find direction from u to v\n        for (const Edge &e : euler_adj[u]) {\n            if (e.to == v) {\n                moves += e.dir;\n                break;\n            }\n        }\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nstruct Candidate {\n    vector<pii> pos;      // 5 positions\n    int internal_cost;    // cost to type this occurrence from scratch\n    vector<int> tail_cost; // tail_cost[k]: cost from position k to end (including letter at k)\n};\n\nint manhattan(const pii& a, const pii& b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    pii start;\n    cin >> start.first >> start.second;\n\n    vector<vector<char>> A(N, vector<char>(N));\n    vector<vector<pii>> pos_list(26); // positions for each letter\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            pos_list[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n\n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n\n    // Random number generator\n    mt19937 rng(123456); // fixed seed for reproducibility\n    uniform_int_distribution<int> dist;\n\n    const int CANDIDATE_COUNT = 100;\n    const int KEEP = 10;\n\n    vector<vector<Candidate>> candidates(M);\n\n    // Generate candidate occurrences for each target\n    for (int idx = 0; idx < M; ++idx) {\n        const string& t = targets[idx];\n        vector<Candidate> cands;\n        for (int iter = 0; iter < CANDIDATE_COUNT; ++iter) {\n            vector<pii> pos(5);\n            for (int k = 0; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                uniform_int_distribution<int> d(0, (int)lst.size() - 1);\n                pos[k] = lst[d(rng)];\n            }\n\n            // Compute internal cost\n            int internal = 5; // cost for typing the letters themselves\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1; // cost to type the last letter\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n\n        // Keep the best KEEP candidates by internal cost\n        sort(cands.begin(), cands.end(),\n             [](const Candidate& a, const Candidate& b) { return a.internal_cost < b.internal_cost; });\n        if (cands.size() > KEEP) cands.resize(KEEP);\n        candidates[idx] = cands;\n    }\n\n    // Precompute valid overlaps between targets\n    vector<vector<vector<int>>> valid(M, vector<vector<int>>(M));\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            const string& si = targets[i];\n            const string& sj = targets[j];\n            vector<int> v;\n            for (int k = 1; k <= 4; ++k) {\n                if (si.substr(5 - k) == sj.substr(0, k)) {\n                    v.push_back(k);\n                }\n            }\n            v.push_back(0); // k=0 always allowed\n            valid[i][j] = v;\n        }\n    }\n\n    // Greedy construction of the path\n    vector<int> order_targets;\n    vector<int> order_candidate_idx;\n    vector<int> order_overlap; // overlap used to reach this target (for i>0)\n    vector<bool> covered(M, false);\n\n    pii cur_pos = start;\n    int cur_target = -1; // index of the last target in the current path\n\n    for (int step = 0; step < M; ++step) {\n        double best_add = 1e18;\n        int best_j = -1, best_c = -1, best_k = -1;\n\n        for (int j = 0; j < M; ++j) {\n            if (covered[j]) continue;\n            for (size_t c = 0; c < candidates[j].size(); ++c) {\n                const Candidate& cand = candidates[j][c];\n                if (cur_target == -1) {\n                    // First target: cost from start to first position + internal cost\n                    int add = manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n                    if (add < best_add) {\n                        best_add = add;\n                        best_j = j;\n                        best_c = c;\n                        best_k = 0; // not used\n                    }\n                } else {\n                    // Consider all valid overlaps\n                    for (int k : valid[cur_target][j]) {\n                        int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                        if (add < best_add) {\n                            best_add = add;\n                            best_j = j;\n                            best_c = c;\n                            best_k = k;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Append the chosen target\n        covered[best_j] = true;\n        order_targets.push_back(best_j);\n        order_candidate_idx.push_back(best_c);\n        if (cur_target != -1) {\n            order_overlap.push_back(best_k);\n        }\n\n        // Update current state\n        cur_target = best_j;\n        cur_pos = candidates[best_j][best_c].pos[4]; // last position of the occurrence\n    }\n\n    // Build the output sequence of moves\n    vector<pii> moves;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        const Candidate& occ = candidates[order_targets[i]][order_candidate_idx[i]];\n        if (i == 0) {\n            for (int j = 0; j < 5; ++j) {\n                moves.push_back(occ.pos[j]);\n            }\n        } else {\n            int k = order_overlap[i];\n            for (int j = k; j < 5; ++j) {\n                moves.push_back(occ.pos[j]);\n            }\n        }\n    }\n\n    // Output the moves\n    for (const pii& p : moves) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (not used in this simple solution)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n    \n    vector<pair<int, int>> oil_cells;\n    \n    // Drill every square\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            int val;\n            cin >> val;\n            if (val > 0) {\n                oil_cells.push_back({i, j});\n            }\n        }\n    }\n    \n    // Output the guess\n    cout << \"a \" << oil_cells.size();\n    for (auto [i, j] : oil_cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    // Read response (should be 1)\n    int resp;\n    cin >> resp;\n    // If response is 0, we could try again, but drilling all should be correct.\n    // For safety, if resp == 0, we could drill again? But problem says operation ends if correct.\n    // We'll just exit.\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <cassert>\nusing namespace std;\n\nconst int W = 1000;\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    int area() const { return (x2 - x1) * (y2 - y1); }\n};\n\n// Greedy allocation of target areas B_k\nvector<long long> allocateB(const vector<vector<int>>& A, int D, int N) {\n    vector<long long> B(N, 0);\n    long long total_remaining = (long long)W * W;\n    // For each k, collect desires and sort\n    vector<vector<int>> sortedA(N);\n    for (int k = 0; k < N; ++k) {\n        for (int d = 0; d < D; ++d) {\n            sortedA[k].push_back(A[d][k]);\n        }\n        sort(sortedA[k].begin(), sortedA[k].end());\n    }\n    // Create segments: each (benefit, length, k)\n    struct Segment {\n        int benefit, len, k;\n        bool operator<(const Segment& other) const {\n            return benefit < other.benefit; // max-heap\n        }\n    };\n    vector<Segment> segments;\n    for (int k = 0; k < N; ++k) {\n        int prev = 0;\n        for (size_t i = 0; i < sortedA[k].size(); ++i) {\n            int cur = sortedA[k][i];\n            if (cur > prev) {\n                int benefit = 100 * (D - i);\n                int len = cur - prev;\n                segments.push_back({benefit, len, k});\n            }\n            prev = cur;\n        }\n        // After the last desire, benefit becomes 0, ignore.\n    }\n    priority_queue<Segment> pq(segments.begin(), segments.end());\n    while (total_remaining > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        if (seg.benefit == 0) break;\n        long long take = min((long long)seg.len, total_remaining);\n        B[seg.k] += take;\n        total_remaining -= take;\n        seg.len -= take;\n        if (seg.len > 0) {\n            pq.push(seg);\n        }\n    }\n    // Distribute remaining area arbitrarily (benefit 0)\n    if (total_remaining > 0) {\n        for (int k = 0; k < N && total_remaining > 0; ++k) {\n            long long add = min(total_remaining, (long long)1);\n            B[k] += add;\n            total_remaining -= add;\n        }\n    }\n    return B;\n}\n\n// Shelf packing for rectangles with target areas B\nvector<Rect> packRectangles(const vector<long long>& B) {\n    int N = B.size();\n    vector<Rect> rects(N);\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    // For each rectangle, choose dimensions to achieve at least B[k] with minimal waste\n    vector<pair<int, int>> dims(N); // (height, width)\n    for (int k = 0; k < N; ++k) {\n        long long area = B[k];\n        int best_h = 1, best_w = area;\n        long long best_waste = best_w * best_h - area;\n        for (int h = 1; h <= W; ++h) {\n            long long w = (area + h - 1) / h; // ceil\n            if (w > W) continue;\n            long long waste = w * h - area;\n            if (waste < best_waste) {\n                best_waste = waste;\n                best_h = h;\n                best_w = w;\n            }\n        }\n        dims[k] = {best_h, best_w};\n    }\n    // Sort indices by height descending\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return dims[i].first > dims[j].first;\n    });\n    // Shelf packing\n    struct Shelf {\n        int y1, y2; // vertical range\n        int x;      // current x position\n    };\n    vector<Shelf> shelves;\n    int current_y = 0;\n    for (int idx : indices) {\n        int h = dims[idx].first, w = dims[idx].second;\n        bool placed = false;\n        for (auto& shelf : shelves) {\n            if (shelf.y2 - shelf.y1 >= h && shelf.x + w <= W) {\n                rects[idx] = {shelf.x, shelf.y1, shelf.x + w, shelf.y1 + h};\n                shelf.x += w;\n                placed = true;\n                break;\n            }\n        }\n        if (!placed) {\n            // Create new shelf at current_y\n            int y2 = min(W, current_y + h);\n            Shelf shelf{current_y, y2, 0};\n            rects[idx] = {0, current_y, w, y2};\n            shelf.x = w;\n            shelves.push_back(shelf);\n            current_y = y2;\n            placed = true;\n        }\n    }\n    return rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int 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) {\n            cin >> A[d][k];\n        }\n    }\n\n    vector<long long> B = allocateB(A, D, N);\n    vector<Rect> rects = packRectangles(B);\n\n    // Compute actual areas and sort indices by area ascending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return rects[i].area() < rects[j].area();\n    });\n\n    // Output for each day\n    for (int d = 0; d < D; ++d) {\n        // Sort reservations by desired area ascending\n        vector<int> day_order(N);\n        iota(day_order.begin(), day_order.end(), 0);\n        sort(day_order.begin(), day_order.end(), [&](int i, int j) {\n            return A[d][i] < A[d][j];\n        });\n        // Create assignment: smallest rect to smallest desire\n        vector<Rect> assigned(N);\n        for (int i = 0; i < N; ++i) {\n            int k = day_order[i];          // reservation index\n            int rect_idx = order[i];       // rectangle index\n            assigned[k] = rects[rect_idx];\n        }\n        // Output in reservation order (0..N-1)\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = assigned[k];\n            cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\nstruct Move {\n    int m, p, q;\n    vector<pair<int, int>> cells; // (index, value)\n};\n\nstruct State {\n    array<int, N*N> board;\n    long long score;\n    State* parent;\n    int m, p, q; // move that led to this state, or -1 for initial\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    vector<int> a(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i*N + j];\n        }\n    }\n\n    vector<array<array<int, 3>, 3>> 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][i][j];\n            }\n        }\n    }\n\n    // Precompute all possible moves\n    vector<Move> moves;\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                Move move;\n                move.m = m;\n                move.p = p;\n                move.q = q;\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        int idx = (p+i)*N + (q+j);\n                        int val = stamps[m][i][j] % MOD;\n                        move.cells.emplace_back(idx, val);\n                    }\n                }\n                moves.push_back(move);\n            }\n        }\n    }\n\n    // Beam search\n    const int beam_width = 10;\n    vector<State*> all_states;\n    State* initial = new State;\n    initial->parent = nullptr;\n    initial->m = initial->p = initial->q = -1;\n    copy(a.begin(), a.end(), initial->board.begin());\n    initial->score = accumulate(a.begin(), a.end(), 0LL);\n    all_states.push_back(initial);\n\n    State* global_best = initial;\n    long long global_best_score = initial->score;\n\n    vector<State*> current_beam;\n    current_beam.push_back(initial);\n\n    for (int step = 0; step < K; ++step) {\n        vector<State*> candidates;\n\n        for (State* s : current_beam) {\n            // Option: do nothing\n            candidates.push_back(s);\n\n            // Try every move\n            for (const Move& move : moves) {\n                array<int, N*N> new_board = s->board;\n                long long gain = 0;\n\n                for (auto [idx, val] : move.cells) {\n                    int old_rem = new_board[idx];\n                    int new_rem = (old_rem + val) % MOD;\n                    gain += new_rem - old_rem;\n                    new_board[idx] = new_rem;\n                }\n\n                long long new_score = s->score + gain;\n\n                State* new_state = new State;\n                new_state->board = new_board;\n                new_state->score = new_score;\n                new_state->parent = s;\n                new_state->m = move.m;\n                new_state->p = move.p;\n                new_state->q = move.q;\n\n                candidates.push_back(new_state);\n                all_states.push_back(new_state);\n\n                if (new_score > global_best_score) {\n                    global_best = new_state;\n                    global_best_score = new_score;\n                }\n            }\n        }\n\n        // Select top beam_width states\n        sort(candidates.begin(), candidates.end(),\n             [](State* a, State* b) { return a->score > b->score; });\n\n        if (!candidates.empty() && candidates[0]->score > global_best_score) {\n            global_best = candidates[0];\n            global_best_score = candidates[0]->score;\n        }\n\n        current_beam.clear();\n        for (int i = 0; i < beam_width && i < candidates.size(); ++i) {\n            current_beam.push_back(candidates[i]);\n        }\n    }\n\n    // Reconstruct the sequence of moves\n    vector<tuple<int, int, int>> sequence;\n    State* cur = global_best;\n    while (cur->parent != nullptr) {\n        sequence.emplace_back(cur->m, cur->p, cur->q);\n        cur = cur->parent;\n    }\n    reverse(sequence.begin(), sequence.end());\n\n    // Output\n    cout << sequence.size() << \"\\n\";\n    for (auto [m, p, q] : sequence) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    // Clean up\n    for (State* s : all_states) {\n        delete s;\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Crane {\n    int r, c;\n    int holding = -1; // container ID or -1\n    enum State { IDLE, MOVING_TO_PICKUP, PICKING_UP, MOVING_TO_DROPOFF, DROPPING_OFF, WAITING };\n    State state = IDLE;\n    int target_r = -1, target_c = -1;\n    int dest_row = -1; // for large crane: destination row for parking\n    vector<pair<int,int>> path;\n    int path_idx = 0;\n    \n    Crane(int r, int c) : r(r), c(c) {}\n};\n\nint grid[N][N]; // -1 empty, else container ID\nint gate_next_idx[N]; // next index to place for each left gate\nvector<int> gate_queues[N]; // A[i][0..4]\nint dispatch_next_needed[N]; // next needed ID for each row\nvector<int> dispatched[N]; // dispatched IDs per row\nbool container_dispatched[N*N] = {false};\nCrane cranes[N] = {Crane(0,0), Crane(1,0), Crane(2,0), Crane(3,0), Crane(4,0)};\n\n// Check if a cell is occupied by a container\nbool has_container(int r, int c) {\n    return grid[r][c] != -1;\n}\n\n// Check if a cell is occupied by another crane (excluding self)\nbool has_other_crane(int r, int c, int self_idx) {\n    for (int i = 0; i < N; ++i) {\n        if (i != self_idx && cranes[i].r == r && cranes[i].c == c) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a crane can move to a cell\nbool can_move_to(int r, int c, int crane_idx, bool carrying) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return false;\n    if (has_other_crane(r, c, crane_idx)) return false;\n    if (carrying && has_container(r, c)) return false; // small crane with container can't move to occupied\n    // Large crane (index 0) can move to cells with containers even while carrying\n    if (crane_idx == 0) return true;\n    return true;\n}\n\n// BFS to find next move direction from (sr,sc) to (tr,tc)\npair<int,int> find_next_move(int sr, int sc, int tr, int tc, int crane_idx, bool carrying) {\n    if (sr == tr && sc == tc) return {0, 0};\n    \n    // BFS\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    visited[sr][sc] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) break;\n        \n        int dr[] = {-1, 1, 0, 0};\n        int dc[] = {0, 0, -1, 1};\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (can_move_to(nr, nc, crane_idx, carrying) && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                prev[nr][nc] = {r, c};\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path and return first step\n    if (!visited[tr][tc]) return {0, 0}; // no path, stay\n    \n    // Trace back\n    int r = tr, c = tc;\n    while (prev[r][c] != make_pair(sr, sc)) {\n        auto [pr, pc] = prev[r][c];\n        r = pr; c = pc;\n    }\n    // Now (r,c) is one step from (sr,sc)\n    return {r - sr, c - sc};\n}\n\n// Find free parking spot in row (columns 1-3)\nint find_free_parking(int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (!has_container(row, c) && !has_other_crane(row, c, -1)) {\n            return c;\n        }\n    }\n    return -1;\n}\n\n// Check if a container is parked in a given row\nbool is_parked_in_row(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return true;\n    }\n    return false;\n}\n\n// Find the cell where a container is parked in a row\npair<int,int> find_parked_cell(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return {row, c};\n    }\n    return {-1, -1};\n}\n\nvoid simulate(vector<string>& actions) {\n    // Initialize\n    memset(grid, -1, sizeof(grid));\n    fill(gate_next_idx, gate_next_idx + N, 0);\n    fill(dispatch_next_needed, dispatch_next_needed + N, 0);\n    for (int i = 0; i < N; ++i) dispatched[i].clear();\n    fill(container_dispatched, container_dispatched + N*N, false);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].holding = -1;\n        cranes[i].state = Crane::IDLE;\n        cranes[i].path.clear();\n    }\n    \n    actions.resize(N);\n    for (int t = 0; t < MAX_TURNS; ++t) {\n        // Step 1: Place containers at gates\n        for (int i = 0; i < N; ++i) {\n            if (gate_next_idx[i] >= N) continue;\n            bool can_place = true;\n            if (has_container(i, 0)) can_place = false;\n            for (int k = 0; k < N; ++k) {\n                if (cranes[k].r == i && cranes[k].c == 0 && cranes[k].holding != -1) {\n                    can_place = false;\n                    break;\n                }\n            }\n            if (can_place) {\n                int container_id = gate_queues[i][gate_next_idx[i]];\n                grid[i][0] = container_id;\n                gate_next_idx[i]++;\n            }\n        }\n        \n        // Step 2: Crane actions\n        vector<char> turn_actions(N, '.');\n        \n        // Process large crane (index 0) first\n        auto& lc = cranes[0];\n        switch (lc.state) {\n            case Crane::IDLE: {\n                // Look for a container at a left gate that needs to be moved to parking\n                for (int i = 0; i < N; ++i) {\n                    if (!has_container(i, 0)) continue;\n                    int container_id = grid[i][0];\n                    int dest = container_id / N;\n                    int free_c = find_free_parking(dest);\n                    if (free_c != -1) {\n                        // Set target to pick up this container\n                        lc.target_r = i;\n                        lc.target_c = 0;\n                        lc.dest_row = dest;\n                        lc.state = Crane::MOVING_TO_PICKUP;\n                        break;\n                    }\n                }\n                break;\n            }\n            case Crane::MOVING_TO_PICKUP: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, lc.holding != -1);\n                if (dr == 0 && dc == 0) {\n                    // Reached, pick up\n                    turn_actions[0] = 'P';\n                    lc.holding = grid[lc.r][lc.c];\n                    grid[lc.r][lc.c] = -1;\n                    lc.state = Crane::PICKING_UP;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::PICKING_UP: {\n                // Set target for dropoff\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c == -1) {\n                    // No free spot, wait\n                    lc.state = Crane::WAITING;\n                } else {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n            case Crane::MOVING_TO_DROPOFF: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, true);\n                if (dr == 0 && dc == 0) {\n                    // Reached, drop\n                    turn_actions[0] = 'Q';\n                    grid[lc.r][lc.c] = lc.holding;\n                    lc.holding = -1;\n                    lc.state = Crane::DROPPING_OFF;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::DROPPING_OFF: {\n                lc.state = Crane::IDLE;\n                break;\n            }\n            case Crane::WAITING: {\n                // Check if a free spot became available\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c != -1) {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n        }\n        \n        // Process small cranes (indices 1-4)\n        for (int i = 1; i < N; ++i) {\n            auto& sc = cranes[i];\n            switch (sc.state) {\n                case Crane::IDLE: {\n                    int need = dispatch_next_needed[i];\n                    if (need < i*N || need >= (i+1)*N) break; // invalid\n                    if (container_dispatched[need]) break;\n                    auto [pr, pc] = find_parked_cell(need, i);\n                    if (pr != -1) {\n                        sc.target_r = pr;\n                        sc.target_c = pc;\n                        sc.state = Crane::MOVING_TO_PICKUP;\n                    }\n                    break;\n                }\n                case Crane::MOVING_TO_PICKUP: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, sc.holding != -1);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'P';\n                        sc.holding = grid[sc.r][sc.c];\n                        grid[sc.r][sc.c] = -1;\n                        sc.state = Crane::PICKING_UP;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::PICKING_UP: {\n                    sc.target_r = i;\n                    sc.target_c = N-1;\n                    sc.state = Crane::MOVING_TO_DROPOFF;\n                    break;\n                }\n                case Crane::MOVING_TO_DROPOFF: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, true);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'Q';\n                        grid[sc.r][sc.c] = sc.holding;\n                        sc.holding = -1;\n                        sc.state = Crane::DROPPING_OFF;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::DROPPING_OFF: {\n                    sc.state = Crane::IDLE;\n                    break;\n                }\n                case Crane::WAITING: {\n                    break;\n                }\n            }\n        }\n        \n        // Step 3: Dispatch containers from right gates\n        for (int i = 0; i < N; ++i) {\n            if (has_container(i, N-1)) {\n                int container_id = grid[i][N-1];\n                dispatched[i].push_back(container_id);\n                container_dispatched[container_id] = true;\n                grid[i][N-1] = -1;\n                // Update next needed for this row\n                while (dispatch_next_needed[i] < (i+1)*N && container_dispatched[dispatch_next_needed[i]]) {\n                    dispatch_next_needed[i]++;\n                }\n            }\n        }\n        \n        // Record actions\n        for (int i = 0; i < N; ++i) {\n            actions[i] += turn_actions[i];\n        }\n        \n        // Check if all containers dispatched\n        bool all_done = true;\n        for (int id = 0; id < N*N; ++id) {\n            if (!container_dispatched[id]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; ++i) {\n        gate_queues[i].resize(N);\n        for (int j = 0; j < N; ++j) {\n            cin >> gate_queues[i][j];\n        }\n    }\n    \n    vector<string> actions;\n    simulate(actions);\n    \n    // Pad shorter strings with '.'\n    size_t max_len = 0;\n    for (const string& s : actions) {\n        max_len = max(max_len, s.size());\n    }\n    for (string& s : actions) {\n        if (s.size() < max_len) {\n            s.append(max_len - s.size(), '.');\n        }\n    }\n    \n    for (const string& s : actions) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 20;\n\n// Generate snake path by rows: (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> ... -> (N-1,0)\nvector<pair<int, int>> generate_path_rows() {\n    vector<pair<int, int>> path;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) path.emplace_back(i, j);\n        } else {\n            for (int j = N - 1; j >= 0; --j) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate snake path by columns: (0,0) -> (1,0) -> ... -> (N-1,0) -> (N-1,1) -> ... -> (0,N-1)\nvector<pair<int, int>> generate_path_cols() {\n    vector<pair<int, int>> path;\n    for (int j = 0; j < N; ++j) {\n        if (j % 2 == 0) {\n            for (int i = 0; i < N; ++i) path.emplace_back(i, j);\n        } else {\n            for (int i = N - 1; i >= 0; --i) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Compute the total load-distance for a loading tour along the given path\nint compute_load_distance(const vector<pair<int, int>>& path, const vector<vector<int>>& h) {\n    int load = 0;\n    int total = 0;\n    for (int idx = 0; idx < (int)path.size(); ++idx) {\n        int i = path[idx].first, j = path[idx].second;\n        if (h[i][j] > 0) load += h[i][j];\n        if (idx < (int)path.size() - 1) total += load;\n    }\n    return total;\n}\n\n// Determine move direction from (i,j) to (ni,nj) assuming they are adjacent\nstring get_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return \"U\";\n    if (ni == i + 1) return \"D\";\n    if (nj == j - 1) return \"L\";\n    if (nj == j + 1) return \"R\";\n    assert(false);\n    return \"\";\n}\n\nint main() {\n    // Read input\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    // Generate two candidate paths\n    vector<pair<int, int>> path_rows = generate_path_rows();\n    vector<pair<int, int>> path_cols = generate_path_cols();\n\n    // Choose the path with smaller load-distance for loading tour\n    int dist_rows = compute_load_distance(path_rows, h);\n    int dist_cols = compute_load_distance(path_cols, h);\n    vector<pair<int, int>> best_path = (dist_rows <= dist_cols) ? path_rows : path_cols;\n\n    // Make a copy of heights for simulation\n    vector<vector<int>> cur_h = h;\n    vector<string> ops;\n    int load = 0;\n\n    // Loading tour along best_path\n    int cur_i = best_path[0].first, cur_j = best_path[0].second;\n    for (int idx = 0; idx < (int)best_path.size(); ++idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Load if positive\n        if (cur_h[i][j] > 0) {\n            int d = cur_h[i][j];\n            ops.push_back(\"+\" + to_string(d));\n            load += d;\n            cur_h[i][j] = 0;\n        }\n        // Move to next cell if not last\n        if (idx < (int)best_path.size() - 1) {\n            int ni = best_path[idx+1].first, nj = best_path[idx+1].second;\n            ops.push_back(get_move(cur_i, cur_j, ni, nj));\n            cur_i = ni;\n            cur_j = nj;\n        }\n    }\n\n    // Unloading tour along the reverse of best_path\n    for (int idx = (int)best_path.size() - 1; idx >= 0; --idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Unload if negative\n        if (cur_h[i][j] < 0) {\n            int amount = min(load, -cur_h[i][j]);\n            if (amount > 0) {\n                ops.push_back(\"-\" + to_string(amount));\n                load -= amount;\n                cur_h[i][j] += amount;\n            }\n        }\n        // Move to previous cell if not first\n        if (idx > 0) {\n            int pi = best_path[idx-1].first, pj = best_path[idx-1].second;\n            ops.push_back(get_move(cur_i, cur_j, pi, pj));\n            cur_i = pi;\n            cur_j = pj;\n        }\n    }\n\n    // Output the operation sequence\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    const int N = 6;\n    const int M = 15;\n    const int T = 10;\n    const int K = 2 * N * (N - 1); // 60\n\n    // Read initial seeds\n    vector<vector<int>> seeds(K, vector<int>(M));\n    for (int i = 0; i < K; ++i) {\n        for (int l = 0; l < M; ++l) {\n            cin >> seeds[i][l];\n        }\n    }\n\n    // Center of the grid (0-indexed)\n    const int center_i = 3, center_j = 3;\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Compute total sums\n        vector<int> sums(K, 0);\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                sums[i] += seeds[i][l];\n            }\n        }\n\n        // Select top 36 seeds by sum\n        vector<int> indices(K);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(),\n             [&](int i, int j) { return sums[i] > sums[j]; });\n        vector<int> S_indices(indices.begin(), indices.begin() + 36);\n\n        // Champion is the best seed\n        int champion_idx = S_indices[0];\n        const auto& champion_vec = seeds[champion_idx];\n\n        // Compute complementarity (potential max sum) for each candidate\n        vector<pair<int, int>> candidate_P; // (P, index)\n        for (int i = 1; i < 36; ++i) {\n            int idx = S_indices[i];\n            int P_val = 0;\n            for (int l = 0; l < M; ++l) {\n                P_val += max(champion_vec[l], seeds[idx][l]);\n            }\n            candidate_P.emplace_back(P_val, idx);\n        }\n        sort(candidate_P.begin(), candidate_P.end(), greater<>());\n\n        // Choose up to 4 mates\n        vector<int> mate_indices;\n        for (int i = 0; i < min(4, (int)candidate_P.size()); ++i) {\n            mate_indices.push_back(candidate_P[i].second);\n        }\n\n        // Build the grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> seed_used(K, false);\n\n        // Place champion\n        grid[center_i][center_j] = champion_idx;\n        seed_used[champion_idx] = true;\n\n        // Place mates in the four orthogonal neighbours\n        vector<pair<int, int>> offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        for (int i = 0; i < (int)mate_indices.size(); ++i) {\n            int ni = center_i + offsets[i].first;\n            int nj = center_j + offsets[i].second;\n            grid[ni][nj] = mate_indices[i];\n            seed_used[mate_indices[i]] = true;\n        }\n\n        // Collect remaining seeds from S_indices\n        vector<int> remaining_seeds;\n        for (int idx : S_indices) {\n            if (!seed_used[idx]) {\n                remaining_seeds.push_back(idx);\n            }\n        }\n\n        // Collect empty cells\n        vector<pair<int, int>> empty_cells;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == -1) {\n                    empty_cells.emplace_back(i, j);\n                }\n            }\n        }\n\n        // Fill the remaining cells\n        for (size_t i = 0; i < remaining_seeds.size(); ++i) {\n            auto [r, c] = empty_cells[i];\n            grid[r][c] = remaining_seeds[i];\n        }\n\n        // Output comments for debugging (ignored by judge)\n        cout << \"# Turn \" << turn << endl;\n        cout << \"# Champion: index=\" << champion_idx << \" sum=\" << sums[champion_idx] << endl;\n        cout << \"# Mates: \";\n        for (size_t i = 0; i < mate_indices.size(); ++i) {\n            int idx = mate_indices[i];\n            cout << idx << \" (sum=\" << sums[idx] << \", P=\" << candidate_P[i].first << \") \";\n        }\n        cout << endl;\n\n        // Output the grid\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j > 0) cout << \" \";\n                cout << grid[i][j];\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read the next set of seeds (for the next turn)\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                cin >> seeds[i][l];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <climits>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Point& other) const { return !(*this == other); }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// direction encoding: 0: right (0,+1), 1: down (+1,0), 2: left (0,-1), 3: up (-1,0)\nint get_dir(const Point& from, const Point& to) {\n    int dx = to.x - from.x;\n    int dy = to.y - from.y;\n    if (dx == 1 && dy == 0) return 1; // down\n    if (dx == -1 && dy == 0) return 3; // up\n    if (dx == 0 && dy == 1) return 0; // right\n    if (dx == 0 && dy == -1) return 2; // left\n    // not adjacent\n    return -1;\n}\n\n// minimal rotation steps from cur_dir to target_dir (0..3)\nint rot_steps(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 0) return 0;\n    if (diff == 2) return 2;\n    return 1; // diff == 1 or 3\n}\n\n// choose rotation character to go from cur_dir to target_dir in one step (if possible)\nchar rot_char(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 1) return 'R';\n    if (diff == 3) return 'L';\n    return '.'; // no rotation or need two steps (handled separately)\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\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 sources and targets\n    vector<Point> 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.emplace_back(i, j);\n            if (t_grid[i][j] == '1') targets.emplace_back(i, j);\n        }\n    }\n\n    // pair sources and targets greedily\n    vector<bool> used_target(M, false);\n    vector<pair<Point, Point>> pairs;\n    for (const Point& src : sources) {\n        int best_idx = -1;\n        int best_dist = INT_MAX;\n        for (int i = 0; i < M; ++i) {\n            if (used_target[i]) continue;\n            int d = manhattan(src, targets[i]);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        pairs.emplace_back(src, targets[best_idx]);\n        used_target[best_idx] = true;\n    }\n\n    // design tree: star with root 0 and leaves 1..V-1, all length 1\n    cout << V << '\\n';\n    for (int i = 1; i < V; ++i) {\n        cout << 0 << ' ' << 1 << '\\n';\n    }\n\n    // initial root position (choose center for convenience)\n    int init_x = N / 2, init_y = N / 2;\n    cout << init_x << ' ' << init_y << '\\n';\n\n    // simulation state\n    int rx = init_x, ry = init_y;\n    int leaf_dir = 0; // initially right\n    bool leaf_holding = false;\n\n    // track current takoyaki positions (initially all sources)\n    vector<vector<bool>> has_takoyaki(N, vector<bool>(N, false));\n    for (const Point& p : sources) has_takoyaki[p.x][p.y] = true;\n    // track filled targets\n    vector<vector<bool>> target_filled(N, vector<bool>(N, false));\n\n    vector<string> ops;\n\n    // helper to add a turn\n    auto add_turn = [&](char move, int rot_vertex, char rot, int grab_vertex, char grab) {\n        string s(2 * V, '.');\n        s[0] = move;\n        if (rot_vertex != -1) {\n            s[1 + rot_vertex] = rot; // rotation slots start at index 1\n        }\n        if (grab_vertex != -1) {\n            s[V + grab_vertex] = grab; // grab slots start at index V\n        }\n        ops.push_back(s);\n    };\n\n    // process each pair\n    for (const auto& p : pairs) {\n        const Point& src = p.first;\n        const Point& dst = p.second;\n\n        // --- pickup ---\n        // find best neighbor for pickup\n        int best_pick_dist = INT_MAX;\n        int best_pick_rot_diff = INT_MAX;\n        Point best_pick_root;\n        int best_pick_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = src.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = src.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_pick_root = Point(nx, ny);\n                best_pick_dir = dir_from_root;\n            }\n        }\n        // move to best_pick_root\n        int px = best_pick_root.x, py = best_pick_root.y;\n        // generate moves\n        vector<char> moves;\n        while (rx != px) {\n            if (rx > px) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != py) {\n            if (ry > py) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        // execute moves, with rotations as needed\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: also rotate and grab\n                int steps = rot_steps(leaf_dir, best_pick_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_pick_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else { // steps == 2\n                    // first rotation in this move (no grab)\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4); // arbitrary direction\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and grab in next turn\n                    char rot2 = rot_char(leaf_dir, best_pick_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // remove takoyaki from source\n        has_takoyaki[src.x][src.y] = false;\n\n        // --- drop ---\n        // find best neighbor for drop (must be empty target)\n        best_pick_dist = INT_MAX;\n        best_pick_rot_diff = INT_MAX;\n        Point best_drop_root;\n        int best_drop_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = dst.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = dst.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (target_filled[nx][ny]) continue; // cannot land on filled target\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_drop_root = Point(nx, ny);\n                best_drop_dir = dir_from_root;\n            }\n        }\n        // move to best_drop_root\n        int dx = best_drop_root.x, dy = best_drop_root.y;\n        moves.clear();\n        while (rx != dx) {\n            if (rx > dx) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != dy) {\n            if (ry > dy) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: rotate and release\n                int steps = rot_steps(leaf_dir, best_drop_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_drop_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else { // steps == 2\n                    // first rotation\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4);\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and release\n                    char rot2 = rot_char(leaf_dir, best_drop_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // mark target filled\n        target_filled[dst.x][dst.y] = true;\n    }\n\n    // output operations\n    for (const string& s : ops) {\n        cout << s << '\\n';\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_PERIMETER = 400000;\n\nstruct Rectangle {\n    int left, right, top, bottom; // grid indices\n    int net;\n    int x_min, x_max, y_min, y_max;\n\n    Rectangle() : net(0) {}\n    Rectangle(int l, int r, int t, int b, int net_val,\n              const vector<int>& x_start, const vector<int>& x_end,\n              const vector<int>& y_start, const vector<int>& y_end)\n        : left(l), right(r), top(t), bottom(b), net(net_val) {\n        x_min = x_start[left];\n        x_max = x_end[right];\n        y_min = y_start[top];\n        y_max = y_end[bottom];\n    }\n\n    int perimeter() const {\n        int width = x_max - x_min + 1;\n        int height = y_max - y_min + 1;\n        return 2 * (width + height);\n    }\n};\n\nRectangle find_best_rectangle(const vector<vector<int>>& net, int G) {\n    int rows = net.size();\n    int cols = net[0].size();\n\n    // Precompute x and y boundaries for each grid index\n    vector<int> x_start(cols), x_end(cols);\n    for (int j = 0; j < cols; ++j) {\n        x_start[j] = j * G;\n        x_end[j] = (j == cols-1) ? MAX_COORD : (j+1) * G - 1;\n    }\n    vector<int> y_start(rows), y_end(rows);\n    for (int i = 0; i < rows; ++i) {\n        y_start[i] = i * G;\n        y_end[i] = (i == rows-1) ? MAX_COORD : (i+1) * G - 1;\n    }\n\n    // Default: an empty cell with net=0\n    Rectangle best;\n    best.net = 0;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (net[i][j] == 0) {\n                best = Rectangle(j, j, i, i, 0, x_start, x_end, y_start, y_end);\n                break;\n            }\n        }\n        if (best.net == 0) break;\n    }\n\n    // Search for the best rectangle\n    for (int top = 0; top < rows; ++top) {\n        vector<int> col_sum(cols, 0);\n        for (int bottom = top; bottom < rows; ++bottom) {\n            for (int c = 0; c < cols; ++c) {\n                col_sum[c] += net[bottom][c];\n            }\n            // Kadane's algorithm for maximum subarray in col_sum\n            int cur = 0, best_cur = 0;\n            int start = 0, best_start = 0, best_end = -1;\n            for (int c = 0; c < cols; ++c) {\n                if (cur <= 0) {\n                    cur = col_sum[c];\n                    start = c;\n                } else {\n                    cur += col_sum[c];\n                }\n                if (cur > best_cur) {\n                    best_cur = cur;\n                    best_start = start;\n                    best_end = c;\n                }\n            }\n            if (best_end == -1) continue;\n\n            Rectangle candidate(best_start, best_end, top, bottom, best_cur,\n                                x_start, x_end, y_start, y_end);\n            // Check perimeter constraint\n            if (candidate.perimeter() <= MAX_PERIMETER) {\n                if (candidate.net > best.net) {\n                    best = candidate;\n                }\n            }\n        }\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].first >> mackerels[i].second;\n    }\n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].first >> sardines[i].second;\n    }\n\n    // Try a few grid sizes to balance resolution and search cost\n    vector<int> grid_sizes = {500, 1000};\n    Rectangle best_overall;\n    best_overall.net = 0;\n\n    for (int G : grid_sizes) {\n        int rows = (MAX_COORD + G) / G;  // number of cells to cover 0..MAX_COORD\n        int cols = rows;\n\n        vector<vector<int>> count_m(rows, vector<int>(cols, 0));\n        vector<vector<int>> count_s(rows, vector<int>(cols, 0));\n\n        for (auto& p : mackerels) {\n            int x = p.first, y = p.second;\n            int i = x / G;\n            int j = y / G;\n            // Coordinates are within [0, MAX_COORD], so i and j are valid\n            if (i < rows && j < cols) {\n                count_m[i][j]++;\n            }\n        }\n        for (auto& p : sardines) {\n            int x = p.first, y = p.second;\n            int i = x / G;\n            int j = y / G;\n            if (i < rows && j < cols) {\n                count_s[i][j]++;\n            }\n        }\n\n        vector<vector<int>> net(rows, vector<int>(cols));\n        for (int i = 0; i < rows; ++i) {\n            for (int j = 0; j < cols; ++j) {\n                net[i][j] = count_m[i][j] - count_s[i][j];\n            }\n        }\n\n        Rectangle best_rect = find_best_rectangle(net, G);\n        if (best_rect.net > best_overall.net) {\n            best_overall = best_rect;\n        }\n    }\n\n    // Output the polygon (rectangle)\n    cout << \"4\\n\";\n    cout << best_overall.x_min << \" \" << best_overall.y_min << \"\\n\";\n    cout << best_overall.x_max << \" \" << best_overall.y_min << \"\\n\";\n    cout << best_overall.x_max << \" \" << best_overall.y_max << \"\\n\";\n    cout << best_overall.x_min << \" \" << best_overall.y_max << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <map>\n#include <set>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Normal distribution with given mean and stddev, rounded to integer, clamped to [1,1e9]\nint normal_int(double mean, double stddev, mt19937& rng) {\n    normal_distribution<double> dist(mean, stddev);\n    double val = dist(rng);\n    int res = (int)round(val);\n    if (res < 1) res = 1;\n    if (res > 1000000000) res = 1000000000;\n    return res;\n}\n\n// Structure for a placement instruction\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference index or -1\n};\n\n// Simulation state: bounding boxes of placed rectangles\nstruct Rect {\n    double x1, y1, x2, y2;\n};\n\n// Check if two rectangles overlap (allowing touching)\nbool overlap(const Rect& a, const Rect& b) {\n    return (a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1);\n}\n\n// Simulate the placement sequence using estimated dimensions.\n// Returns true if valid (no overlap, all coordinates non-negative).\n// Also returns the bounding box (W, H).\nbool simulate(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est,\n              double& W, double& H, map<int, Rect>& boxes) {\n    boxes.clear();\n    W = 0.0;\n    H = 0.0;\n    set<int> placed;\n    for (const Placement& pl : seq) {\n        int id = pl.p;\n        double w, h;\n        if (pl.r == 0) {\n            w = w_est[id];\n            h = h_est[id];\n        } else {\n            w = h_est[id];\n            h = w_est[id];\n        }\n        Rect r;\n        if (pl.d == 'U') {\n            if (pl.b == -1) {\n                r.x1 = 0.0;\n                r.y1 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x1 = ref.x2;\n                r.y1 = ref.y2;\n            }\n            r.x2 = r.x1 + w;\n            r.y2 = r.y1 + h;\n        } else if (pl.d == 'L') {\n            if (pl.b == -1) {\n                r.x2 = 0.0;\n                r.y2 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x2 = ref.x1;\n                r.y2 = ref.y1;\n            }\n            r.x1 = r.x2 - w;\n            r.y1 = r.y2 - h;\n        } else {\n            return false; // invalid direction\n        }\n        // Check bounds\n        if (r.x1 < 0.0 || r.y1 < 0.0) return false;\n        // Check overlap with existing rectangles\n        for (const auto& kv : boxes) {\n            if (overlap(r, kv.second)) return false;\n        }\n        boxes[id] = r;\n        placed.insert(id);\n        W = max(W, r.x2);\n        H = max(H, r.y2);\n    }\n    return true;\n}\n\n// Greedy packing based on estimated dimensions.\n// Returns a placement sequence.\nvector<Placement> greedy_packing(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, bool randomize = true) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Try all options for rectangle i\n        struct Option {\n            double delta; // increase in W+H\n            Placement pl;\n        };\n        vector<Option> options;\n\n        for (int rot = 0; rot < 2; ++rot) {\n            for (char dir : {'U', 'L'}) {\n                // Try all possible references: -1 and all placed indices\n                vector<int> refs = {-1};\n                for (int idx : placed) refs.push_back(idx);\n                for (int b : refs) {\n                    // Skip invalid combinations: L with b=-1 likely leads to negative coordinates\n                    if (dir == 'L' && b == -1) {\n                        // Only allow if w_est[i] == 0 (impossible) -> skip\n                        continue;\n                    }\n                    Placement pl{ i, rot, dir, b };\n                    // Simulate with this new rectangle appended\n                    vector<Placement> test_seq = seq;\n                    test_seq.push_back(pl);\n                    map<int, Rect> test_boxes;\n                    double newW, newH;\n                    if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                        double delta = (newW + newH) - (curW + curH);\n                        options.push_back({ delta, pl });\n                    }\n                }\n            }\n        }\n        // Consider skipping\n        double skip_penalty = w_est[i] + h_est[i]; // estimated penalty if skipped\n\n        if (options.empty()) {\n            // must skip\n            continue;\n        }\n        // Find option with minimum delta\n        double best_delta = 1e30;\n        for (const auto& opt : options) {\n            if (opt.delta < best_delta) best_delta = opt.delta;\n        }\n        // Collect all options with delta close to best (within 1e-6) to randomize\n        vector<Option> best_options;\n        for (const auto& opt : options) {\n            if (abs(opt.delta - best_delta) < 1e-6) best_options.push_back(opt);\n        }\n        // Choose one randomly if randomize, otherwise the first\n        Option chosen = best_options[0];\n        if (randomize && best_options.size() > 1) {\n            uniform_int_distribution<int> dist(0, best_options.size() - 1);\n            chosen = best_options[dist(rng)];\n        }\n        // Decide to place or skip based on greedy criterion\n        if (best_delta < skip_penalty) {\n            // Place it\n            seq.push_back(chosen.pl);\n            // Update current state by re-simulating from scratch (could be optimized but N is small)\n            simulate(seq, w_est, h_est, curW, curH, current_boxes);\n            placed.insert(i);\n        }\n        // else skip\n    }\n    return seq;\n}\n\n// Mutate a sequence: randomly change one parameter of one placement, or add/remove a rectangle.\n// Returns a new sequence (might be invalid, to be checked by caller)\nvector<Placement> mutate_sequence(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> new_seq = seq;\n    if (new_seq.empty() || uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n        // Try to add a rectangle not yet placed\n        set<int> placed_ids;\n        for (const auto& pl : new_seq) placed_ids.insert(pl.p);\n        vector<int> not_placed;\n        for (int i = 0; i < N; ++i) if (placed_ids.count(i) == 0) not_placed.push_back(i);\n        if (!not_placed.empty()) {\n            int id = not_placed[uniform_int_distribution<int>(0, not_placed.size()-1)(rng)];\n            // Generate random placement for this rectangle\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_int_distribution<int>(0,1)(rng) == 0) ? 'U' : 'L';\n            int b = -1;\n            if (dir == 'L') {\n                // need a reference with positive left edge\n                if (!new_seq.empty()) {\n                    // choose a random placed index as reference\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n                // else b remains -1, but that will likely be invalid, so skip addition\n                if (b == -1) return new_seq; // no change\n            } else {\n                if (!new_seq.empty() && uniform_int_distribution<int>(0,1)(rng) == 0) {\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n            }\n            // Insert in correct order (increasing p)\n            Placement pl{id, rot, dir, b};\n            auto it = lower_bound(new_seq.begin(), new_seq.end(), pl, \n                [](const Placement& a, const Placement& b) { return a.p < b.p; });\n            new_seq.insert(it, pl);\n        }\n    } else if (new_seq.size() < N && uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n        // Try to remove a random rectangle\n        int idx = uniform_int_distribution<int>(0, new_seq.size()-1)(rng);\n        new_seq.erase(new_seq.begin() + idx);\n    } else {\n        // Modify one random placement\n        int idx = uniform_int_distribution<int>(0, new_seq.size()-1)(rng);\n        Placement& pl = new_seq[idx];\n        int choice = uniform_int_distribution<int>(0,2)(rng);\n        if (choice == 0) {\n            // flip rotation\n            pl.r = 1 - pl.r;\n        } else if (choice == 1) {\n            // change direction\n            pl.d = (pl.d == 'U') ? 'L' : 'U';\n            // if direction becomes L and b == -1, set b to some reference (or skip)\n            if (pl.d == 'L' && pl.b == -1 && !new_seq.empty()) {\n                // choose a random earlier placed rectangle as reference\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                }\n                // else keep -1, but likely invalid\n            }\n        } else {\n            // change reference\n            if (pl.b == -1) {\n                // try to set to some earlier placed rectangle\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                }\n            } else {\n                // change to another reference or -1\n                vector<int> candidates = {-1};\n                for (int j = 0; j < idx; ++j) candidates.push_back(new_seq[j].p);\n                pl.b = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(rng)];\n            }\n        }\n    }\n    return new_seq;\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    vector<int> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Convert to double for estimates\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = w_obs[i];\n        h_est[i] = h_obs[i];\n    }\n\n    // Precompute total penalty estimate (using observed values)\n    double total_penalty_est = 0.0;\n    for (int i = 0; i < N; ++i) {\n        total_penalty_est += w_est[i] + h_est[i];\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Placement> best_seq;\n    double best_score = 1e30;\n\n    for (int t = 0; t < T; ++t) {\n        vector<Placement> cur_seq;\n        if (t == 0 || uniform_real_distribution<double>(0,1)(rng) < 0.7) {\n            // Generate a new greedy packing with perturbed estimates\n            vector<double> pert_w = w_est, pert_h = h_est;\n            normal_distribution<double> noise(0.0, sigma * 0.5);\n            for (int i = 0; i < N; ++i) {\n                pert_w[i] += noise(rng);\n                pert_h[i] += noise(rng);\n                // clamp to positive\n                if (pert_w[i] < 1.0) pert_w[i] = 1.0;\n                if (pert_h[i] < 1.0) pert_h[i] = 1.0;\n            }\n            cur_seq = greedy_packing(pert_w, pert_h, rng, true);\n        } else {\n            // Mutate best sequence\n            cur_seq = mutate_sequence(best_seq, w_est, h_est, rng);\n        }\n\n        // Ensure sequence is valid under current estimates; if not, fallback to greedy\n        {\n            map<int, Rect> dummy_boxes;\n            double dummyW, dummyH;\n            if (!simulate(cur_seq, w_est, h_est, dummyW, dummyH, dummy_boxes)) {\n                cur_seq = greedy_packing(w_est, h_est, rng, true);\n            }\n        }\n\n        // Output the sequence\n        cout << cur_seq.size() << '\\n';\n        for (const Placement& pl : cur_seq) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout.flush();\n\n        // Read measurement\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n\n        // Compute observed score\n        set<int> placed_ids;\n        for (const Placement& pl : cur_seq) placed_ids.insert(pl.p);\n        double penalty = 0.0;\n        for (int i = 0; i < N; ++i) {\n            if (placed_ids.count(i) == 0) {\n                penalty += w_est[i] + h_est[i]; // use estimated penalty\n            }\n        }\n        double score = W_meas + H_meas + penalty;\n\n        // Update best\n        if (score < best_score) {\n            best_score = score;\n            best_seq = cur_seq;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // All-pairs shortest distances (BFS from each vertex)\n    vector<vector<short>> dist(N, vector<short>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        queue<int> q;\n        dist[s][s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // cover[v] = bitset of vertices within distance H from v\n    vector<bitset<MAXN>> cover(N);\n    for (int v = 0; v < N; ++v) {\n        for (int u = 0; u < N; ++u) {\n            if (dist[v][u] != -1 && dist[v][u] <= H) {\n                cover[v].set(u);\n            }\n        }\n    }\n\n    // Greedy weighted set cover to select roots (minimize sum of A of roots)\n    bitset<MAXN> uncovered;\n    uncovered.set();\n    vector<int> roots;\n    while (uncovered.any()) {\n        int best = -1;\n        double best_ratio = 1e18;\n        for (int v = 0; v < N; ++v) {\n            bitset<MAXN> cur = cover[v] & uncovered;\n            if (cur.none()) continue;\n            int gain = cur.count();\n            double ratio = (double)A[v] / gain;\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best = v;\n            }\n        }\n        if (best == -1) break;   // should never happen\n        roots.push_back(best);\n        uncovered &= ~cover[best];\n    }\n\n    // Assign each vertex to the nearest root (break ties arbitrarily)\n    vector<int> root_of(N, -1);\n    vector<int> dist_to_root(N, 1000);\n    for (int v = 0; v < N; ++v) {\n        int best_r = -1, best_d = 1000;\n        for (int r : roots) {\n            int d = dist[v][r];\n            if (d < best_d) {\n                best_d = d;\n                best_r = r;\n            }\n        }\n        root_of[v] = best_r;\n        dist_to_root[v] = best_d;\n    }\n\n    // Build the parent array (forest)\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (root_of[v] == v) {\n            parent[v] = -1;\n            continue;\n        }\n        int r = root_of[v];\n        int d = dist_to_root[v];\n        bool found = false;\n        for (int u : adj[v]) {\n            if (root_of[u] == r && dist[u][r] == d - 1) {\n                parent[v] = u;\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            // Fallback: any neighbor with same root and smaller distance\n            for (int u : adj[v]) {\n                if (root_of[u] == r && dist[u][r] < d) {\n                    parent[v] = u;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i];\n        if (i < N - 1) cout << ' ';\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<pair<char, int>> moves;\n\n    // Helper functions to perform a single shift and record the move\n    auto shiftRowLeft = [&](int i) {\n        // Remove the leftmost piece\n        char removed = board[i][0]; // not used\n        for (int j = 0; j < N - 1; ++j) {\n            board[i][j] = board[i][j + 1];\n        }\n        board[i][N - 1] = '.';\n        moves.push_back({'L', i});\n    };\n\n    auto shiftRowRight = [&](int i) {\n        char removed = board[i][N - 1];\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n        moves.push_back({'R', i});\n    };\n\n    auto shiftColUp = [&](int j) {\n        char removed = board[0][j];\n        for (int i = 0; i < N - 1; ++i) {\n            board[i][j] = board[i + 1][j];\n        }\n        board[N - 1][j] = '.';\n        moves.push_back({'U', j});\n    };\n\n    auto shiftColDown = [&](int j) {\n        char removed = board[N - 1][j];\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n        moves.push_back({'D', j});\n    };\n\n    while (true) {\n        // Collect all current Oni positions\n        vector<pair<int, int>> oniList;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    oniList.emplace_back(i, j);\n                }\n            }\n        }\n        if (oniList.empty()) {\n            break;\n        }\n\n        // Find the best Oni and direction to remove it with fewest shifts\n        int bestIdx = -1;\n        char bestDir = ' ';\n        int bestShifts = 1e9;\n\n        for (size_t idx = 0; idx < oniList.size(); ++idx) {\n            auto [i, j] = oniList[idx];\n\n            // Check safety in each direction\n            bool safeUp = true;\n            for (int r = 0; r < i; ++r) {\n                if (board[r][j] == 'o') safeUp = false;\n            }\n            bool safeDown = true;\n            for (int r = i + 1; r < N; ++r) {\n                if (board[r][j] == 'o') safeDown = false;\n            }\n            bool safeLeft = true;\n            for (int c = 0; c < j; ++c) {\n                if (board[i][c] == 'o') safeLeft = false;\n            }\n            bool safeRight = true;\n            for (int c = j + 1; c < N; ++c) {\n                if (board[i][c] == 'o') safeRight = false;\n            }\n\n            // Evaluate each safe direction\n            if (safeUp) {\n                int shifts = i + 1;\n                if (shifts < bestShifts) {\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'U';\n                }\n            }\n            if (safeDown) {\n                int shifts = N - i;\n                if (shifts < bestShifts) {\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'D';\n                }\n            }\n            if (safeLeft) {\n                int shifts = j + 1;\n                if (shifts < bestShifts) {\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'L';\n                }\n            }\n            if (safeRight) {\n                int shifts = N - j;\n                if (shifts < bestShifts) {\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'R';\n                }\n            }\n        }\n\n        // According to the problem guarantee, there should always be a safe direction.\n        // If not, break to avoid infinite loop (should not happen).\n        if (bestIdx == -1) {\n            break;\n        }\n\n        auto [i, j] = oniList[bestIdx];\n\n        // Perform the shifts in the chosen direction\n        if (bestDir == 'U') {\n            for (int k = 0; k < i + 1; ++k) {\n                shiftColUp(j);\n            }\n        } else if (bestDir == 'D') {\n            for (int k = 0; k < N - i; ++k) {\n                shiftColDown(j);\n            }\n        } else if (bestDir == 'L') {\n            for (int k = 0; k < j + 1; ++k) {\n                shiftRowLeft(i);\n            }\n        } else if (bestDir == 'R') {\n            for (int k = 0; k < N - j; ++k) {\n                shiftRowRight(i);\n            }\n        }\n    }\n\n    // Output the moves\n    for (auto [d, p] : moves) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Dinic's max flow\nstruct Edge {\n    int to, rev;\n    long long cap;\n};\n\nclass Dinic {\npublic:\n    vector<vector<Edge>> graph;\n    vector<int> level, iter;\n    Dinic(int n) : graph(n), level(n), iter(n) {}\n    void add_edge(int from, int to, long long cap) {\n        graph[from].push_back({to, (int)graph[to].size(), cap});\n        graph[to].push_back({from, (int)graph[from].size() - 1, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto& e : graph[v]) {\n                if (e.cap > 0 && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    long long dfs(int v, int t, long long f) {\n        if (v == t) return f;\n        for (int& i = iter[v]; i < (int)graph[v].size(); ++i) {\n            Edge& e = graph[v][i];\n            if (e.cap > 0 && level[v] < level[e.to]) {\n                long long d = dfs(e.to, t, min(f, e.cap));\n                if (d > 0) {\n                    e.cap -= d;\n                    graph[e.to][e.rev].cap += d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    long long max_flow(int s, int t) {\n        long long flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            long long f;\n            while ((f = dfs(s, t, 1e18)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\nint main() {\n    const int N = 100;\n    const long long L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Build flow network\n    int source = 0;\n    int left_start = 1;                     // 1 .. 200\n    int right_start = left_start + 2 * N;   // 201 .. 300\n    int sink = right_start + N;             // 301\n    Dinic dinic(sink + 1);\n\n    // Source to left nodes (two per employee)\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n        dinic.add_edge(source, node1, T[i]);\n        dinic.add_edge(source, node2, T[i]);\n    }\n\n    // Right nodes to sink\n    for (int j = 0; j < N; ++j) {\n        int node = right_start + j;\n        dinic.add_edge(node, sink, 2 * T[j]);\n    }\n\n    // Left nodes to right nodes (infinite capacity)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node1 = left_start + 2 * i;\n            int node2 = left_start + 2 * i + 1;\n            int right_node = right_start + j;\n            dinic.add_edge(node1, right_node, L);\n            dinic.add_edge(node2, right_node, L);\n        }\n    }\n\n    // Compute max flow\n    long long flow = dinic.max_flow(source, sink);\n    // flow should be 2*L\n\n    // Extract a[i] and b[i] by rounding to the dominant assignment\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n\n        // Find best j for node1\n        long long max_fl1 = -1;\n        int best_j1 = 0;\n        for (auto& e : dinic.graph[node1]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;  // flow sent = initial cap - residual\n                if (fl > max_fl1) {\n                    max_fl1 = fl;\n                    best_j1 = e.to - right_start;\n                }\n            }\n        }\n        a[i] = best_j1;\n\n        // Find best j for node2\n        long long max_fl2 = -1;\n        int best_j2 = 0;\n        for (auto& e : dinic.graph[node2]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl2) {\n                    max_fl2 = fl;\n                    best_j2 = e.to - right_start;\n                }\n            }\n        }\n        b[i] = best_j2;\n    }\n\n    // Simulate the cleaning process\n    vector<int> cnt(N, 0);\n    int current = 0;\n    cnt[current] = 1;  // first week\n    for (long long week = 2; week <= L; ++week) {\n        if (cnt[current] % 2 == 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        cnt[current]++;\n    }\n\n    // Compute error (just for internal check, not output)\n    long long error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(cnt[i] - T[i]);\n    }\n    // Optionally, one could perform local improvements here.\n\n    // Output the solution\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int, int>;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\n\nvector<vector<int>> groups;\nvector<vector<pii>> group_edges;\n\n// Perform a fortune\u2011telling query.\nvector<pii> query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    vector<pii> edges;\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    vector<int> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        // integer center (floor of average)\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Sort cities by their center coordinates (x then y).\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n\n    // Partition the sorted list into groups according to G.\n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n\n    int total_queries = 0;\n    for (int i = 0; i < M; ++i) {\n        int s = groups[i].size();\n        if (s == 1) continue;                     // no edges needed\n        if (s <= L) {\n            // whole group fits in one query\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n            ++total_queries;\n        } else {\n            // sliding windows of size L, overlapping by one city.\n            int start = 0;\n            while (start < s) {\n                int end = min(start + L, s);\n                int window_size = end - start;\n                if (window_size >= 2) {\n                    vector<int> window(groups[i].begin() + start, groups[i].begin() + end);\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                    ++total_queries;\n                }\n                // next window starts L-1 positions later \u2192 overlap of exactly one city\n                start += L - 1;\n            }\n        }\n        // safety check (should never trigger because total_queries \u2264 400)\n        if (total_queries > Q) break;\n    }\n\n    // Output the answer.\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // city list of the group\n        for (size_t j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> points(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n\n    pair<int, int> cur = points[0];\n    vector<pair<int, int>> targets(points.begin() + 1, points.end());\n    vector<string> actions;\n\n    // Directions for moves: down, up, right, left\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n    const string dir_name[4] = {\"D\", \"U\", \"R\", \"L\"};\n\n    for (size_t k = 0; k < targets.size(); ++k) {\n        auto [ti, tj] = targets[k];\n\n        // Slide optimization: if aligned and target on boundary\n        if (cur.first == ti) {\n            if (tj == 0) {\n                // slide left\n                actions.push_back(\"S L\");\n                cur.second = tj;\n                continue;\n            } else if (tj == N - 1) {\n                // slide right\n                actions.push_back(\"S R\");\n                cur.second = tj;\n                continue;\n            }\n        } else if (cur.second == tj) {\n            if (ti == 0) {\n                // slide up\n                actions.push_back(\"S U\");\n                cur.first = ti;\n                continue;\n            } else if (ti == N - 1) {\n                // slide down\n                actions.push_back(\"S D\");\n                cur.first = ti;\n                continue;\n            }\n        }\n\n        // Otherwise, find shortest path avoiding future targets using BFS\n        // Build blocked cells: all targets with index > k\n        vector<vector<bool>> blocked(N, vector<bool>(N, false));\n        for (size_t i = k + 1; i < targets.size(); ++i) {\n            int x = targets[i].first, y = targets[i].second;\n            blocked[x][y] = true;\n        }\n\n        // BFS from cur to (ti, tj)\n        vector<vector<int>> prev_x(N, vector<int>(N, -1));\n        vector<vector<int>> prev_y(N, vector<int>(N, -1));\n        vector<vector<int>> dir_idx(N, vector<int>(N, -1));\n        queue<pair<int, int>> q;\n        q.push(cur);\n        prev_x[cur.first][cur.second] = cur.first; // mark visited\n        prev_y[cur.first][cur.second] = cur.second;\n\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            if (x == ti && y == tj) break;\n\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                if (blocked[nx][ny]) continue;\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                dir_idx[nx][ny] = d;\n                q.push({nx, ny});\n            }\n        }\n\n        // Reconstruct path\n        vector<string> path_actions;\n        int x = ti, y = tj;\n        while (x != cur.first || y != cur.second) {\n            int d = dir_idx[x][y];\n            path_actions.push_back(\"M \" + dir_name[d]);\n            int px = prev_x[x][y];\n            int py = prev_y[x][y];\n            x = px;\n            y = py;\n        }\n        reverse(path_actions.begin(), path_actions.end());\n\n        for (const string& a : path_actions) {\n            actions.push_back(a);\n        }\n\n        cur = {ti, tj};\n    }\n\n    // Output actions\n    for (const string& a : actions) {\n        cout << a << \"\\n\";\n    }\n\n    return 0;\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r, idx;\n};\n\nint main() {\n    int n;\n    cin >> n;\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].idx = i;\n    }\n\n    // sort by x coordinate\n    sort(companies.begin(), companies.end(),\n         [](const Company& a, const Company& b) { return a.x < b.x; });\n\n    // extract sorted data\n    vector<int> xs(n), ys(n), rs(n);\n    for (int i = 0; i < n; ++i) {\n        xs[i] = companies[i].x;\n        ys[i] = companies[i].y;\n        rs[i] = companies[i].r;\n    }\n\n    // precompute satisfaction for each possible width (1..10000) for each company\n    vector<vector<double>> sat(n, vector<double>(10001, 0.0));\n    for (int i = 0; i < n; ++i) {\n        long long r = rs[i];\n        for (int w = 1; w <= 10000; ++w) {\n            // height = round(r / w) clamped to [1, 10000]\n            long long h = (r + w / 2) / w;  // integer rounding\n            if (h > 10000) h = 10000;\n            if (h < 1) h = 1;\n            long long s = w * h;\n            double ratio = min(r, s) / (double)max(r, s);\n            sat[i][w] = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        }\n    }\n\n    // initial widths: must cover xi and be at least ceil(r/10000)\n    vector<int> w(n);\n    long long cur_start = 0;\n    for (int i = 0; i < n; ++i) {\n        long long w_min_cov = max(1LL, (long long)xs[i] - cur_start + 1);\n        long long w_min_area = (rs[i] + 9999) / 10000; // ceil(r/10000)\n        w[i] = max(w_min_cov, w_min_area);\n        cur_start += w[i];\n    }\n\n    long long total_width = cur_start;\n    long long excess = total_width - 10000;\n\n    // reduce widths if total exceeds 10000\n    while (excess > 0) {\n        // recompute current starts\n        vector<long long> start_pos(n);\n        cur_start = 0;\n        for (int i = 0; i < n; ++i) {\n            start_pos[i] = cur_start;\n            cur_start += w[i];\n        }\n\n        int best_i = -1;\n        double best_loss = 1e18;\n        for (int i = 0; i < n; ++i) {\n            long long w_min_cov = max(1LL, (long long)xs[i] - start_pos[i] + 1);\n            if (w[i] <= w_min_cov) continue; // cannot reduce without losing point\n            double p_curr = sat[i][w[i]];\n            double p_red = sat[i][w[i] - 1];\n            double loss = p_curr - p_red;\n            if (loss < best_loss) {\n                best_loss = loss;\n                best_i = i;\n            }\n        }\n        if (best_i == -1) break; // no reduction possible\n        w[best_i]--;\n        excess--;\n    }\n\n    // compute final heights and output rectangles\n    vector<int> a(n), b(n), c(n), d(n);\n    cur_start = 0;\n    for (int i = 0; i < n; ++i) {\n        int wi = w[i];\n        long long h = (rs[i] + wi / 2) / wi;\n        if (h > 10000) h = 10000;\n        if (h < 1) h = 1;\n        int ai = cur_start;\n        int ci = ai + wi;\n        int bi = max(0, ys[i] - (int)h + 1);\n        int di = bi + (int)h;\n\n        // store in original order\n        int idx = companies[i].idx;\n        a[idx] = ai;\n        b[idx] = bi;\n        c[idx] = ci;\n        d[idx] = di;\n\n        cur_start += wi;\n    }\n\n    // output\n    for (int i = 0; i < n; ++i) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <random>\n#include <tuple>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> tile(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tile[i][j];\n        }\n    }\n\n    vector<vector<int>> value(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> value[i][j];\n        }\n    }\n\n    // Find total number of tiles (M)\n    int M = 0;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            M = max(M, tile[i][j] + 1);\n        }\n    }\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n    // Timestamp technique to avoid resetting visited array each trial\n    vector<int> visited_tiles(M, 0);\n    int cur_timestamp = 0;\n\n    random_device rd;\n    mt19937 gen(rd());\n\n    string best_path = \"\";\n    int best_score = -1;\n\n    const int num_trials = 20000; // will be plus one greedy trial\n    for (int trial = 0; trial <= num_trials; ++trial) {\n        ++cur_timestamp;\n        int policy; // 0: uniform random, 1: weighted random, 2: greedy\n        if (trial == num_trials) {\n            policy = 2; // greedy at the end\n        } else {\n            policy = (gen() % 2); // 50% uniform, 50% weighted\n        }\n\n        int cur_r = si, cur_c = sj;\n        visited_tiles[tile[cur_r][cur_c]] = cur_timestamp;\n        int score = value[cur_r][cur_c];\n        string path = \"\";\n\n        while (true) {\n            // Collect unvisited neighbors\n            // Fixed: Changed to tuple with 5 elements to match emplace_back\n            vector<tuple<int, int, int, int, char>> candidates; // value, nr, nc, tid, dir\n            for (int d = 0; d < 4; ++d) {\n                int nr = cur_r + dr[d];\n                int nc = cur_c + dc[d];\n                if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n                int tid = tile[nr][nc];\n                if (visited_tiles[tid] == cur_timestamp) continue;\n                candidates.emplace_back(value[nr][nc], nr, nc, tid, dir_char[d]);\n            }\n            if (candidates.empty()) break;\n\n            int chosen_idx = 0;\n            if (policy == 2) {\n                // Greedy: choose the candidate with maximum value\n                for (int i = 1; i < (int)candidates.size(); ++i) {\n                    if (get<0>(candidates[i]) > get<0>(candidates[chosen_idx])) {\n                        chosen_idx = i;\n                    }\n                }\n            } else {\n                if (policy == 0) {\n                    // Uniform random\n                    chosen_idx = gen() % candidates.size();\n                } else {\n                    // Weighted random (weights = value)\n                    int total = 0;\n                    for (const auto& cand : candidates) {\n                        total += get<0>(cand);\n                    }\n                    if (total == 0) {\n                        chosen_idx = gen() % candidates.size();\n                    } else {\n                        int r = gen() % total;\n                        int cum = 0;\n                        for (int i = 0; i < (int)candidates.size(); ++i) {\n                            cum += get<0>(candidates[i]);\n                            if (cum > r) {\n                                chosen_idx = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Execute the chosen move\n            // Fixed: Updated structured binding to match 5-element tuple\n            auto [val, nr, nc, tid, dir] = candidates[chosen_idx];\n            path += dir;\n            cur_r = nr;\n            cur_c = nc;\n            visited_tiles[tid] = cur_timestamp;\n            score += val;\n        }\n\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n        }\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    const int N = 30;\n    vector<vector<double>> est_h(N, vector<double>(N-1, 5000.0)); // horizontal edges\n    vector<vector<double>> est_v(N-1, vector<double>(N, 5000.0)); // vertical edges\n\n    double lr = 0.1;                     // learning rate\n    int total_updates = 0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        int start = si * N + sj;\n        int target = ti * N + tj;\n\n        // ---------- Dijkstra ----------\n        const double INF = 1e18;\n        vector<double> dist(N * N, INF);\n        vector<int> prev(N * N, -1);\n        vector<char> prev_move(N * N); // direction that led to this node\n\n        dist[start] = 0.0;\n        priority_queue<pair<double, int>,\n                       vector<pair<double, int>>,\n                       greater<pair<double, int>>> pq;\n        pq.emplace(0.0, start);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            int ui = u / N, uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = (ui - 1) * N + uj;\n                double w = est_v[ui - 1][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'U';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // down\n            if (ui < N - 1) {\n                int v = (ui + 1) * N + uj;\n                double w = est_v[ui][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'D';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = ui * N + (uj - 1);\n                double w = est_h[ui][uj - 1];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'L';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // right\n            if (uj < N - 1) {\n                int v = ui * N + (uj + 1);\n                double w = est_h[ui][uj];\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'R';\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        // ---------- Reconstruct path ----------\n        vector<char> moves;\n        struct Edge { bool hor; int i; int j; };\n        vector<Edge> path_edges;\n\n        int cur = target;\n        while (cur != start) {\n            int p = prev[cur];\n            char dir = prev_move[cur];\n            moves.push_back(dir);\n\n            int pi = p / N, pj = p % N;\n            int ci = cur / N, cj = cur % N;\n\n            if (pi == ci) { // horizontal move\n                int j = min(pj, cj);\n                path_edges.push_back({true, pi, j});\n            } else { // vertical move\n                int i = min(pi, ci);\n                path_edges.push_back({false, i, pj});\n            }\n            cur = p;\n        }\n        reverse(moves.begin(), moves.end());\n        reverse(path_edges.begin(), path_edges.end());\n\n        // ---------- Output ----------\n        for (char c : moves) cout << c;\n        cout << endl;\n\n        // ---------- Read feedback ----------\n        int res;\n        cin >> res;\n\n        // ---------- Compute predicted length ----------\n        double L_est = 0.0;\n        for (auto& e : path_edges) {\n            if (e.hor) L_est += est_h[e.i][e.j];\n            else       L_est += est_v[e.i][e.j];\n        }\n        int len = path_edges.size();\n        double delta = lr * (res - L_est) / len;\n\n        // ---------- Update estimates ----------\n        for (auto& e : path_edges) {\n            if (e.hor) {\n                est_h[e.i][e.j] += delta;\n                est_h[e.i][e.j] = max(1000.0, min(9000.0, est_h[e.i][e.j]));\n            } else {\n                est_v[e.i][e.j] += delta;\n                est_v[e.i][e.j] = max(1000.0, min(9000.0, est_v[e.i][e.j]));\n            }\n        }\n\n        total_updates += len;\n        lr *= 0.999;   // decay learning rate\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int BASE = 131;\n\nstruct SubInfo {\n    int start;\n    int k;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n    \n    // Hash each string\n    auto compute_hash_string = [](const string &s) -> uint64_t {\n        uint64_t h = 0;\n        for (char ch : s) {\n            h = h * BASE + (ch - 'A' + 1);\n        }\n        return h;\n    };\n    vector<uint64_t> str_hash(M);\n    unordered_map<uint64_t, int> hash_to_str;\n    for (int i = 0; i < M; ++i) {\n        str_hash[i] = compute_hash_string(strs[i]);\n        hash_to_str[str_hash[i]] = i;\n    }\n    \n    // Precompute for each cell the list of row/column substrings that contain it\n    vector<vector<SubInfo>> cell_row_info(N * N);\n    vector<vector<SubInfo>> cell_col_info(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cell = r * N + c;\n            for (int k = 2; k <= 12; ++k) {\n                // row substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (c >= s && c < s + k) in = true;\n                    } else {\n                        if (c >= s || c < (s + k) % N) in = true;\n                    }\n                    if (in) cell_row_info[cell].push_back({s, k});\n                }\n                // column substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (r >= s && r < s + k) in = true;\n                    } else {\n                        if (r >= s || r < (s + k) % N) in = true;\n                    }\n                    if (in) cell_col_info[cell].push_back({s, k});\n                }\n            }\n        }\n    }\n    \n    // Initialize random grid\n    vector<vector<char>> grid(N, vector<char>(N));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_letter(0, 7);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + dist_letter(rng);\n        }\n    }\n    \n    // Helper functions for row/column hash using the current grid\n    auto compute_hash_row = [&](int r, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int col = (start + i) % N;\n            h = h * BASE + (grid[r][col] - 'A' + 1);\n        }\n        return h;\n    };\n    auto compute_hash_col = [&](int c, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int row = (start + i) % N;\n            h = h * BASE + (grid[row][c] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    // Initialize count map for all substring hashes\n    unordered_map<uint64_t, int> cnt;\n    for (int r = 0; r < N; ++r) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_row(r, s, k)]++;\n            }\n        }\n    }\n    for (int c = 0; c < N; ++c) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_col(c, s, k)]++;\n            }\n        }\n    }\n    \n    // Initial satisfaction\n    vector<bool> satisfied(M, false);\n    int c_sat = 0;\n    for (int i = 0; i < M; ++i) {\n        if (cnt[str_hash[i]] > 0) {\n            satisfied[i] = true;\n            ++c_sat;\n        }\n    }\n    \n    // Simulated annealing parameters\n    const int iterations = 200000;\n    double temp = 10.0;\n    const double cooling = 0.99995;\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    uniform_int_distribution<int> dist_cell(0, N - 1);\n    uniform_int_distribution<int> dist_newchar(0, 7);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int r = dist_cell(rng);\n        int col = dist_cell(rng);\n        int cell = r * N + col;\n        char old_char = grid[r][col];\n        char new_char = 'A' + dist_newchar(rng);\n        if (new_char == old_char) continue;\n        \n        // Collect old hashes for row and column substrings through this cell\n        vector<uint64_t> old_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            old_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            old_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        \n        // Temporarily change the cell to compute new hashes\n        grid[r][col] = new_char;\n        vector<uint64_t> new_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            new_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            new_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        grid[r][col] = old_char;  // revert\n        \n        // Compute net changes in hash counts\n        unordered_map<uint64_t, int> delta_count;\n        for (size_t i = 0; i < old_hashes.size(); ++i) {\n            if (old_hashes[i] != new_hashes[i]) {\n                delta_count[old_hashes[i]]--;\n                delta_count[new_hashes[i]]++;\n            }\n        }\n        \n        // Estimate change in number of satisfied strings\n        int delta_c = 0;\n        for (auto &[hash, d] : delta_count) {\n            int old_cnt = cnt[hash];\n            int new_cnt = old_cnt + d;\n            if (old_cnt == 0 && new_cnt > 0) delta_c++;\n            if (old_cnt > 0 && new_cnt == 0) delta_c--;\n        }\n        \n        // Acceptance probability\n        bool accept = false;\n        if (delta_c > 0) {\n            accept = true;\n        } else if (temp > 1e-6) {\n            double prob = exp(delta_c / temp);\n            if (prob > dist_real(rng)) accept = true;\n        }\n        \n        if (accept) {\n            grid[r][col] = new_char;\n            for (auto &[hash, d] : delta_count) {\n                int old_cnt = cnt[hash];\n                cnt[hash] = old_cnt + d;\n                if (old_cnt == 0 && cnt[hash] > 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = true;\n                        ++c_sat;\n                    }\n                }\n                if (old_cnt > 0 && cnt[hash] == 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = false;\n                        --c_sat;\n                    }\n                }\n            }\n        }\n        \n        temp *= cooling;\n        if (c_sat == M) break;  // early exit if all satisfied\n    }\n    \n    // Output the matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n};\n\n// Hopcroft\u2013Karp for bipartite matching\nint hopcroft_karp(const vector<vector<int>>& adj, int L, int R,\n                  vector<int>& matchL, vector<int>& matchR) {\n    vector<int> dist(L, -1);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            dist[u] = 0;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (matchR[v] != -1 && dist[matchR[v]] == -1) {\n                dist[matchR[v]] = dist[u] + 1;\n                q.push(matchR[v]);\n            }\n        }\n    }\n    function<bool(int)> dfs = [&](int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 ||\n                (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n    int matching = 0;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1 && dfs(u)) ++matching;\n    }\n    return matching;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; ++i) cin >> grid_str[i];\n\n    // Convert grid: -1 for obstacle, otherwise cost (5-9)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Point> roads;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid_str[i][j];\n            if (c != '#') {\n                grid[i][j] = c - '0';\n                roads.push_back({i, j});\n            }\n        }\n    }\n\n    // ---------- row segments ----------\n    vector<vector<int>> row_seg(N, vector<int>(N, -1));\n    int L = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != -1) {\n                int start = j;\n                while (j < N && grid[i][j] != -1) ++j;\n                int end = j - 1;\n                for (int k = start; k <= end; ++k) row_seg[i][k] = L;\n                ++L;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ---------- column segments ----------\n    vector<vector<int>> col_seg(N, vector<int>(N, -1));\n    int R = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != -1) {\n                int start = i;\n                while (i < N && grid[i][j] != -1) ++i;\n                int end = i - 1;\n                for (int k = start; k <= end; ++k) col_seg[k][j] = R;\n                ++R;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ---------- bipartite graph (row segments vs column segments) ----------\n    vector<vector<int>> adj(L);\n    vector<vector<pair<int, Point>>> edge_coord(L); // for each row segment: (col_segment, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        adj[u].push_back(v);\n        edge_coord[u].push_back({v, {p.i, p.j}});\n    }\n\n    // ---------- minimum vertex cover (via maximum matching) ----------\n    vector<int> matchL(L, -1), matchR(R, -1);\n    hopcroft_karp(adj, L, R, matchL, matchR);\n\n    vector<bool> visL(L, false), visR(R, false);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            visL[u] = true;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (!visR[v]) {\n                visR[v] = true;\n                if (matchR[v] != -1 && !visL[matchR[v]]) {\n                    visL[matchR[v]] = true;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n    }\n    vector<bool> selected_row(L, false), selected_col(R, false);\n    for (int u = 0; u < L; ++u) selected_row[u] = !visL[u];\n    for (int v = 0; v < R; ++v) selected_col[v] = visR[v];\n\n    // ---------- selected segments ----------\n    vector<int> sel_row_list, sel_col_list;\n    for (int u = 0; u < L; ++u) if (selected_row[u]) sel_row_list.push_back(u);\n    for (int v = 0; v < R; ++v) if (selected_col[v]) sel_col_list.push_back(v);\n    int L2 = sel_row_list.size(), R2 = sel_col_list.size();\n    map<int, int> row_idx, col_idx;\n    for (int i = 0; i < L2; ++i) row_idx[sel_row_list[i]] = i;\n    for (int i = 0; i < R2; ++i) col_idx[sel_col_list[i]] = i;\n\n    // ---------- induced graph on selected segments ----------\n    vector<vector<int>> adj2(L2);\n    vector<vector<int>> radj2(R2);\n    vector<vector<pair<int, Point>>> edge_coord2(L2); // (col_idx, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        if (selected_row[u] && selected_col[v]) {\n            int u2 = row_idx[u];\n            int v2 = col_idx[v];\n            adj2[u2].push_back(v2);\n            radj2[v2].push_back(u2);\n            edge_coord2[u2].push_back({v2, {p.i, p.j}});\n        }\n    }\n\n    // ---------- minimum edge cover on induced graph ----------\n    vector<int> matchL2(L2, -1), matchR2(R2, -1);\n    hopcroft_karp(adj2, L2, R2, matchL2, matchR2);\n\n    vector<Point> S; // squares to visit\n    vector<bool> row_covered(L2, false), col_covered(R2, false);\n\n    // 1. take all matching edges\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (matchL2[u2] != -1) {\n            int v2 = matchL2[u2];\n            for (auto& e : edge_coord2[u2]) {\n                if (e.first == v2) {\n                    S.push_back(e.second);\n                    break;\n                }\n            }\n            row_covered[u2] = true;\n            col_covered[v2] = true;\n        }\n    }\n\n    // 2. cover unmatched rows\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (!row_covered[u2]) {\n            if (!adj2[u2].empty()) {\n                int v2 = adj2[u2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n                col_covered[v2] = true;\n            } else { // isolated row segment\n                int u_orig = sel_row_list[u2];\n                for (auto& p : roads) {\n                    if (row_seg[p.i][p.j] == u_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n            }\n        }\n    }\n\n    // 3. cover unmatched columns\n    for (int v2 = 0; v2 < R2; ++v2) {\n        if (!col_covered[v2]) {\n            if (!radj2[v2].empty()) {\n                int u2 = radj2[v2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            } else { // isolated column segment\n                int v_orig = sel_col_list[v2];\n                for (auto& p : roads) {\n                    if (col_seg[p.i][p.j] == v_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            }\n        }\n    }\n\n    // ---------- nodes for TSP (start + S without duplicates) ----------\n    vector<Point> nodes;\n    nodes.push_back({si, sj});\n    set<pair<int, int>> visited_set;\n    for (auto& p : S) {\n        if (p.i == si && p.j == sj) continue;\n        if (visited_set.insert({p.i, p.j}).second) {\n            nodes.push_back(p);\n        }\n    }\n    int n = nodes.size();\n\n    // ---------- Dijkstra from each node, build distance matrix and predecessors ----------\n    const int INF = 1e9;\n    vector<vector<int>> dist_mat(n, vector<int>(n, INF));\n    vector<vector<vector<char>>> pred(n, vector<vector<char>>(N, vector<char>(N, 0)));\n\n    auto dijkstra = [&](int src_idx) {\n        int si = nodes[src_idx].i, sj = nodes[src_idx].j;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        dist[si][sj] = 0;\n        pred[src_idx][si][sj] = 0; // 0 marks the source\n        priority_queue<pair<int, pair<int, int>>,\n                       vector<pair<int, pair<int, int>>>,\n                       greater<>> pq;\n        pq.push({0, {si, sj}});\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dir[4] = {'U', 'D', 'L', 'R'};\n        while (!pq.empty()) {\n            auto [d, pos] = pq.top(); pq.pop();\n            int i = pos.first, j = pos.second;\n            if (d != dist[i][j]) continue;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid[ni][nj] == -1) continue;\n                int nd = d + grid[ni][nj];\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    pred[src_idx][ni][nj] = dir[k];\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n        for (int t = 0; t < n; ++t) {\n            int ti = nodes[t].i, tj = nodes[t].j;\n            dist_mat[src_idx][t] = dist[ti][tj];\n        }\n    };\n    for (int s = 0; s < n; ++s) dijkstra(s);\n\n    // ---------- TSP heuristic (nearest neighbour + 2\u2011opt) ----------\n    vector<int> tour;\n    vector<bool> vis(n, false);\n    tour.push_back(0); // start at index 0\n    vis[0] = true;\n    int cur = 0;\n    for (int iter = 0; iter < n - 1; ++iter) {\n        int nxt = -1, best = INF;\n        for (int v = 0; v < n; ++v) {\n            if (!vis[v] && dist_mat[cur][v] < best) {\n                best = dist_mat[cur][v];\n                nxt = v;\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = true;\n        cur = nxt;\n    }\n    tour.push_back(0); // return to start\n\n    // 2\u2011opt\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 0; i < sz - 2; ++i) {\n            for (int j = i + 2; j < sz - 1; ++j) {\n                int a = tour[i], b = tour[i+1], c = tour[j], d = tour[j+1];\n                int cur_cost = dist_mat[a][b] + dist_mat[c][d];\n                // cost of original segment b->...->c\n                int seg_orig = 0;\n                for (int k = i+1; k < j; ++k) seg_orig += dist_mat[tour[k]][tour[k+1]];\n                // new cost if we reverse segment i+1..j\n                int new_cost = dist_mat[a][c] + dist_mat[b][d];\n                int seg_rev = 0;\n                for (int k = j; k > i+1; --k) seg_rev += dist_mat[tour[k]][tour[k-1]];\n                if (cur_cost + seg_orig > new_cost + seg_rev) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // ---------- build move string ----------\n    string moves;\n    for (int idx = 0; idx < (int)tour.size() - 1; ++idx) {\n        int src_idx = tour[idx];\n        int tgt_idx = tour[idx+1];\n        int ci = nodes[tgt_idx].i, cj = nodes[tgt_idx].j;\n        vector<char> path;\n        while (!(ci == nodes[src_idx].i && cj == nodes[src_idx].j)) {\n            char d = pred[src_idx][ci][cj];\n            path.push_back(d);\n            // move to parent\n            if (d == 'U') ci++;\n            else if (d == 'D') ci--;\n            else if (d == 'L') cj++;\n            else if (d == 'R') cj--;\n        }\n        reverse(path.begin(), path.end());\n        for (char c : path) moves.push_back(c);\n    }\n\n    cout << moves << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            cin >> d[i][k];\n        }\n    }\n\n    vector<vector<int>> children(N);\n    vector<int> prereq_count(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        prereq_count[v]++;\n    }\n\n    // Critical path length L[i]\n    vector<int> L(N, 1);\n    for (int i = N - 1; i >= 0; --i) {\n        for (int v : children[i]) {\n            L[i] = max(L[i], 1 + L[v]);\n        }\n    }\n\n    // Available tasks (prerequisites satisfied)\n    vector<int> avail;\n    for (int i = 0; i < N; ++i) {\n        if (prereq_count[i] == 0) {\n            avail.push_back(i);\n        }\n    }\n\n    // Task status: 0=not started, 1=started, 2=completed\n    vector<int> task_status(N, 0);\n\n    // Team member state\n    vector<int> current_task(M, -1);      // -1 if idle\n    vector<int> start_day(M, -1);\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));  // estimated skill levels\n\n    const double learning_rate = 0.01;\n\n    int cur_day = 1;\n\n    while (true) {\n        // Collect idle members\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // Collect currently available tasks (status 0)\n        vector<int> today_avail;\n        for (int i : avail) {\n            if (task_status[i] == 0) {\n                today_avail.push_back(i);\n            }\n        }\n\n        // Sort by critical path length descending\n        sort(today_avail.begin(), today_avail.end(),\n             [&](int a, int b) { return L[a] > L[b]; });\n\n        vector<pair<int, int>> assignments; // (member, task)\n        vector<bool> member_used(M, false);\n\n        for (int i : today_avail) {\n            if (idle_members.empty()) break;\n\n            int best_j = -1;\n            double best_w = 1e9;\n            for (int j : idle_members) {\n                if (member_used[j]) continue;\n                double w = 0.0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        w += d[i][k] - s_est[j][k];\n                    }\n                }\n                if (w < best_w) {\n                    best_w = w;\n                    best_j = j;\n                }\n            }\n            if (best_j != -1) {\n                assignments.emplace_back(best_j, i);\n                member_used[best_j] = true;\n                // Update current task and start day immediately\n                current_task[best_j] = i;\n                start_day[best_j] = cur_day;\n                task_status[i] = 1; // mark as started\n            }\n        }\n\n        // Output assignments\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        // Read response line\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        istringstream iss(line);\n        int n;\n        iss >> n;\n        vector<int> completing;\n        for (int i = 0; i < n; ++i) {\n            int f;\n            iss >> f;\n            completing.push_back(f - 1); // to 0-index\n        }\n\n        // Process completions\n        for (int j : completing) {\n            int i = current_task[j];\n            if (i == -1) continue; // should not happen\n\n            int t = cur_day - start_day[j] + 1; // actual duration\n\n            // Update skill estimates for member j\n            double w_est = 0.0;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    w_est += d[i][k] - s_est[j][k];\n                }\n            }\n            double error = t - w_est;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    s_est[j][k] -= learning_rate * error;\n                    if (s_est[j][k] < 0.0) s_est[j][k] = 0.0;\n                }\n            }\n\n            // Mark task as completed\n            task_status[i] = 2;\n            current_task[j] = -1;\n\n            // Update dependent tasks\n            for (int v : children[i]) {\n                prereq_count[v]--;\n                if (prereq_count[v] == 0) {\n                    avail.push_back(v);\n                }\n            }\n        }\n\n        ++cur_day;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <ctime>\n#include <cassert>\n\nusing namespace std;\n\nstruct Order {\n    int id;          // original index (0-based)\n    int a, b, c, d;  // restaurant and destination\n    int cx, cy;      // centroid\n};\n\nvector<Order> orders; // all 1000 orders\n\n// Manhattan distance\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Point in the route: (order_index, type) type: 0=restaurant, 1=destination\nusing Point = pair<int, int>;\n\n// Compute total distance for a sequence of points\nint total_distance(const vector<Point>& seq, const vector<Order>& sel) {\n    int cur_x = 400, cur_y = 400;\n    int total = 0;\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) { // restaurant\n            total += dist(cur_x, cur_y, sel[idx].a, sel[idx].b);\n            cur_x = sel[idx].a;\n            cur_y = sel[idx].b;\n        } else { // destination\n            total += dist(cur_x, cur_y, sel[idx].c, sel[idx].d);\n            cur_x = sel[idx].c;\n            cur_y = sel[idx].d;\n        }\n    }\n    total += dist(cur_x, cur_y, 400, 400);\n    return total;\n}\n\n// Check precedence constraints: for each order, restaurant before destination\nbool is_valid(const vector<Point>& seq, int m) {\n    vector<int> rest_pos(m, -1), dest_pos(m, -1);\n    for (size_t i = 0; i < seq.size(); ++i) {\n        int idx = seq[i].first;\n        if (seq[i].second == 0) {\n            rest_pos[idx] = i;\n        } else {\n            dest_pos[idx] = i;\n        }\n    }\n    for (int i = 0; i < m; ++i) {\n        if (rest_pos[i] == -1 || dest_pos[i] == -1) return false;\n        if (rest_pos[i] >= dest_pos[i]) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read all orders\n    orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n        // Compute centroid\n        orders[i].cx = (orders[i].a + orders[i].c) / 2;\n        orders[i].cy = (orders[i].b + orders[i].d) / 2;\n    }\n\n    // Selection: pick 50 orders with centroid closest to office (400,400)\n    vector<int> indices(1000);\n    for (int i = 0; i < 1000; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int di = dist(400, 400, orders[i].cx, orders[i].cy);\n        int dj = dist(400, 400, orders[j].cx, orders[j].cy);\n        return di < dj;\n    });\n    vector<Order> selected;\n    vector<bool> used(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        selected.push_back(orders[indices[i]]);\n        used[indices[i]] = true;\n    }\n    int m = 50;\n\n    // Generate initial sequence using nearest neighbor with precedence\n    vector<Point> seq;\n    vector<bool> rest_done(m, false), dest_done(m, false);\n    vector<int> available; // orders whose restaurant done but destination not\n    int cur_x = 400, cur_y = 400;\n\n    for (int step = 0; step < 2 * m; ++step) {\n        int best_idx = -1;\n        int best_type = -1;\n        int best_cost = 1e9;\n\n        // Consider restaurants of unvisited orders\n        for (int i = 0; i < m; ++i) {\n            if (rest_done[i]) continue;\n            int cost = dist(cur_x, cur_y, selected[i].a, selected[i].b);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 0;\n            }\n        }\n        // Consider destinations of available orders\n        for (int i : available) {\n            int cost = dist(cur_x, cur_y, selected[i].c, selected[i].d);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 1;\n            }\n        }\n        assert(best_idx != -1);\n        seq.emplace_back(best_idx, best_type);\n        if (best_type == 0) {\n            rest_done[best_idx] = true;\n            available.push_back(best_idx);\n        } else {\n            dest_done[best_idx] = true;\n            // Remove from available\n            auto it = find(available.begin(), available.end(), best_idx);\n            if (it != available.end()) available.erase(it);\n        }\n        // Update current position\n        if (best_type == 0) {\n            cur_x = selected[best_idx].a;\n            cur_y = selected[best_idx].b;\n        } else {\n            cur_x = selected[best_idx].c;\n            cur_y = selected[best_idx].d;\n        }\n    }\n    assert(is_valid(seq, m));\n    int total = total_distance(seq, selected);\n\n    // Local search: 2-opt (segment reversal) and point swaps\n    clock_t start = clock();\n    const double time_limit = 1.9 * CLOCKS_PER_SEC;\n    bool improved = true;\n    while (improved && (clock() - start) < time_limit) {\n        improved = false;\n        // Try all segment reversals\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                vector<Point> new_seq = seq;\n                reverse(new_seq.begin() + i, new_seq.begin() + j + 1);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n        // Try all point swaps\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                if (i == j) continue;\n                vector<Point> new_seq = seq;\n                swap(new_seq[i], new_seq[j]);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n    }\n\n    // Output selected orders (1-based indices)\n    cout << m;\n    for (const auto& order : selected) {\n        cout << ' ' << order.id + 1;\n    }\n    cout << '\\n';\n\n    // Output route: office, then points in seq, then office\n    cout << 1 + 2 * m + 1; // start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) {\n            cout << ' ' << selected[idx].a << ' ' << selected[idx].b;\n        } else {\n            cout << ' ' << selected[idx].c << ' ' << selected[idx].d;\n        }\n    }\n    cout << \" 400 400\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, rank;\n    int components;\n    DSU(int n) : parent(n), rank(n, 0), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        components--;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        double dx = x[u[i]] - x[v[i]];\n        double dy = y[u[i]] - y[v[i]];\n        double dist = sqrt(dx * dx + dy * dy);\n        d[i] = (int)round(dist);\n    }\n\n    DSU dsu(N);\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (dsu.find(u[i]) == dsu.find(v[i])) {\n            cout << 0 << endl;\n        } else {\n            int K = dsu.components;\n            int rem = M - i;\n            if (rem <= 2 * K) {\n                cout << 1 << endl;\n                dsu.unite(u[i], v[i]);\n            } else {\n                if (l <= 2 * d[i]) {\n                    cout << 1 << endl;\n                    dsu.unite(u[i], v[i]);\n                } else {\n                    cout << 0 << endl;\n                }\n            }\n        }\n        cout.flush();\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 30;\nint N, M;\nint px[20], py[20], pt[20];\nint hx[10], hy[10];\nbool passable[31][31]; // 1-indexed\n\nbool pet_at[31][31];\nbool human_at[31][31];\nbool adj_to_pet[31][31]; // adjacent to at least one pet at start of turn\n\nbool blocked_this_turn[31][31]; // squares that will be blocked this turn (by humans)\n\nrandom_device rd;\nmt19937 rng(rd());\n\n// BFS function: returns component size and sets pet_count\nint bfs(int sx, int sy, int& pet_count, bool temp_blocked, int tbx, int tby) {\n    static bool visited[31][31];\n    memset(visited, 0, sizeof(visited));\n    queue<pair<int,int>> q;\n    if (passable[sx][sy] && !blocked_this_turn[sx][sy] && !(temp_blocked && sx==tbx && sy==tby)) {\n        q.push({sx, sy});\n        visited[sx][sy] = true;\n    }\n    int size = 0;\n    pet_count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        size++;\n        if (pet_at[x][y]) pet_count++;\n        for (int dx = -1; dx <= 1; dx++) {\n            for (int dy = -1; dy <= 1; dy++) {\n                if (abs(dx) + abs(dy) != 1) continue;\n                int nx = x + dx, ny = y + dy;\n                if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) continue;\n                if (!passable[nx][ny]) continue;\n                if (blocked_this_turn[nx][ny]) continue;\n                if (temp_blocked && nx==tbx && ny==tby) continue;\n                if (visited[nx][ny]) continue;\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return size;\n}\n\nint main() {\n    // Read input\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> px[i] >> py[i] >> pt[i];\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> hx[i] >> hy[i];\n    }\n\n    // Initialize passable grid\n    for (int i = 1; i <= MAXN; i++) {\n        for (int j = 1; j <= MAXN; j++) {\n            passable[i][j] = true;\n        }\n    }\n\n    // Loop for 300 turns\n    for (int turn = 0; turn < 300; turn++) {\n        // Precompute pet_at, human_at, adj_to_pet\n        memset(pet_at, 0, sizeof(pet_at));\n        for (int i = 0; i < N; i++) {\n            pet_at[px[i]][py[i]] = true;\n        }\n        memset(human_at, 0, sizeof(human_at));\n        for (int i = 0; i < M; i++) {\n            human_at[hx[i]][hy[i]] = true;\n        }\n        memset(adj_to_pet, 0, sizeof(adj_to_pet));\n        for (int i = 0; i < N; i++) {\n            int x = px[i], y = py[i];\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    if (abs(dx) + abs(dy) != 1) continue;\n                    int nx = x + dx, ny = y + dy;\n                    if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN) {\n                        adj_to_pet[nx][ny] = true;\n                    }\n                }\n            }\n        }\n\n        // Reset blocked_this_turn\n        memset(blocked_this_turn, 0, sizeof(blocked_this_turn));\n\n        // Random order for humans\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        string actions(M, '.'); // default action\n\n        for (int idx : order) {\n            int x = hx[idx], y = hy[idx];\n            double best_value = -1.0;\n            char best_action = '.';\n\n            // Helper lambda to evaluate an action\n            auto evaluate = [&](char action) -> double {\n                int nx = x, ny = y;\n                bool is_block = false;\n                bool is_move = false;\n                int tbx = -1, tby = -1;\n\n                if (action == '.') {\n                    // stay\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    // block\n                    is_block = true;\n                    if (action == 'u') { nx = x-1; ny = y; }\n                    else if (action == 'd') { nx = x+1; ny = y; }\n                    else if (action == 'l') { nx = x; ny = y-1; }\n                    else if (action == 'r') { nx = x; ny = y+1; }\n                    // Check legality for block\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1.0;\n                    if (!passable[nx][ny]) return -1.0;\n                    if (pet_at[nx][ny]) return -1.0;\n                    if (human_at[nx][ny]) return -1.0;\n                    if (adj_to_pet[nx][ny]) return -1.0;\n                    tbx = nx; tby = ny;\n                } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // move\n                    is_move = true;\n                    if (action == 'U') { nx = x-1; ny = y; }\n                    else if (action == 'D') { nx = x+1; ny = y; }\n                    else if (action == 'L') { nx = x; ny = y-1; }\n                    else if (action == 'R') { nx = x; ny = y+1; }\n                    // Check legality for move\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1.0;\n                    if (!passable[nx][ny]) return -1.0;\n                    if (blocked_this_turn[nx][ny]) return -1.0;\n                } else {\n                    return -1.0;\n                }\n\n                // Now compute component from the human's new position after action\n                int start_x = is_move ? nx : x;\n                int start_y = is_move ? ny : y;\n                int pet_count;\n                int comp_size = bfs(start_x, start_y, pet_count, is_block, tbx, tby);\n                double value = (comp_size / 900.0) * pow(2.0, -pet_count);\n                return value;\n            };\n\n            // Evaluate each possible action\n            vector<char> actions_list = {'.', 'u', 'd', 'l', 'r', 'U', 'D', 'L', 'R'};\n            for (char a : actions_list) {\n                double val = evaluate(a);\n                if (val > best_value) {\n                    best_value = val;\n                    best_action = a;\n                }\n            }\n\n            // If best_value is still -1 (no legal action), stay\n            if (best_value < 0) best_action = '.';\n\n            actions[idx] = best_action;\n\n            // If this human chose to block, add to blocked_this_turn\n            if (best_action == 'u' || best_action == 'd' || best_action == 'l' || best_action == 'r') {\n                int bx = x, by = y;\n                if (best_action == 'u') bx = x-1;\n                else if (best_action == 'd') bx = x+1;\n                else if (best_action == 'l') by = y-1;\n                else if (best_action == 'r') by = y+1;\n                blocked_this_turn[bx][by] = true;\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            // Apply movement\n            for (char c : s) {\n                if (c == 'U') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n                // else '.' do nothing\n            }\n        }\n\n        // Update passable grid based on blocks placed this turn\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'u' || a == 'd' || a == 'l' || a == 'r') {\n                int bx = hx[i], by = hy[i];\n                if (a == 'u') bx = hx[i]-1;\n                else if (a == 'd') bx = hx[i]+1;\n                else if (a == 'l') by = hy[i]-1;\n                else if (a == 'r') by = hy[i]+1;\n                passable[bx][by] = false;\n            }\n        }\n\n        // Update human positions based on moves\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') hx[i]--;\n            else if (a == 'D') hx[i]++;\n            else if (a == 'L') hy[i]--;\n            else if (a == 'R') hy[i]++;\n        }\n\n        // End of turn\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0:U, 1:D, 2:L, 3:R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Precompute next cell for each cell and direction\nvector<vector<vector<pair<int, int>>>> precompute_next(\n    const vector<vector<int>>& h,\n    const vector<vector<int>>& v) {\n    vector<vector<vector<pair<int, int>>>> next(4, vector<vector<pair<int, int>>>(20, vector<pair<int, int>>(20)));\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            // U\n            if (i > 0 && v[i-1][j] == 0)\n                next[0][i][j] = {i-1, j};\n            else\n                next[0][i][j] = {i, j};\n            // D\n            if (i < 19 && v[i][j] == 0)\n                next[1][i][j] = {i+1, j};\n            else\n                next[1][i][j] = {i, j};\n            // L\n            if (j > 0 && h[i][j-1] == 0)\n                next[2][i][j] = {i, j-1};\n            else\n                next[2][i][j] = {i, j};\n            // R\n            if (j < 19 && h[i][j] == 0)\n                next[3][i][j] = {i, j+1};\n            else\n                next[3][i][j] = {i, j};\n        }\n    }\n    return next;\n}\n\n// BFS to find a shortest path from start to target\nstring bfs_path(int si, int sj, int ti, int tj,\n                const vector<vector<int>>& h,\n                const vector<vector<int>>& v) {\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move(20, vector<char>(20, ' '));\n    queue<pair<int, int>> q;\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        // Try four directions\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            // Check walls\n            if (d == 0 && (i == 0 || v[i-1][j] == 1)) continue;\n            if (d == 1 && (i == 19 || v[i][j] == 1)) continue;\n            if (d == 2 && (j == 0 || h[i][j-1] == 1)) continue;\n            if (d == 3 && (j == 19 || h[i][j] == 1)) continue;\n            if (!visited[ni][nj]) {\n                visited[ni][nj] = true;\n                parent[ni][nj] = {i, j};\n                move[ni][nj] = dir_char[d];\n                q.emplace(ni, nj);\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path = \"\";\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        char m = move[i][j];\n        path += m;\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Simulate the stochastic process and compute expected score\ndouble simulate(const string& s,\n                const vector<vector<vector<pair<int, int>>>>& next,\n                int si, int sj, int ti, int tj, double p) {\n    vector<vector<double>> dist(20, vector<double>(20, 0.0));\n    dist[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int t = 1; t <= L; ++t) {\n        char c = s[t-1];\n        int d = -1;\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        vector<vector<double>> new_dist(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob = dist[i][j];\n                if (prob == 0.0) continue;\n                // With probability p, forget and stay\n                new_dist[i][j] += prob * p;\n                // With probability 1-p, try to move\n                auto [ni, nj] = next[d][i][j];\n                if (ni == ti && nj == tj) {\n                    score += prob * (1-p) * (401 - t);\n                } else {\n                    new_dist[ni][nj] += prob * (1-p);\n                }\n            }\n        }\n        dist = new_dist;\n    }\n    return score;\n}\n\n// Generate greedy nominal string (always try to move towards target)\nstring greedy_nominal(int si, int sj, int ti, int tj,\n                      const vector<vector<int>>& h,\n                      const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';  // arbitrary after reaching target\n            continue;\n        }\n        char best = 'R';\n        bool moved = false;\n        // Try right\n        if (cur_c < tj && h[cur_r][cur_c] == 0) {\n            best = 'R';\n            moved = true;\n        }\n        // Try down\n        if (!moved && cur_r < ti && v[cur_r][cur_c] == 0) {\n            best = 'D';\n            moved = true;\n        }\n        // Try left\n        if (!moved && cur_c > tj && (cur_c > 0 && h[cur_r][cur_c-1] == 0)) {\n            best = 'L';\n            moved = true;\n        }\n        // Try up\n        if (!moved && cur_r > ti && (cur_r > 0 && v[cur_r-1][cur_c] == 0)) {\n            best = 'U';\n            moved = true;\n        }\n        // If no move reduces Manhattan distance, try any possible move\n        if (!moved) {\n            if (cur_c < 19 && h[cur_r][cur_c] == 0) best = 'R';\n            else if (cur_r < 19 && v[cur_r][cur_c] == 0) best = 'D';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) best = 'L';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) best = 'U';\n            else best = 'R'; // should not happen\n        }\n        cand += best;\n        // Update nominal position\n        if (best == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (best == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (best == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n        else if (best == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n    }\n    return cand;\n}\n\n// Generate alternating direction string (prioritize down then right)\nstring alternating_string(int si, int sj, int ti, int tj,\n                          const vector<vector<int>>& h,\n                          const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char dir = 'D';\n        if (cur_r > ti) dir = 'U';\n        else if (cur_c < tj) dir = 'R';\n        else if (cur_c > tj) dir = 'L';\n        // else cur_r < ti already set to 'D'\n        bool possible = false;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) possible = true;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) possible = true;\n        if (!possible) {\n            // Try any possible direction\n            if (cur_r < 19 && v[cur_r][cur_c] == 0) dir = 'D';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) dir = 'U';\n            else if (cur_c < 19 && h[cur_r][cur_c] == 0) dir = 'R';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) dir = 'L';\n            else dir = 'R';\n        }\n        cand += dir;\n        // Update nominal position\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n    }\n    return cand;\n}\n\n// New method: DP + greedy lookahead using optimal adaptive value function\nstring dp_greedy_sequence(int si, int sj, int ti, int tj, double p,\n                          const vector<vector<vector<pair<int, int>>>>& next) {\n    // Precompute V[t][i][j] for t steps remaining\n    vector<vector<vector<double>>> V(201, vector<vector<double>>(20, vector<double>(20, 0.0)));\n    for (int t = 1; t <= 200; ++t) {\n        int step_num = 201 - t;   // the step number if we take this step now\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    V[t][i][j] = 0.0;\n                    continue;\n                }\n                double best = -1e9;\n                for (int a = 0; a < 4; ++a) {\n                    double val = 0.0;\n                    // stay (forget)\n                    val += p * V[t-1][i][j];\n                    // move (no forget)\n                    auto [ni, nj] = next[a][i][j];\n                    if (ni == ti && nj == tj) {\n                        val += (1-p) * (401 - step_num);\n                    } else {\n                        val += (1-p) * V[t-1][ni][nj];\n                    }\n                    if (val > best) best = val;\n                }\n                V[t][i][j] = best;\n            }\n        }\n    }\n\n    // Greedy construction using V as heuristic\n    vector<vector<double>> prob(20, vector<double>(20, 0.0));\n    prob[si][sj] = 1.0;\n    string s = \"\";\n    for (int t = 1; t <= 200; ++t) {\n        int remaining = 200 - t;   // steps after this step\n        double best_score = -1e9;\n        int best_a = 0;\n        for (int a = 0; a < 4; ++a) {\n            double immediate = 0.0;\n            double future = 0.0;\n            for (int i = 0; i < 20; ++i) {\n                for (int j = 0; j < 20; ++j) {\n                    double p_ij = prob[i][j];\n                    if (p_ij == 0.0) continue;\n                    // stay part\n                    future += p_ij * p * V[remaining][i][j];\n                    // move part\n                    auto [ni, nj] = next[a][i][j];\n                    if (ni == ti && nj == tj) {\n                        immediate += p_ij * (1-p) * (401 - t);\n                    } else {\n                        future += p_ij * (1-p) * V[remaining][ni][nj];\n                    }\n                }\n            }\n            double total = immediate + future;\n            if (total > best_score) {\n                best_score = total;\n                best_a = a;\n            }\n        }\n        s += dir_char[best_a];\n        // Update probability distribution\n        vector<vector<double>> new_prob(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double p_ij = prob[i][j];\n                if (p_ij == 0.0) continue;\n                // stay\n                new_prob[i][j] += p_ij * p;\n                // move\n                auto [ni, nj] = next[best_a][i][j];\n                if (ni == ti && nj == tj) {\n                    // reached target, do not add\n                } else {\n                    new_prob[ni][nj] += p_ij * (1-p);\n                }\n            }\n        }\n        prob = new_prob;\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    vector<vector<int>> h(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 19; ++j) {\n            h[i][j] = line[j] - '0';\n        }\n    }\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 20; ++j) {\n            v[i][j] = line[j] - '0';\n        }\n    }\n\n    // Precompute next cells\n    auto next_cell = precompute_next(h, v);\n\n    // Find a shortest path\n    string shortest_path = bfs_path(si, sj, ti, tj, h, v);\n    int k = shortest_path.size();\n\n    // Generate candidates\n    vector<string> candidates;\n\n    // 1. Shortest path itself\n    if (k > 0) {\n        candidates.push_back(shortest_path);\n    }\n\n    // 2. Repeat the whole path (padded to length 200)\n    if (k > 0) {\n        int t = 200 / k;\n        int rem = 200 % k;\n        string cand = \"\";\n        for (int i = 0; i < t; ++i) cand += shortest_path;\n        cand += shortest_path.substr(0, rem);\n        candidates.push_back(cand);\n    }\n\n    // 3. Repeat each move m times (m = floor(200/k))\n    if (k > 0) {\n        int m = 200 / k;\n        string cand = \"\";\n        for (char c : shortest_path) {\n            for (int i = 0; i < m; ++i) cand += c;\n        }\n        candidates.push_back(cand);\n    }\n\n    // 4. Greedy nominal moves\n    candidates.push_back(greedy_nominal(si, sj, ti, tj, h, v));\n\n    // 5. Alternating direction\n    candidates.push_back(alternating_string(si, sj, ti, tj, h, v));\n\n    // 6. New DP+greedy sequence\n    candidates.push_back(dp_greedy_sequence(si, sj, ti, tj, p, next_cell));\n\n    // Evaluate each candidate and pick the best\n    double best_score = -1.0;\n    string best_str = \"\";\n    for (const string& cand : candidates) {\n        double score = simulate(cand, next_cell, si, sj, ti, tj, p);\n        if (score > best_score) {\n            best_score = score;\n            best_str = cand;\n        }\n    }\n\n    cout << best_str << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nconst int STEPS = 15000;\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},    // tile 0\n    {3, -1, -1, 0},    // tile 1\n    {-1, -1, 3, 2},    // tile 2\n    {-1, 2, 1, -1},    // tile 3\n    {1, 0, 3, 2},      // tile 4\n    {3, 2, 1, 0},      // tile 5\n    {2, -1, 0, -1},    // tile 6\n    {-1, 3, -1, 1}     // tile 7\n};\n\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nint rotate(int t, int r) {\n    for (int i = 0; i < r; i++) {\n        if (t == 0) t = 1;\n        else if (t == 1) t = 2;\n        else if (t == 2) t = 3;\n        else if (t == 3) t = 0;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else if (t == 7) t = 6;\n    }\n    return t;\n}\n\npair<int, int> compute_two_longest(const vector<vector<int>>& tiles) {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\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                if (visited[i][j][d]) continue;\n                \n                int si = i, sj = j, sd = d;\n                int ci = i, cj = j, cd = d;\n                int length = 0;\n                bool valid = true;\n                \n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t = tiles[ci][cj];\n                    int d2 = to[t][cd];\n                    if (d2 == -1) {\n                        valid = false;\n                        break;\n                    }\n                    \n                    ci += di[d2];\n                    cj += dj[d2];\n                    if (ci < 0 || ci >= N || cj < 0 || cj >= N) {\n                        valid = false;\n                        break;\n                    }\n                    \n                    cd = (d2 + 2) % 4;\n                    length++;\n                    \n                    if (ci == si && cj == sj && cd == sd) {\n                        if (length > max1) {\n                            max2 = max1;\n                            max1 = length;\n                        } else if (length > max2) {\n                            max2 = length;\n                        }\n                        break;\n                    }\n                    \n                    if (length > 4 * N * N) {\n                        valid = false;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    vector<vector<int>> tiles(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n    \n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n    vector<vector<int>> best_rotations = rotations;\n    \n    auto [initial_max1, initial_max2] = compute_two_longest(tiles);\n    long long current_score = (long long)initial_max1 * initial_max2;\n    long long best_score = current_score;\n    \n    double temperature = 1000.0;\n    double cooling_rate = 0.9995;\n    \n    for (int step = 0; step < STEPS; step++) {\n        int i = pos_dist(rng);\n        int j = pos_dist(rng);\n        int old_rot = rotations[i][j];\n        int new_rot = rot_dist(rng);\n        \n        if (new_rot == old_rot) continue;\n        \n        int diff = (new_rot - old_rot + 4) % 4;\n        int old_type = tiles[i][j];\n        int new_type = rotate(old_type, diff);\n        \n        tiles[i][j] = new_type;\n        rotations[i][j] = new_rot;\n        \n        auto [new_max1, new_max2] = compute_two_longest(tiles);\n        long long new_score = (long long)new_max1 * new_max2;\n        \n        if (new_score > current_score || \n            rng() % 10000 < 10000 * exp((new_score - current_score) / temperature)) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rotations = rotations;\n            }\n        } else {\n            tiles[i][j] = old_type;\n            rotations[i][j] = old_rot;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += '0' + best_rotations[i][j];\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <utility>\n\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opposite[4] = {1, 0, 3, 2};\n\nstruct State {\n    int S;          // size of largest tree component\n    int edges;      // total number of edges in the whole graph\n};\n\nState compute_state() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_vertices = 0;\n    int total_edges = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            if (visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int vertices = 0;\n            int edges = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                vertices++;\n                int mask = board[x][y];\n                for (int d = 0; d < 4; ++d) {\n                    if (!(mask & (1 << d))) continue;\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    int opp_mask = board[nx][ny];\n                    int opp_bit = 1 << opposite[d];\n                    if (opp_mask & opp_bit) {\n                        if (d == 1 || d == 3) {\n                            edges++;\n                        }\n                        if (!visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            total_edges += edges;\n            if (edges == vertices - 1) {\n                max_tree_vertices = max(max_tree_vertices, vertices);\n            }\n        }\n    }\n    return {max_tree_vertices, total_edges};\n}\n\nvector<char> get_valid_moves() {\n    vector<char> moves;\n    for (int d = 0; d < 4; ++d) {\n        int ni = empty_i + di[d];\n        int nj = empty_j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            moves.push_back(dir_char[d]);\n        }\n    }\n    return moves;\n}\n\nvoid apply_move(int d) {\n    int ni = empty_i + di[d];\n    int nj = empty_j + dj[d];\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nvoid undo_move(int d) {\n    apply_move(opposite[d]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            board[i][j] = val;\n            if (val == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n\n    State current_state = compute_state();\n    int current_score = current_state.S * 10000 + current_state.edges;\n    int best_S = current_state.S;\n    string best_seq = \"\";\n    string current_seq = \"\";\n    string best_full_seq = \"\";\n\n    double temp = 1.0;\n    double cooling = 0.999;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n\n    for (int iter = 0; iter < T; ++iter) {\n        vector<char> moves = get_valid_moves();\n        if (moves.empty()) break;\n        char move = moves[gen() % moves.size()];\n        int d;\n        for (int i = 0; i < 4; ++i) {\n            if (dir_char[i] == move) {\n                d = i;\n                break;\n            }\n        }\n        apply_move(d);\n        State new_state = compute_state();\n        int new_score = new_state.S * 10000 + new_state.edges;\n        double delta = new_score - current_score;\n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            // accept\n            current_state = new_state;\n            current_score = new_score;\n            current_seq += move;\n            if (new_state.S > best_S) {\n                best_S = new_state.S;\n                best_seq = current_seq;\n            }\n            if (new_state.S == N * N - 1) {\n                if (best_full_seq.empty() || current_seq.length() < best_full_seq.length()) {\n                    best_full_seq = current_seq;\n                }\n            }\n        } else {\n            // reject\n            undo_move(d);\n        }\n        temp *= cooling;\n    }\n\n    if (!best_full_seq.empty()) {\n        if (best_seq.empty() || best_full_seq.length() < best_seq.length()) {\n            cout << best_full_seq << endl;\n        } else {\n            cout << best_seq << endl;\n        }\n    } else {\n        cout << best_seq << endl;\n    }\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n#include <set>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\n// Global arrays\nint a[11]; // a[1]..a[10]\n\n// Compute the score for given vertical lines V and horizontal lines H\nint compute_score(const vector<int>& V, const vector<int>& H, const vector<pair<int,int>>& points) {\n    int p = V.size();\n    int q = H.size();\n    int total_cells = (p+1)*(q+1);\n    vector<int> cell_counts(total_cells, 0);\n    \n    // Create boundary arrays including cake boundaries (-10000 and 10000)\n    vector<int> V_all(p+2), H_all(q+2);\n    V_all[0] = -10000;\n    for (int i=0; i<p; ++i) V_all[i+1] = V[i];\n    V_all[p+1] = 10000;\n    H_all[0] = -10000;\n    for (int i=0; i<q; ++i) H_all[i+1] = H[i];\n    H_all[q+1] = 10000;\n    \n    // For each point, determine its cell\n    for (const auto& pt : points) {\n        int x = pt.first, y = pt.second;\n        // Find vertical interval index i such that V_all[i] < x < V_all[i+1]\n        auto it_x = upper_bound(V_all.begin(), V_all.end(), x);\n        // Since x is strictly between -10000 and 10000, it_x cannot be begin or end\n        int i = (it_x - V_all.begin()) - 1;\n        // Find horizontal interval index j\n        auto it_y = upper_bound(H_all.begin(), H_all.end(), y);\n        int j = (it_y - H_all.begin()) - 1;\n        int cell_idx = i * (q+1) + j;\n        cell_counts[cell_idx]++;\n    }\n    \n    // Compute b_d for d=1..10\n    vector<int> b(11, 0); // index 1..10\n    for (int cnt : cell_counts) {\n        if (1 <= cnt && cnt <= 10) {\n            b[cnt]++;\n        }\n    }\n    int score = 0;\n    for (int d=1; d<=10; ++d) {\n        score += min(a[d], b[d]);\n    }\n    return score;\n}\n\n// Check if a vertical line at position x is valid (does not pass through any point)\nbool is_valid_vertical(int x, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.first == x) return false;\n    }\n    return true;\n}\n\n// Check if a horizontal line at position y is valid\nbool is_valid_horizontal(int y, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.second == y) return false;\n    }\n    return true;\n}\n\n// Find a free integer coordinate for a line, starting from a candidate and exploring nearby integers\nint find_free(int cand, const vector<int>& lines, const vector<pair<int,int>>& points, bool is_vertical) {\n    for (int d=0; ; ++d) {\n        for (int sign : {0, 1, -1}) {\n            int pos = cand + sign * d;\n            if (pos < -10000 || pos > 10000) continue;\n            // Check not already used by another line\n            if (find(lines.begin(), lines.end(), pos) != lines.end()) continue;\n            // Check not on any point\n            if (is_vertical) {\n                if (!is_valid_vertical(pos, points)) continue;\n            } else {\n                if (!is_valid_horizontal(pos, points)) continue;\n            }\n            return pos;\n        }\n    }\n}\n\n// Simulated annealing for a given split (p,q)\npair<vector<int>, vector<int>> sa_optimize(int p, int q, const vector<pair<int,int>>& points, int iterations=1000) {\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    uniform_int_distribution<int> dist_line(0, p+q-1);\n    uniform_int_distribution<int> dist_offset(-50, 50);\n    \n    // Extract x and y coordinates for initialization\n    int N = points.size();\n    vector<int> xs(N), ys(N);\n    for (int i=0; i<N; ++i) {\n        xs[i] = points[i].first;\n        ys[i] = points[i].second;\n    }\n    sort(xs.begin(), xs.end());\n    sort(ys.begin(), ys.end());\n    \n    // Initialize vertical lines\n    vector<int> V;\n    for (int i=1; i<=p; ++i) {\n        int idx = i * N / (p+1);\n        int cand = xs[idx];\n        int pos = find_free(cand, V, points, true);\n        V.push_back(pos);\n    }\n    sort(V.begin(), V.end());\n    \n    // Initialize horizontal lines\n    vector<int> H;\n    for (int i=1; i<=q; ++i) {\n        int idx = i * N / (q+1);\n        int cand = ys[idx];\n        int pos = find_free(cand, H, points, false);\n        H.push_back(pos);\n    }\n    sort(H.begin(), H.end());\n    \n    int cur_score = compute_score(V, H, points);\n    vector<int> bestV = V, bestH = H;\n    int best_score = cur_score;\n    \n    double temp = 1000.0;\n    double cooling = 0.999;\n    \n    for (int iter=0; iter<iterations; ++iter) {\n        // Choose a line to modify\n        int line_idx = dist_line(rng);\n        bool is_vertical = (line_idx < p);\n        int idx = is_vertical ? line_idx : line_idx - p;\n        \n        // Current position\n        int cur_pos = is_vertical ? V[idx] : H[idx];\n        // Generate candidate new position\n        int new_pos = cur_pos + dist_offset(rng);\n        if (new_pos < -10000 || new_pos > 10000) continue;\n        if (new_pos == cur_pos) continue;\n        \n        // Create candidate line sets\n        vector<int> newV = V;\n        vector<int> newH = H;\n        if (is_vertical) {\n            newV[idx] = new_pos;\n            // Check validity and no duplicates\n            if (!is_valid_vertical(new_pos, points)) continue;\n            sort(newV.begin(), newV.end());\n            if (adjacent_find(newV.begin(), newV.end()) != newV.end()) continue;\n        } else {\n            newH[idx] = new_pos;\n            if (!is_valid_horizontal(new_pos, points)) continue;\n            sort(newH.begin(), newH.end());\n            if (adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n        }\n        \n        // Compute new score\n        int new_score = compute_score(newV, newH, points);\n        int delta = new_score - cur_score;\n        if (delta > 0 || prob(rng) < exp(delta / temp)) {\n            // Accept move\n            cur_score = new_score;\n            V = newV;\n            H = newH;\n            if (cur_score > best_score) {\n                best_score = cur_score;\n                bestV = V;\n                bestH = H;\n            }\n        }\n        temp *= cooling;\n    }\n    return {bestV, bestH};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, K;\n    cin >> N >> K;\n    for (int d=1; d<=10; ++d) cin >> a[d];\n    \n    vector<pair<int,int>> points(N);\n    for (int i=0; i<N; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // We'll try three different splits of vertical and horizontal lines\n    vector<pair<int,int>> splits = {{30,70}, {50,50}, {70,30}};\n    int best_total_score = -1;\n    vector<int> bestV, bestH;\n    \n    for (auto [p,q] : splits) {\n        if (p+q > K) continue; // shouldn't happen\n        auto [V, H] = sa_optimize(p, q, points, 1000);\n        int score = compute_score(V, H, points);\n        if (score > best_total_score) {\n            best_total_score = score;\n            bestV = V;\n            bestH = H;\n        }\n    }\n    \n    // Output\n    cout << bestV.size() + bestH.size() << '\\n';\n    // Vertical lines\n    for (int x : bestV) {\n        cout << x << \" \" << -10000 << \" \" << x << \" \" << 10000 << '\\n';\n    }\n    // Horizontal lines\n    for (int y : bestH) {\n        cout << -10000 << \" \" << y << \" \" << 10000 << \" \" << y << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <ctime>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\n// Encode a unit segment into a 32-bit integer (canonical order: smaller x first, or if x equal, smaller y first)\nuint32_t encode_seg(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    // N <= 61, so 6 bits per coordinate are enough\n    return (x1 << 18) | (y1 << 12) | (x2 << 6) | y2;\n}\n\n// Check condition 2 for axis-aligned rectangle: no other dots on the perimeter (excluding corners)\nbool check_perimeter_axis(int x1, int y1, int x2, int y2, const vector<vector<bool>>& dot_grid) {\n    // vertical sides\n    for (int y = y1 + 1; y < y2; ++y) {\n        if (dot_grid[x1][y] || dot_grid[x2][y])\n            return false;\n    }\n    // horizontal sides\n    for (int x = x1 + 1; x < x2; ++x) {\n        if (dot_grid[x][y1] || dot_grid[x][y2])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for axis-aligned rectangle: no overlapping segments\nbool check_used_segments_axis(int x1, int y1, int x2, int y2, const unordered_set<uint32_t>& used_segments) {\n    // vertical sides\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x1, y, x1, y + 1)))\n            return false;\n        if (used_segments.count(encode_seg(x2, y, x2, y + 1)))\n            return false;\n    }\n    // horizontal sides\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y1, x + 1, y1)))\n            return false;\n        if (used_segments.count(encode_seg(x, y2, x + 1, y2)))\n            return false;\n    }\n    return true;\n}\n\n// Check condition 2 for 45-degree rectangle\nbool check_perimeter_45(int x, int y, int a, int b, const vector<vector<bool>>& dot_grid) {\n    // side P->C: (x,y) to (x+a, y+a)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + i][y + i])\n            return false;\n    }\n    // side C->Q: (x+a, y+a) to (x+a+b, y+a-b)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + a + i][y + a - i])\n            return false;\n    }\n    // side Q->D: (x+a+b, y+a-b) to (x+b, y-b)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + a + b - i][y + a - b - i])\n            return false;\n    }\n    // side D->P: (x+b, y-b) to (x,y)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + b - i][y - b + i])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for 45-degree rectangle\nbool check_used_segments_45(int x, int y, int a, int b, const unordered_set<uint32_t>& used_segments) {\n    // side P->C\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + i, y + i, x + i + 1, y + i + 1)))\n            return false;\n    }\n    // side C->Q\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + a + i, y + a - i, x + a + i + 1, y + a - i - 1)))\n            return false;\n    }\n    // side Q->D\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + a + b - i, y + a - b - i, x + a + b - i - 1, y + a - b - i - 1)))\n            return false;\n    }\n    // side D->P\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + b - i, y - b + i, x + b - i - 1, y - b + i + 1)))\n            return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    vector<Point> initial(M);\n    vector<vector<bool>> dot_grid(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        cin >> initial[i].x >> initial[i].y;\n        dot_grid[initial[i].x][initial[i].y] = true;\n    }\n\n    vector<Point> dots = initial;  // current list of dots\n    unordered_set<uint32_t> used_segments;\n    vector<array<int, 8>> operations;\n\n    int c = (N - 1) / 2;  // center coordinate\n    clock_t start_time = clock();\n\n    while (true) {\n        // Check time limit (4.5 seconds margin)\n        if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.5)\n            break;\n\n        int best_weight = -1;\n        array<int, 8> best_op;\n        bool found = false;\n\n        int Mcurr = dots.size();\n        for (int i = 0; i < Mcurr; ++i) {\n            for (int j = i + 1; j < Mcurr; ++j) {\n                Point A = dots[i], B = dots[j];\n\n                // ---------- Axis-aligned rectangle ----------\n                int x1 = min(A.x, B.x), x2 = max(A.x, B.x);\n                int y1 = min(A.y, B.y), y2 = max(A.y, B.y);\n                if (x1 < x2 && y1 < y2) {\n                    bool c1 = dot_grid[x1][y1];\n                    bool c2 = dot_grid[x1][y2];\n                    bool c3 = dot_grid[x2][y1];\n                    bool c4 = dot_grid[x2][y2];\n                    int cnt = c1 + c2 + c3 + c4;\n                    if (cnt == 3) {\n                        Point D;\n                        if (!c1) D = {x1, y1};\n                        else if (!c2) D = {x1, y2};\n                        else if (!c3) D = {x2, y1};\n                        else D = {x2, y2};\n\n                        if (check_perimeter_axis(x1, y1, x2, y2, dot_grid) &&\n                            check_used_segments_axis(x1, y1, x2, y2, used_segments)) {\n                            int w = (D.x - c) * (D.x - c) + (D.y - c) * (D.y - c) + 1;\n                            if (w > best_weight) {\n                                best_weight = w;\n                                // Build operation in cyclic order\n                                array<Point, 4> corners = { {x1, y1}, {x1, y2}, {x2, y2}, {x2, y1} };\n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                            }\n                        }\n                    }\n                }\n\n                // ---------- 45-degree rectangle ----------\n                // Try both orders (A as start, then B as start)\n                for (int order = 0; order < 2; ++order) {\n                    Point start = (order == 0) ? A : B;\n                    Point opposite = (order == 0) ? B : A;\n                    int dx = opposite.x - start.x;\n                    int dy = opposite.y - start.y;\n                    int sum_diff = dx + dy;\n                    int sub_diff = dx - dy;\n                    if (sum_diff % 2 != 0 || sub_diff % 2 != 0) continue;\n                    int a = sum_diff / 2;\n                    int b = sub_diff / 2;\n                    if (a <= 0 || b <= 0) continue;\n\n                    // Other two corners\n                    Point C = {start.x + a, start.y + a};\n                    Point D = {start.x + b, start.y - b};\n                    if (C.x < 0 || C.x >= N || C.y < 0 || C.y >= N ||\n                        D.x < 0 || D.x >= N || D.y < 0 || D.y >= N) continue;\n\n                    bool cC = dot_grid[C.x][C.y];\n                    bool cD = dot_grid[D.x][D.y];\n                    if (cC + cD != 1) continue;  // exactly one of C,D is a dot\n\n                    Point missing = cC ? D : C;  // the one that is not a dot\n                    // The four corners in order: start -> C -> opposite -> D\n                    array<Point, 4> corners = {start, C, opposite, D};\n\n                    if (check_perimeter_45(start.x, start.y, a, b, dot_grid) &&\n                        check_used_segments_45(start.x, start.y, a, b, used_segments)) {\n                        int w = (missing.x - c) * (missing.x - c) + (missing.y - c) * (missing.y - c) + 1;\n                        if (w > best_weight) {\n                            best_weight = w;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (!found) break;\n\n        // Perform the operation\n        operations.push_back(best_op);\n        Point new_dot = {best_op[0], best_op[1]};\n        dot_grid[new_dot.x][new_dot.y] = true;\n        dots.push_back(new_dot);\n\n        // Add the four edges of the rectangle to used_segments\n        for (int k = 0; k < 4; ++k) {\n            int k2 = (k + 1) % 4;\n            int x1 = best_op[2*k], y1 = best_op[2*k+1];\n            int x2 = best_op[2*k2], y2 = best_op[2*k2+1];\n            used_segments.insert(encode_seg(x1, y1, x2, y2));\n        }\n    }\n\n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            cout << op[i];\n            if (i < 7) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\nusing namespace std;\n\nconst int SIZE = 10;\nusing Grid = vector<vector<int>>; // 1\u2011indexed, 11x11\n\n// Apply a tilt in the given direction and return the new grid.\nGrid apply_tilt(const Grid& grid, char dir) {\n    Grid new_grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n    if (dir == 'L') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][i + 1] = flavors[i];\n        }\n    } else if (dir == 'R') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][SIZE - k + 1 + i] = flavors[i];\n        }\n    } else if (dir == 'F') { // forward = up\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[i + 1][c] = flavors[i];\n        }\n    } else { // 'B' \u2013 backward = down\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[SIZE - k + 1 + i][c] = flavors[i];\n        }\n    }\n    return new_grid;\n}\n\n// Compute sum of squares of connected component sizes.\nlong long compute_score(const Grid& grid) {\n    bool visited[SIZE + 1][SIZE + 1] = {false};\n    long long score = 0;\n    const int dr[] = {1, -1, 0, 0};\n    const int dc[] = {0, 0, 1, -1};\n    for (int r = 1; r <= SIZE; ++r) {\n        for (int c = 1; c <= SIZE; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                vector<pair<int, int>> queue = {{r, c}};\n                visited[r][c] = true;\n                int idx = 0;\n                while (idx < queue.size()) {\n                    auto [cr, cc] = queue[idx++];\n                    ++size;\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = cr + dr[d];\n                        int nc = cc + dc[d];\n                        if (nr >= 1 && nr <= SIZE && nc >= 1 && nc <= SIZE &&\n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            queue.push_back({nr, nc});\n                        }\n                    }\n                }\n                score += (long long)size * size;\n            }\n        }\n    }\n    return score;\n}\n\nint main() {\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) cin >> f[i];\n\n    Grid grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n\n    for (int t = 1; t <= 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Locate the p\u2011th empty cell (front\u2011to\u2011back, left\u2011to\u2011right).\n        int count = 0;\n        int placed_r = -1, placed_c = -1;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == 0) {\n                    ++count;\n                    if (count == p) {\n                        placed_r = r;\n                        placed_c = c;\n                        break;\n                    }\n                }\n            }\n            if (placed_r != -1) break;\n        }\n        grid[placed_r][placed_c] = f[t];\n\n        if (t == 100) break; // last candy \u2013 no tilt needed\n\n        // One\u2011step lookahead: for each possible current tilt,\n        // compute the expected best score after the next candy.\n        char best_dir = 'F';\n        double best_expected = -1.0;\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid grid1 = apply_tilt(grid, dir);\n\n            // Collect empty cells in grid1.\n            vector<pair<int, int>> empties;\n            for (int r = 1; r <= SIZE; ++r)\n                for (int c = 1; c <= SIZE; ++c)\n                    if (grid1[r][c] == 0) empties.emplace_back(r, c);\n\n            double total = 0.0;\n            for (auto [r, c] : empties) {\n                Grid grid2 = grid1;\n                grid2[r][c] = f[t + 1]; // next candy flavor\n\n                long long best_next = 0;\n                for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                    Grid grid3 = apply_tilt(grid2, next_dir);\n                    long long sc = compute_score(grid3);\n                    if (sc > best_next) best_next = sc;\n                }\n                total += best_next;\n            }\n            double expected = total / empties.size();\n\n            if (expected > best_expected) {\n                best_expected = expected;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        grid = apply_tilt(grid, best_dir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Precompute expected sorted degree lists for each possible a (1..N)\n    vector<vector<double>> exp_sorted(N + 1);\n    for (int a = 1; a <= N; ++a) {\n        vector<double> degs;\n        if (a == N) {\n            double mu = (N - 1) * (1 - epsilon);\n            degs.assign(N, mu);\n        } else {\n            double muA = (a - 1) * (1 - epsilon) + (N - a) * epsilon;\n            double muB = (N - a - 1) * (1 - epsilon) + a * epsilon;\n            for (int i = 0; i < a; ++i) degs.push_back(muA);\n            for (int i = 0; i < N - a; ++i) degs.push_back(muB);\n            sort(degs.begin(), degs.end());\n        }\n        exp_sorted[a] = degs;\n    }\n\n    // Precompute L1 distances between any two a\n    vector<vector<double>> dist(N + 1, vector<double>(N + 1, 0.0));\n    for (int a1 = 1; a1 <= N; ++a1) {\n        for (int a2 = a1 + 1; a2 <= N; ++a2) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(exp_sorted[a1][i] - exp_sorted[a2][i]);\n            }\n            dist[a1][a2] = d;\n            dist[a2][a1] = d;\n        }\n    }\n\n    // Greedy selection of M a values\n    vector<int> selected;\n    selected.push_back(50);  // start with middle to cover the range\n    vector<bool> used(N + 1, false);\n    used[50] = true;\n    for (int step = 1; step < M; ++step) {\n        int best_a = -1;\n        double best_min_dist = -1.0;\n        for (int a = 1; a <= N; ++a) {\n            if (used[a]) continue;\n            double min_dist = 1e18;\n            for (int b : selected) {\n                min_dist = min(min_dist, dist[a][b]);\n            }\n            if (min_dist > best_min_dist) {\n                best_min_dist = min_dist;\n                best_a = a;\n            }\n        }\n        selected.push_back(best_a);\n        used[best_a] = true;\n    }\n\n    // Sort selected a in increasing order for output order\n    sort(selected.begin(), selected.end());\n\n    // Create mapping from a to index\n    vector<int> index_of_a(N + 1, -1);\n    for (int i = 0; i < M; ++i) {\n        index_of_a[selected[i]] = i;\n    }\n\n    // Output N\n    cout << N << endl;\n\n    // Output M graphs\n    for (int a : selected) {\n        string graph;\n        graph.resize(N * (N - 1) / 2, '0');\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool same_clique = false;\n                if (a == N) {\n                    same_clique = true;  // complete graph\n                } else {\n                    if (i < a && j < a) same_clique = true;\n                    else if (i >= a && j >= a) same_clique = true;\n                }\n                if (same_clique) graph[pos] = '1';\n                pos++;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        // Compute degrees\n        vector<int> deg(N, 0);\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[pos] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                pos++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n\n        // Find the a with minimum L1 distance\n        int best_idx = -1;\n        double best_dist = 1e18;\n        for (int a : selected) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(deg[i] - exp_sorted[a][i]);\n            }\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = index_of_a[a];\n            }\n        }\n\n        cout << best_idx << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll INF = 1e18;\nconst int MAXN = 1000;\n\nint N, M, D, K;\nvector<vector<pair<int, int>>> adj; // neighbor, edge index\nvector<int> u, v, w;\nvector<double> mid_x, mid_y;\nvector<ll> cnt;\nvector<vector<char>> removed; // removed[day][edge]\nvector<int> day_assign;\nvector<ll> day_sum;\nvector<int> day_cnt;\nvector<double> sum_mid_x, sum_mid_y;\n\nint vis[MAXN];\nint cur_mark = 0;\n\nbool isConnected(int d) {\n    cur_mark++;\n    queue<int> q;\n    q.push(0);\n    vis[0] = cur_mark;\n    int count = 1;\n    while (!q.empty()) {\n        int node = q.front(); q.pop();\n        for (auto [nbr, eidx] : adj[node]) {\n            if (removed[d][eidx]) continue;\n            if (vis[nbr] != cur_mark) {\n                vis[nbr] = cur_mark;\n                q.push(nbr);\n                count++;\n            }\n        }\n    }\n    return count == N;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> D >> K;\n    u.resize(M); v.resize(M); w.resize(M);\n    adj.resize(N);\n    vector<vector<int>> edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        edge_idx[u[i]][v[i]] = i;\n        edge_idx[v[i]][u[i]] = i;\n        adj[u[i]].emplace_back(v[i], i);\n        adj[v[i]].emplace_back(u[i], i);\n    }\n\n    vector<int> coord_x(N), coord_y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coord_x[i] >> coord_y[i];\n    }\n\n    mid_x.resize(M); mid_y.resize(M);\n    for (int i = 0; i < M; ++i) {\n        mid_x[i] = (coord_x[u[i]] + coord_x[v[i]]) * 0.5;\n        mid_y[i] = (coord_y[u[i]] + coord_y[v[i]]) * 0.5;\n    }\n\n    // All-pairs shortest paths and parent selection\n    vector<vector<ll>> dist(N, vector<ll>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        dist[s][s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.emplace(0, s);\n        while (!pq.empty()) {\n            auto [d, node] = pq.top(); pq.pop();\n            if (d != dist[s][node]) continue;\n            for (auto [nbr, weight] : adj[node]) {\n                ll nd = d + weight;\n                if (nd < dist[s][nbr]) {\n                    dist[s][nbr] = nd;\n                    parent[s][nbr] = node;\n                    pq.emplace(nd, nbr);\n                } else if (nd == dist[s][nbr] && node < parent[s][nbr]) {\n                    parent[s][nbr] = node;\n                }\n            }\n        }\n    }\n\n    // Criticality (cnt) for each edge\n    cnt.assign(M, 0);\n    for (int s = 0; s < N; ++s) {\n        vector<vector<int>> tree(N);\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            tree[p].push_back(v);\n            tree[v].push_back(p);\n        }\n        vector<int> order;\n        vector<bool> visited(N, false);\n        stack<int> stk;\n        stk.push(s);\n        visited[s] = true;\n        while (!stk.empty()) {\n            int node = stk.top(); stk.pop();\n            order.push_back(node);\n            for (int nbr : tree[node]) {\n                if (!visited[nbr]) {\n                    visited[nbr] = true;\n                    stk.push(nbr);\n                }\n            }\n        }\n        vector<int> sz(N, 0);\n        for (int i = order.size()-1; i >= 0; --i) {\n            int node = order[i];\n            sz[node] = 1;\n            for (int nbr : tree[node]) {\n                if (nbr == s) continue;\n                if (parent[s][nbr] == node) {\n                    sz[node] += sz[nbr];\n                }\n            }\n        }\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            cnt[eidx] += sz[v];\n        }\n    }\n\n    // Initialize day structures\n    day_assign.assign(M, -1);\n    day_sum.assign(D, 0);\n    day_cnt.assign(D, 0);\n    sum_mid_x.assign(D, 0.0);\n    sum_mid_y.assign(D, 0.0);\n    removed.assign(D, vector<char>(M, 0));\n\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n    sort(order_edges.begin(), order_edges.end(),\n         [&](int a, int b) { return cnt[a] > cnt[b]; });\n\n    for (int e : order_edges) {\n        // Find minimum day_sum among days with free slots\n        ll min_sum = INF;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K) {\n                min_sum = min(min_sum, day_sum[d]);\n            }\n        }\n\n        int best_day = -1;\n        double best_dist2 = -1.0;\n\n        // Try days with min_sum first\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K && day_sum[d] == min_sum) {\n                removed[d][e] = 1;\n                if (isConnected(d)) {\n                    double dist2;\n                    if (day_cnt[d] == 0) {\n                        dist2 = 1e18;\n                    } else {\n                        double avg_x = sum_mid_x[d] / day_cnt[d];\n                        double avg_y = sum_mid_y[d] / day_cnt[d];\n                        double dx = mid_x[e] - avg_x;\n                        double dy = mid_y[e] - avg_y;\n                        dist2 = dx*dx + dy*dy;\n                    }\n                    if (best_day == -1 || dist2 > best_dist2) {\n                        best_dist2 = dist2;\n                        best_day = d;\n                    }\n                }\n                removed[d][e] = 0;\n            }\n        }\n\n        // If no day with min_sum kept connectivity, fallback to first min_sum day\n        if (best_day == -1) {\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] < K && day_sum[d] == min_sum) {\n                    best_day = d;\n                    break;\n                }\n            }\n        }\n\n        // Assign edge to best_day\n        day_assign[e] = best_day;\n        day_sum[best_day] += cnt[e];\n        day_cnt[best_day]++;\n        sum_mid_x[best_day] += mid_x[e];\n        sum_mid_y[best_day] += mid_y[e];\n        removed[best_day][e] = 1;\n    }\n\n    // Output\n    for (int i = 0; i < M; ++i) {\n        cout << day_assign[i] + 1;\n        if (i < M - 1) cout << ' ';\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;  // global, needed for canonical shape normalization\n\n// 24 rotation matrices\nvector<array<array<int, 3>, 3>> rotations;\n\n// generate all rotations (determinant = 1)\nvoid generate_rotations() {\n    vector<int> axes = {0, 1, 2};\n    do {\n        // compute sign of permutation (even -> +1, odd -> -1)\n        int inversions = 0;\n        for (int i = 0; i < 3; ++i)\n            for (int j = i + 1; j < 3; ++j)\n                if (axes[i] > axes[j]) ++inversions;\n        int perm_sign = (inversions % 2 == 0) ? 1 : -1;\n\n        for (int s0 : {-1, 1}) {\n            for (int s1 : {-1, 1}) {\n                // s2 determined by determinant = s0 * s1 * s2 * perm_sign = 1\n                int s2 = (perm_sign * s0 * s1 == 1) ? 1 : -1;\n                array<array<int, 3>, 3> mat{};\n                mat[0][axes[0]] = s0;\n                mat[1][axes[1]] = s1;\n                mat[2][axes[2]] = s2;\n                rotations.push_back(mat);\n            }\n        }\n    } while (next_permutation(axes.begin(), axes.end()));\n}\n\nusing Point = array<int, 3>;\n\n// canonical shape of a block: normalized to min (0,0,0) and all rotations considered\nvector<Point> canonical_shape(const vector<Point>& cubes) {\n    // find current min\n    Point min_point = {D, D, D};\n    for (auto& p : cubes) {\n        for (int i = 0; i < 3; ++i) min_point[i] = min(min_point[i], p[i]);\n    }\n    vector<Point> rel;\n    for (auto& p : cubes) {\n        rel.push_back({p[0] - min_point[0], p[1] - min_point[1], p[2] - min_point[2]});\n    }\n\n    vector<Point> best = rel;\n    sort(best.begin(), best.end());\n\n    // try all rotations\n    for (const auto& rot : rotations) {\n        vector<Point> rotated;\n        for (auto& p : rel) {\n            Point np;\n            for (int i = 0; i < 3; ++i) {\n                np[i] = 0;\n                for (int j = 0; j < 3; ++j) np[i] += rot[i][j] * p[j];\n            }\n            rotated.push_back(np);\n        }\n        // normalize after rotation\n        Point min_rot = {D, D, D};\n        for (auto& p : rotated) {\n            for (int i = 0; i < 3; ++i) min_rot[i] = min(min_rot[i], p[i]);\n        }\n        vector<Point> norm;\n        for (auto& p : rotated) {\n            norm.push_back({p[0] - min_rot[0], p[1] - min_rot[1], p[2] - min_rot[2]});\n        }\n        sort(norm.begin(), norm.end());\n        if (norm < best) best = norm;\n    }\n    return best;\n}\n\n// a connected component (block)\nstruct Component {\n    vector<Point> cubes;\n    int volume;\n    vector<Point> canon;  // canonical shape\n    int block_id;\n    bool used;  // for matching\n};\n\n// generate minimal object from silhouette pair\nvector<Point> generate_object(const vector<string>& f, const vector<string>& r) {\n    vector<Point> cubes;\n    for (int z = 0; z < D; ++z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (f[z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (r[z][y] == '1') Y.push_back(y);\n        // guaranteed non-empty per problem statement\n        if (X.size() <= Y.size()) {\n            // match each x to a distinct y\n            for (size_t i = 0; i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining y\n            for (size_t i = X.size(); i < Y.size(); ++i) {\n                cubes.push_back({X[0], Y[i], z});\n            }\n        } else {\n            // match each y to a distinct x\n            for (size_t i = 0; i < Y.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining x\n            for (size_t i = Y.size(); i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[0], z});\n            }\n        }\n    }\n    return cubes;\n}\n\n// extract connected components from a set of cubes\nvector<Component> get_components(const vector<Point>& cubes) {\n    // boolean grid\n    vector<vector<vector<bool>>> grid(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (auto& p : cubes) grid[p[0]][p[1]][p[2]] = true;\n\n    vector<bool> visited(D * D * D, false);\n    vector<Component> comps;\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    for (auto& p : cubes) {\n        int idx = p[0] * D * D + p[1] * D + p[2];\n        if (!visited[idx]) {\n            // BFS\n            vector<Point> comp_cubes;\n            queue<Point> q;\n            q.push(p);\n            visited[idx] = true;\n            while (!q.empty()) {\n                Point cur = q.front(); q.pop();\n                comp_cubes.push_back(cur);\n                for (int d = 0; d < 6; ++d) {\n                    int nx = cur[0] + dx[d], ny = cur[1] + dy[d], nz = cur[2] + dz[d];\n                    if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && grid[nx][ny][nz]) {\n                        int nidx = nx * D * D + ny * D + nz;\n                        if (!visited[nidx]) {\n                            visited[nidx] = true;\n                            q.push({nx, ny, nz});\n                        }\n                    }\n                }\n            }\n            Component comp;\n            comp.cubes = comp_cubes;\n            comp.volume = comp_cubes.size();\n            comp.canon = canonical_shape(comp_cubes);\n            comp.used = false;\n            comps.push_back(comp);\n        }\n    }\n    return comps;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D;\n\n    // read silhouettes\n    vector<string> f0(D), r0(D), f1(D), r1(D);\n    for (int i = 0; i < D; ++i) cin >> f0[i];\n    for (int i = 0; i < D; ++i) cin >> r0[i];\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n\n    generate_rotations();\n\n    // minimal objects\n    vector<Point> obj0_cubes = generate_object(f0, r0);\n    vector<Point> obj1_cubes = generate_object(f1, r1);\n\n    // components for each object\n    vector<Component> comp0 = get_components(obj0_cubes);\n    vector<Component> comp1 = get_components(obj1_cubes);\n\n    // sort by volume (largest first) to prioritize matching large blocks\n    sort(comp0.begin(), comp0.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n    sort(comp1.begin(), comp1.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n\n    // map from canonical shape to list of indices in comp1\n    map<vector<Point>, vector<int>> shape_to_idx1;\n    for (size_t i = 0; i < comp1.size(); ++i) {\n        shape_to_idx1[comp1[i].canon].push_back(i);\n    }\n\n    int block_id = 1;\n    // match components with same shape\n    for (size_t i = 0; i < comp0.size(); ++i) {\n        auto it = shape_to_idx1.find(comp0[i].canon);\n        if (it != shape_to_idx1.end() && !it->second.empty()) {\n            int j = it->second.back();\n            it->second.pop_back();\n            comp0[i].block_id = block_id;\n            comp1[j].block_id = block_id;\n            comp0[i].used = true;\n            comp1[j].used = true;\n            ++block_id;\n        }\n    }\n\n    // assign ids to unmatched components\n    for (auto& comp : comp0) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    for (auto& comp : comp1) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    int n = block_id - 1;\n\n    // build output arrays\n    vector<int> b0(D * D * D, 0), b1(D * D * D, 0);\n    for (auto& comp : comp0) {\n        for (auto& p : comp.cubes) {\n            b0[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n    for (auto& comp : comp1) {\n        for (auto& p : comp.cubes) {\n            b1[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n\n    // output\n    cout << n << '\\n';\n    for (size_t i = 0; i < b0.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b0[i];\n    }\n    cout << '\\n';\n    for (size_t i = 0; i < b1.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <map>\n#include <set>\n#include <random>\n#include <climits>\n#include <cassert>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nconst double EPS = 1e-9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // Read edges and build distance matrix\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    for (int i = 0; i < N; ++i) distV[i][i] = 0;\n\n    vector<tuple<int, int, long long>> edges(M);\n    map<pair<int, int>, int> edgeIndex; // (min(u,v), max(u,v)) -> edge index\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[j] = {u, v, w};\n        if (u > v) swap(u, v);\n        edgeIndex[{u, v}] = j;\n        distV[u][v] = min(distV[u][v], w);\n        distV[v][u] = min(distV[v][u], w);\n    }\n\n    // Floyd-Warshall with next matrix for path reconstruction\n    vector<vector<int>> next(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i != j && distV[i][j] < INF) {\n                next[i][j] = j;\n            }\n        }\n    }\n\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][k] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[k][j] == INF) continue;\n                if (distV[i][j] > distV[i][k] + distV[k][j]) {\n                    distV[i][j] = distV[i][k] + distV[k][j];\n                    next[i][j] = next[i][k];\n                }\n            }\n        }\n    }\n\n    // Read residents\n    vector<double> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // Distance from each vertex to each resident\n    vector<vector<double>> distVtoR(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            distVtoR[i][k] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Initial assignment: each resident to nearest vertex\n    vector<int> assign(K);\n    vector<vector<int>> residentList(N);\n    for (int k = 0; k < K; ++k) {\n        int best = 0;\n        for (int i = 1; i < N; ++i) {\n            if (distVtoR[i][k] < distVtoR[best][k] - EPS) {\n                best = i;\n            }\n        }\n        assign[k] = best;\n        residentList[best].push_back(k);\n    }\n\n    // Compute initial P[i]\n    vector<int> P(N, 0);\n    for (int i = 0; i < N; ++i) {\n        if (residentList[i].empty()) {\n            P[i] = 0;\n        } else {\n            double maxDist = 0;\n            for (int k : residentList[i]) {\n                maxDist = max(maxDist, distVtoR[i][k]);\n            }\n            P[i] = (int)ceil(maxDist);\n            // Ensure not exceeding 5000 (though problem guarantees within 5000)\n            if (P[i] > 5000) P[i] = 5000;\n        }\n    }\n\n    // Compute initial sum of squares\n    long long sumSq = 0;\n    for (int i = 0; i < N; ++i) {\n        sumSq += (long long)P[i] * P[i];\n    }\n\n    // Function to compute Steiner tree cost for a set of terminals\n    auto computeSteinerCost = [&](const vector<int>& T) -> long long {\n        int n = T.size();\n        if (n <= 1) return 0;\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        minDist[0] = 0;\n        long long total = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            if (u == -1) break;\n            inMST[u] = true;\n            total += minDist[u];\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[T[u]][T[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                    }\n                }\n            }\n        }\n        return total;\n    };\n\n    // Build initial T (vertex 0 + vertices with P>0)\n    vector<int> currentT;\n    currentT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            currentT.push_back(i);\n        }\n    }\n    long long currentSteinerCost = computeSteinerCost(currentT);\n    long long currentCost = sumSq + currentSteinerCost;\n\n    // Local search\n    int maxIter = 10000;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> residentDist(0, K-1);\n\n    for (int iter = 0; i < maxIter; ++iter) {\n        int k = residentDist(gen);\n        int i = assign[k];\n        bool improved = false;\n        for (int j = 0; j < N; ++j) {\n            if (j == i) continue;\n\n            // Simulate move\n            int oldP_i = P[i], oldP_j = P[j];\n\n            // Compute new lists without scanning entire list each time? We'll copy temporarily.\n            vector<int> newList_i, newList_j;\n            for (int r : residentList[i]) {\n                if (r != k) newList_i.push_back(r);\n            }\n            for (int r : residentList[j]) {\n                newList_j.push_back(r);\n            }\n            newList_j.push_back(k);\n\n            // Compute new P_i and P_j\n            int newP_i = 0, newP_j = 0;\n            if (!newList_i.empty()) {\n                double maxDist = 0;\n                for (int r : newList_i) {\n                    maxDist = max(maxDist, distVtoR[i][r]);\n                }\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!newList_j.empty()) {\n                double maxDist = 0;\n                for (int r : newList_j) {\n                    maxDist = max(maxDist, distVtoR[j][r]);\n                }\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n\n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n\n            // Check if T changes\n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                // Remove i from newT\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                // Add j to newT\n                newT.push_back(j);\n            }\n\n            long long newCost;\n            if (newT == currentT) {\n                newCost = newSumSq + currentSteinerCost;\n            } else {\n                long long newSteinerCost = computeSteinerCost(newT);\n                newCost = newSumSq + newSteinerCost;\n                if (newCost < currentCost - EPS) {\n                    // Accept move\n                    // Update structures\n                    sumSq = newSumSq;\n                    P[i] = newP_i;\n                    P[j] = newP_j;\n                    residentList[i] = newList_i;\n                    residentList[j] = newList_j;\n                    assign[k] = j;\n                    currentT = newT;\n                    currentSteinerCost = newSteinerCost;\n                    currentCost = newCost;\n                    improved = true;\n                    break;\n                }\n            }\n            if (newCost < currentCost - EPS) {\n                // Accept move\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                residentList[i] = newList_i;\n                residentList[j] = newList_j;\n                assign[k] = j;\n                currentT = newT;\n                currentCost = newCost;\n                improved = true;\n                break;\n            }\n        }\n        // If no improvement, continue to next iteration\n    }\n\n    // Final T for output\n    vector<int> finalT;\n    finalT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            finalT.push_back(i);\n        }\n    }\n\n    // Compute Steiner tree edges\n    set<int> onEdges;\n    auto addPath = [&](int u, int v) {\n        while (u != v) {\n            int nxt = next[u][v];\n            int a = u, b = nxt;\n            if (a > b) swap(a, b);\n            onEdges.insert(edgeIndex[{a, b}]);\n            u = nxt;\n        }\n    };\n\n    // Compute MST on metric closure of finalT\n    int n = finalT.size();\n    if (n > 1) {\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[finalT[u]][finalT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        // Reconstruct MST edges\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u != -1) {\n                addPath(finalT[u], finalT[v]);\n            }\n        }\n    }\n\n    // Output P[i]\n    for (int i = 0; i < N; ++i) {\n        cout << P[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    // Output B[j]\n    for (int j = 0; j < M; ++j) {\n        cout << (onEdges.count(j) ? 1 : 0);\n        if (j < M-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2; // 465\n\n// Convert (x,y) to index (row-major order)\nint to_index(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Convert index to (x,y)\npair<int, int> to_coord(int idx) {\n    int x = 0;\n    while (idx >= x + 1) {\n        idx -= (x + 1);\n        x++;\n    }\n    return {x, idx};\n}\n\n// Directions: six neighbors as deltas (dx, dy)\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Check if coordinates are valid\nbool valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y <= x;\n}\n\nint main() {\n    // Read input\n    vector<int> ball(TOTAL);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int b;\n            cin >> b;\n            ball[to_index(x, y)] = b;\n        }\n    }\n\n    // Create sorted list of all ball numbers\n    vector<int> sorted = ball;\n    sort(sorted.begin(), sorted.end());\n\n    // Target: row-major order with sorted numbers\n    vector<int> target(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) {\n        target[i] = sorted[i];\n    }\n\n    // Precompute adjacency list\n    vector<vector<int>> adj(TOTAL);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int u = to_index(x, y);\n            for (int d = 0; d < 6; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (valid(nx, ny)) {\n                    int v = to_index(nx, ny);\n                    adj[u].push_back(v);\n                }\n            }\n        }\n    }\n\n    // Current position of each ball (by number)\n    vector<int> pos(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) {\n        pos[ball[i]] = i;\n    }\n\n    vector<bool> fixed(TOTAL, false);\n    vector<tuple<int, int, int, int>> swaps; // (x1,y1,x2,y2)\n\n    // Helper to perform a swap between two adjacent positions\n    auto do_swap = [&](int i, int j) {\n        // Record the swap\n        auto [x1, y1] = to_coord(i);\n        auto [x2, y2] = to_coord(j);\n        swaps.emplace_back(x1, y1, x2, y2);\n        // Update ball and pos arrays\n        int b1 = ball[i], b2 = ball[j];\n        swap(ball[i], ball[j]);\n        pos[b1] = j;\n        pos[b2] = i;\n    };\n\n    // BFS to find shortest path from src to dest avoiding fixed nodes (except dest)\n    auto bfs = [&](int src, int dest, const vector<bool>& fixed) -> vector<int> {\n        vector<int> parent(TOTAL, -1);\n        vector<bool> visited(TOTAL, false);\n        queue<int> q;\n        q.push(src);\n        visited[src] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            if (u == dest) break;\n            for (int v : adj[u]) {\n                if (!visited[v] && (v == dest || !fixed[v])) {\n                    visited[v] = true;\n                    parent[v] = u;\n                    q.push(v);\n                }\n            }\n        }\n        if (parent[dest] == -1) return {}; // no path\n        vector<int> path;\n        for (int cur = dest; cur != -1; cur = parent[cur]) {\n            path.push_back(cur);\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    // Process positions in row-major order\n    for (int i = 0; i < TOTAL; ++i) {\n        if (fixed[i]) continue;\n        if (ball[i] == target[i]) {\n            fixed[i] = true;\n            continue;\n        }\n        int want = target[i];\n        int src = pos[want];\n        if (src == i) {\n            fixed[i] = true;\n            continue;\n        }\n        // Find path from src to i avoiding fixed nodes (except i)\n        vector<int> path = bfs(src, i, fixed);\n        // In case no path found, we try to relax by allowing fixed nodes temporarily?\n        // For safety, if no path, we simply skip? But should not happen.\n        if (path.empty()) {\n            // Fallback: just swap directly if adjacent? Not necessarily.\n            // We'll try to find any path without avoiding fixed, but that might disturb fixed.\n            // Instead, we can try to find a path that goes through fixed but then we need to re-fix them.\n            // To keep it simple, we assume a path always exists (should be true for connected graph).\n            // If not, we break.\n            continue;\n        }\n        // Perform swaps along the path\n        for (size_t k = 0; k + 1 < path.size(); ++k) {\n            do_swap(path[k], path[k + 1]);\n        }\n        // Now i should have the correct ball\n        fixed[i] = true;\n        // Note: intermediate positions along the path are not fixed, so we leave them.\n    }\n\n    // Output\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nconst int D = 9;\nconst int entrance_i = 0, entrance_j = 4;\n\nint main() {\n    int N;\n    cin >> D >> N;  // D is always 9, but read anyway\n    bool obstacle[D][D] = {false};\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N; // number of containers\n\n    bool occupied[D][D] = {false};\n    int label_of[D][D];\n    int parent_i[D][D], parent_j[D][D];\n    vector<pair<int, int>> children[D][D];\n\n    vector<int> seen_labels;\n\n    // process containers one by one\n    for (int d = 0; d < M; ++d) {\n        int t;\n        cin >> t;\n\n        // BFS from entrance through empty squares\n        int dist[D][D];\n        memset(dist, -1, sizeof(dist));\n        pair<int, int> bfs_parent[D][D];\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            const int di[4] = {1, -1, 0, 0};\n            const int dj[4] = {0, 0, 1, -1};\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                    !obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    bfs_parent[ni][nj] = {i, j};\n                    q.push({ni, nj});\n                }\n            }\n        }\n\n        // collect leaves (empty squares with exactly one empty neighbor)\n        vector<tuple<int, int, int>> leaves; // (distance, i, j)\n        const int di[4] = {1, -1, 0, 0};\n        const int dj[4] = {0, 0, 1, -1};\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == entrance_i && j == entrance_j) continue;\n                if (dist[i][j] == -1) continue;\n                int empty_neighbors = 0;\n                for (int dir = 0; dir < 4; ++dir) {\n                    int ni = i + di[dir], nj = j + dj[dir];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                        !obstacle[ni][nj] && !occupied[ni][nj]) {\n                        empty_neighbors++;\n                    }\n                }\n                if (empty_neighbors == 1) {\n                    leaves.push_back({dist[i][j], i, j});\n                }\n            }\n        }\n\n        // sort leaves by distance (closest first)\n        sort(leaves.begin(), leaves.end());\n\n        // compute quantile of current label among seen labels\n        double quantile;\n        if (seen_labels.empty()) {\n            quantile = 0.0;\n        } else {\n            int count_smaller = 0;\n            for (int lbl : seen_labels) {\n                if (lbl < t) count_smaller++;\n            }\n            quantile = (double)count_smaller / seen_labels.size();\n        }\n\n        // choose leaf according to quantile\n        int L = leaves.size();\n        int idx = (int)round(quantile * (L - 1));\n        idx = max(0, min(L - 1, idx));\n        auto [dist_val, pi, pj] = leaves[idx];\n\n        // output placement\n        cout << pi << \" \" << pj << endl;\n\n        // record placement\n        occupied[pi][pj] = true;\n        label_of[pi][pj] = t;\n        parent_i[pi][pj] = bfs_parent[pi][pj].first;\n        parent_j[pi][pj] = bfs_parent[pi][pj].second;\n        children[parent_i[pi][pj]][parent_j[pi][pj]].push_back({pi, pj});\n\n        seen_labels.push_back(t);\n    }\n\n    // determine and output transport order\n    priority_queue<pair<int, pair<int, int>>,\n                   vector<pair<int, pair<int, int>>>,\n                   greater<>> pq;\n    bool removed[D][D] = {false};\n\n    // initially, containers whose parent is the entrance are removable\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (occupied[i][j] && parent_i[i][j] == entrance_i && parent_j[i][j] == entrance_j) {\n                pq.push({label_of[i][j], {i, j}});\n            }\n        }\n    }\n\n    while (!pq.empty()) {\n        auto [lbl, coords] = pq.top(); pq.pop();\n        int i = coords.first, j = coords.second;\n        cout << i << \" \" << j << endl;\n        removed[i][j] = true;\n\n        // children of the removed container become removable\n        for (auto child : children[i][j]) {\n            int ci = child.first, cj = child.second;\n            pq.push({label_of[ci][cj], {ci, cj}});\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x < p.x || (x == p.x && y < p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\n// BFS to find shortest path between two sets in a graph defined by allowed cells\nvector<Point> bfs_path(const vector<vector<bool>>& allowed, \n                       const set<Point>& start_set, \n                       const set<Point>& end_set,\n                       int n) {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    vector<vector<Point>> prev(n, vector<Point>(n, Point(-1, -1)));\n    queue<Point> q;\n    \n    for (const Point& p : start_set) {\n        visited[p.x][p.y] = true;\n        q.push(p);\n    }\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        if (end_set.count(cur)) {\n            // Reconstruct path\n            vector<Point> path;\n            Point at = cur;\n            while (!(at.x == -1 && at.y == -1)) {\n                path.push_back(at);\n                at = prev[at.x][at.y];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && allowed[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                prev[nx][ny] = cur;\n                q.push(Point(nx, ny));\n            }\n        }\n    }\n    return {}; // No path found\n}\n\n// Check if removing a point disconnects a set of points\nbool is_articulation(const set<Point>& region, const Point& p, int n) {\n    if (!region.count(p)) return false;\n    \n    set<Point> remaining = region;\n    remaining.erase(p);\n    \n    if (remaining.empty()) return false;\n    \n    // Find first point in remaining\n    Point start = *remaining.begin();\n    set<Point> component;\n    queue<Point> q;\n    q.push(start);\n    component.insert(start);\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            Point np(nx, ny);\n            if (remaining.count(np) && !component.count(np)) {\n                component.insert(np);\n                q.push(np);\n            }\n        }\n    }\n    \n    return component.size() != remaining.size();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n = N, m = M;\n    vector<vector<int>> grid(n, vector<int>(n));\n    \n    // Read input\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    // Build adjacency information\n    vector<set<int>> adj_colors(m + 1); // neighbors for each color\n    // For each unordered pair (c,d), store a list of adjacent cell pairs\n    vector<vector<vector<pair<Point, Point>>>> adj_pairs(m + 1, vector<vector<pair<Point, Point>>>(m + 1));\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int color = grid[ni][nj];\n                    if (color != c) {\n                        // Ensure c < color for consistent ordering\n                        if (c < color) {\n                            adj_colors[c].insert(color);\n                            adj_colors[color].insert(c);\n                            adj_pairs[c][color].push_back({Point(i, j), Point(ni, nj)});\n                        } else if (c > color) {\n                            adj_colors[color].insert(c);\n                            adj_colors[c].insert(color);\n                            adj_pairs[color][c].push_back({Point(ni, nj), Point(i, j)});\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Anchor selection: for each edge (c,d), choose one pair\n    vector<set<Point>> anchors(m + 1);\n    \n    for (int c = 1; c <= m; c++) {\n        for (int d : adj_colors[c]) {\n            if (c >= d) continue; // process each edge once\n            \n            // Check if we already have an adjacent pair in anchors\n            bool already_adjacent = false;\n            for (const Point& p1 : anchors[c]) {\n                for (int dir = 0; dir < 4; dir++) {\n                    Point p2(p1.x + dx[dir], p1.y + dy[dir]);\n                    if (anchors[d].count(p2)) {\n                        already_adjacent = true;\n                        break;\n                    }\n                }\n                if (already_adjacent) break;\n            }\n            if (already_adjacent) continue;\n            \n            // Try to find a pair that uses existing anchors\n            bool found = false;\n            for (auto& pr : adj_pairs[c][d]) {\n                Point u = pr.first, v = pr.second;\n                if (anchors[c].count(u)) {\n                    anchors[d].insert(v);\n                    found = true;\n                    break;\n                } else if (anchors[d].count(v)) {\n                    anchors[c].insert(u);\n                    found = true;\n                    break;\n                }\n            }\n            if (!found && !adj_pairs[c][d].empty()) {\n                // Add both cells\n                Point u = adj_pairs[c][d][0].first;\n                Point v = adj_pairs[c][d][0].second;\n                anchors[c].insert(u);\n                anchors[d].insert(v);\n            }\n        }\n    }\n    \n    // For colors with no anchors, add an arbitrary cell\n    for (int c = 1; c <= m; c++) {\n        if (anchors[c].empty()) {\n            // Find any cell of this color\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (grid[i][j] == c) {\n                        anchors[c].insert(Point(i, j));\n                        break;\n                    }\n                }\n                if (!anchors[c].empty()) break;\n            }\n        }\n    }\n    \n    // Build Steiner trees for each color\n    vector<set<Point>> kept(m + 1); // kept cells for each color\n    \n    for (int c = 1; c <= m; c++) {\n        // Create allowed matrix for this color\n        vector<vector<bool>> allowed(n, vector<bool>(n, false));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == c) {\n                    allowed[i][j] = true;\n                }\n            }\n        }\n        \n        set<Point> terminals = anchors[c];\n        set<Point> current = terminals;\n        \n        // Connect components iteratively\n        while (true) {\n            // Find connected components of current\n            vector<set<Point>> components;\n            set<Point> visited;\n            \n            for (const Point& p : current) {\n                if (visited.count(p)) continue;\n                \n                set<Point> comp;\n                queue<Point> q;\n                q.push(p);\n                comp.insert(p);\n                visited.insert(p);\n                \n                while (!q.empty()) {\n                    Point cur = q.front();\n                    q.pop();\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point np(cur.x + dx[d], cur.y + dy[d]);\n                        if (np.x >= 0 && np.x < n && np.y >= 0 && np.y < n && \n                            allowed[np.x][np.y] && current.count(np) && !visited.count(np)) {\n                            comp.insert(np);\n                            visited.insert(np);\n                            q.push(np);\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n            \n            if (components.size() <= 1) break;\n            \n            // Connect first two components\n            set<Point> comp1 = components[0], comp2 = components[1];\n            vector<Point> path = bfs_path(allowed, comp1, comp2, n);\n            \n            if (!path.empty()) {\n                for (const Point& p : path) {\n                    current.insert(p);\n                }\n            } else {\n                // Should not happen since graph is connected\n                break;\n            }\n        }\n        \n        // Prune leaves that are not terminals\n        set<Point> tree = current;\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            vector<Point> to_remove;\n            for (const Point& p : tree) {\n                if (terminals.count(p)) continue;\n                \n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    Point np(p.x + dx[d], p.y + dy[d]);\n                    if (tree.count(np)) deg++;\n                }\n                if (deg <= 1) {\n                    to_remove.push_back(p);\n                }\n            }\n            \n            for (const Point& p : to_remove) {\n                tree.erase(p);\n                changed = true;\n            }\n        }\n        \n        kept[c] = tree;\n    }\n    \n    // Build output grid\n    vector<vector<int>> output(n, vector<int>(n, 0));\n    for (int c = 1; c <= m; c++) {\n        for (const Point& p : kept[c]) {\n            output[p.x][p.y] = c;\n        }\n    }\n    \n    // Check connectivity of 0\n    vector<vector<bool>> visited0(n, vector<bool>(n, false));\n    queue<Point> q0;\n    \n    // Start from boundary 0 cells (connected to outside)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if ((i == 0 || i == n-1 || j == 0 || j == n-1) && output[i][j] == 0) {\n                q0.push(Point(i, j));\n                visited0[i][j] = true;\n            }\n        }\n    }\n    \n    while (!q0.empty()) {\n        Point cur = q0.front();\n        q0.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                output[nx][ny] == 0 && !visited0[nx][ny]) {\n                visited0[nx][ny] = true;\n                q0.push(Point(nx, ny));\n            }\n        }\n    }\n    \n    // If there are unvisited 0 cells, try to fix\n    bool disconnected = false;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0 && !visited0[i][j]) {\n                disconnected = true;\n                break;\n            }\n        }\n        if (disconnected) break;\n    }\n    \n    if (disconnected) {\n        // Try to remove some non-zero cells to connect 0\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] != 0 && !visited0[i][j]) {\n                    int c = output[i][j];\n                    Point p(i, j);\n                    \n                    // Check if this cell can be removed\n                    bool can_remove = true;\n                    \n                    // Check if it's a leaf in its tree and not a terminal\n                    if (kept[c].count(p)) {\n                        int deg = 0;\n                        for (int d = 0; d < 4; d++) {\n                            Point np(i + dx[d], j + dy[d]);\n                            if (kept[c].count(np)) deg++;\n                        }\n                        if (deg > 1) can_remove = false;\n                        \n                        // Check if it's the only anchor for some neighbor\n                        for (int d : adj_colors[c]) {\n                            if (d == 0) continue;\n                            bool has_other = false;\n                            for (const Point& q : kept[c]) {\n                                if (q == p) continue;\n                                for (int dir = 0; dir < 4; dir++) {\n                                    Point nq(q.x + dx[dir], q.y + dy[dir]);\n                                    if (nq.x >= 0 && nq.x < n && nq.y >= 0 && nq.y < n && \n                                        output[nq.x][nq.y] == d) {\n                                        has_other = true;\n                                        break;\n                                    }\n                                }\n                                if (has_other) break;\n                            }\n                            if (!has_other) {\n                                can_remove = false;\n                                break;\n                            }\n                        }\n                    } else {\n                        can_remove = false;\n                    }\n                    \n                    if (can_remove) {\n                        // Change to 0 and update\n                        output[i][j] = 0;\n                        kept[c].erase(p);\n                        \n                        // Re-run BFS for 0 connectivity\n                        fill(visited0.begin(), visited0.end(), vector<bool>(n, false));\n                        queue<Point> q0;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if ((ii == 0 || ii == n-1 || jj == 0 || jj == n-1) && output[ii][jj] == 0) {\n                                    q0.push(Point(ii, jj));\n                                    visited0[ii][jj] = true;\n                                }\n                            }\n                        }\n                        while (!q0.empty()) {\n                            Point cur = q0.front();\n                            q0.pop();\n                            for (int d = 0; d < 4; d++) {\n                                int nx = cur.x + dx[d];\n                                int ny = cur.y + dy[d];\n                                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                                    output[nx][ny] == 0 && !visited0[nx][ny]) {\n                                    visited0[nx][ny] = true;\n                                    q0.push(Point(nx, ny));\n                                }\n                            }\n                        }\n                        \n                        // Check if still disconnected\n                        disconnected = false;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if (output[ii][jj] == 0 && !visited0[ii][jj]) {\n                                    disconnected = true;\n                                    break;\n                                }\n                            }\n                            if (disconnected) break;\n                        }\n                        if (!disconnected) break;\n                    }\n                }\n            }\n            if (!disconnected) break;\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\n// perform a query with given left and right sets, return the comparison result\nchar query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string s;\n    cin >> s;\n    queries_used++;\n    return s[0];\n}\n\n// compare two individual items\nchar compare(int i, int j) {\n    return query({i}, {j});\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    vector<int> items;  // sorted order as much as we know\n\n    // Insert items one by one using binary search with comparisons\n    for (int i = 0; i < N; ++i) {\n        if (queries_used >= Q) {\n            // no queries left, just append\n            items.push_back(i);\n            continue;\n        }\n        int left = 0, right = items.size();\n        while (left < right && queries_used < Q) {\n            int mid = (left + right) / 2;\n            char res = compare(i, items[mid]);\n            if (res == '<') {\n                right = mid;\n            } else {\n                left = mid + 1;\n            }\n        }\n        items.insert(items.begin() + left, i);\n    }\n\n    // Use any remaining queries (dummy comparisons)\n    while (queries_used < Q) {\n        compare(0, 1);  // always valid as N >= 2\n    }\n\n    // Assign items to buckets in snake order according to the (partially) sorted list\n    vector<int> ans(N);\n    for (int i = 0; i < N; ++i) {\n        int item = items[i];\n        int bucket = i % D;\n        if ((i / D) % 2 == 1) {\n            bucket = D - 1 - bucket;\n        }\n        ans[item] = bucket;\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    int h = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    for (int v = 1; v <= n; ++v) {\n        // Find the stack and position of box v\n        int s = -1, pos = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == v) {\n                    s = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (pos == (int)stacks[s].size() - 1) {\n            // v is already on top: remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        } else {\n            // Need to move the boxes above v\n            int T = stacks[s].back();  // top of the group to be moved\n            // Choose destination stack d according to the heuristic\n            int d = -1;\n            bool found_empty = false;\n            int empty_d = -1;\n            int best_d = -1;\n            int best_top = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if (stacks[i].empty()) {\n                    found_empty = true;\n                    if (empty_d == -1) empty_d = i;\n                } else {\n                    int top = stacks[i].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        best_d = i;\n                    }\n                }\n            }\n\n            if (found_empty) {\n                if (best_d == -1 || T > best_top) {\n                    d = empty_d;\n                } else {\n                    d = best_d;\n                }\n            } else {\n                d = best_d;\n            }\n\n            // Move the suffix starting at the box just above v\n            int w = stacks[s][pos + 1];\n            cout << w << \" \" << d + 1 << \"\\n\";\n\n            vector<int> suffix(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[s].erase(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[d].insert(stacks[d].end(), suffix.begin(), suffix.end());\n\n            // Now v is on top, remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        }\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\nusing namespace std;\n\nconst int dx[] = {1, -1, 0, 0}; // D, U, R, L\nconst int dy[] = {0, 0, 1, -1};\nconst char dir_char[] = {'D', 'U', 'R', 'L'};\nconst char opp_char[] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<bool>> visited;\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (visited[ni][nj]) continue;\n        // check wall\n        if (d == 0 && h[i][j] == '1') continue;      // down\n        if (d == 1 && h[ni][nj] == '1') continue;    // up\n        if (d == 2 && v[i][j] == '1') continue;      // right\n        if (d == 3 && v[i][nj] == '1') continue;     // left\n        cout << dir_char[d];\n        dfs(ni, nj);\n        cout << opp_char[d];\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\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    visited.assign(N, vector<bool>(N, false));\n    dfs(0, 0);\n    cout << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nstruct Candidate {\n    vector<pii> pos;      // 5 positions\n    int internal_cost;    // cost to type this occurrence from scratch\n    vector<int> tail_cost; // tail_cost[k]: cost from position k to end (including letter at k)\n};\n\nint manhattan(const pii& a, const pii& b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\nint compute_cost(const vector<int>& order_targets, \n                 const vector<int>& order_candidate_idx,\n                 const vector<vector<Candidate>>& candidates,\n                 const vector<vector<vector<int>>>& valid,\n                 const pii& start) {\n    int total = 0;\n    pii cur_pos = start;\n    int cur_target = -1;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& cand = candidates[j][order_candidate_idx[i]];\n        if (cur_target == -1) {\n            total += manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n        } else {\n            int best_add = 1e9;\n            for (int k : valid[cur_target][j]) {\n                int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                if (add < best_add) best_add = add;\n            }\n            total += best_add;\n        }\n        cur_target = j;\n        cur_pos = cand.pos[4];\n    }\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    pii start;\n    cin >> start.first >> start.second;\n\n    vector<vector<char>> A(N, vector<char>(N));\n    vector<vector<pii>> pos_list(26); // positions for each letter\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            pos_list[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n\n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n\n    // Random number generator\n    mt19937 rng(123456);\n    uniform_int_distribution<int> dist;\n\n    const int CANDIDATE_COUNT = 100;\n    const int KEEP = 15;\n\n    vector<vector<Candidate>> candidates(M);\n\n    // Generate candidate occurrences for each target\n    for (int idx = 0; idx < M; ++idx) {\n        const string& t = targets[idx];\n        vector<Candidate> cands;\n        for (int iter = 0; iter < CANDIDATE_COUNT; ++iter) {\n            vector<pii> pos(5);\n            for (int k = 0; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                uniform_int_distribution<int> d(0, (int)lst.size() - 1);\n                pos[k] = lst[d(rng)];\n            }\n\n            // Compute internal cost\n            int internal = 5; // cost for typing the letters themselves\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1; // cost to type the last letter\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n\n        // Keep the best KEEP candidates by internal cost\n        sort(cands.begin(), cands.end(),\n             [](const Candidate& a, const Candidate& b) { return a.internal_cost < b.internal_cost; });\n        if (cands.size() > KEEP) cands.resize(KEEP);\n        candidates[idx] = cands;\n    }\n\n    // Precompute valid overlaps between targets\n    vector<vector<vector<int>>> valid(M, vector<vector<int>>(M));\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            const string& si = targets[i];\n            const string& sj = targets[j];\n            vector<int> v;\n            for (int k = 1; k <= 4; ++k) {\n                if (si.substr(5 - k) == sj.substr(0, k)) {\n                    v.push_back(k);\n                }\n            }\n            v.push_back(0); // k=0 always allowed\n            valid[i][j] = v;\n        }\n    }\n\n    // Greedy construction of the path\n    vector<int> order_targets;\n    vector<int> order_candidate_idx;\n    vector<bool> covered(M, false);\n\n    pii cur_pos = start;\n    int cur_target = -1;\n\n    for (int step = 0; step < M; ++step) {\n        int best_add = 1e9;\n        int best_j = -1, best_c = -1;\n\n        for (int j = 0; j < M; ++j) {\n            if (covered[j]) continue;\n            for (size_t c = 0; c < candidates[j].size(); ++c) {\n                const Candidate& cand = candidates[j][c];\n                if (cur_target == -1) {\n                    // First target\n                    int add = manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n                    if (add < best_add) {\n                        best_add = add;\n                        best_j = j;\n                        best_c = c;\n                    }\n                } else {\n                    for (int k : valid[cur_target][j]) {\n                        int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                        if (add < best_add) {\n                            best_add = add;\n                            best_j = j;\n                            best_c = c;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Append the chosen target\n        covered[best_j] = true;\n        order_targets.push_back(best_j);\n        order_candidate_idx.push_back(best_c);\n\n        // Update current state\n        cur_target = best_j;\n        cur_pos = candidates[best_j][best_c].pos[4];\n    }\n\n    // Local search to improve order\n    int current_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < M - 1; ++i) {\n            // Try swapping i and i+1\n            swap(order_targets[i], order_targets[i + 1]);\n            swap(order_candidate_idx[i], order_candidate_idx[i + 1]);\n            int new_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n            if (new_cost < current_cost) {\n                current_cost = new_cost;\n                improved = true;\n            } else {\n                // Swap back\n                swap(order_targets[i], order_targets[i + 1]);\n                swap(order_candidate_idx[i], order_candidate_idx[i + 1]);\n            }\n        }\n    }\n\n    // Build the output sequence of moves\n    vector<pii> moves;\n    int cur_target_move = -1;\n    pii cur_pos_move = start;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& occ = candidates[j][order_candidate_idx[i]];\n        if (cur_target_move == -1) {\n            for (int k = 0; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        } else {\n            int best_k = 0;\n            int best_add = 1e9;\n            for (int k : valid[cur_target_move][j]) {\n                int add = manhattan(cur_pos_move, occ.pos[k]) + occ.tail_cost[k];\n                if (add < best_add) {\n                    best_add = add;\n                    best_k = k;\n                }\n            }\n            for (int k = best_k; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        }\n        cur_target_move = j;\n        cur_pos_move = occ.pos[4];\n    }\n\n    // Output the moves\n    for (const pii& p : moves) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (not used in this simple solution)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n    \n    vector<pair<int, int>> oil_cells;\n    \n    // Drill every square\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            int val;\n            cin >> val;\n            if (val > 0) {\n                oil_cells.push_back({i, j});\n            }\n        }\n    }\n    \n    // Output the guess\n    cout << \"a \" << oil_cells.size();\n    for (auto [i, j] : oil_cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    // Read response (should be 1)\n    int resp;\n    cin >> resp;\n    // If response is 0, we could try again, but drilling all should be correct.\n    // For safety, if resp == 0, we could drill again? But problem says operation ends if correct.\n    // We'll just exit.\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <cassert>\nusing namespace std;\n\nconst int W = 1000;\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    int area() const { return (x2 - x1) * (y2 - y1); }\n};\n\n// Greedy allocation of target areas B_k\nvector<long long> allocateB(const vector<vector<int>>& A, int D, int N) {\n    vector<long long> B(N, 0);\n    long long total_remaining = (long long)W * W;\n    // For each k, collect desires and sort\n    vector<vector<int>> sortedA(N);\n    for (int k = 0; k < N; ++k) {\n        for (int d = 0; d < D; ++d) {\n            sortedA[k].push_back(A[d][k]);\n        }\n        sort(sortedA[k].begin(), sortedA[k].end());\n    }\n    // Create segments: each (benefit, length, k)\n    struct Segment {\n        int benefit, len, k;\n        bool operator<(const Segment& other) const {\n            return benefit < other.benefit; // max-heap\n        }\n    };\n    vector<Segment> segments;\n    for (int k = 0; k < N; ++k) {\n        int prev = 0;\n        for (size_t i = 0; i < sortedA[k].size(); ++i) {\n            int cur = sortedA[k][i];\n            if (cur > prev) {\n                int benefit = 100 * (D - i);\n                int len = cur - prev;\n                segments.push_back({benefit, len, k});\n            }\n            prev = cur;\n        }\n        // After the last desire, benefit becomes 0, ignore.\n    }\n    priority_queue<Segment> pq(segments.begin(), segments.end());\n    while (total_remaining > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        if (seg.benefit == 0) break;\n        long long take = min((long long)seg.len, total_remaining);\n        B[seg.k] += take;\n        total_remaining -= take;\n        seg.len -= take;\n        if (seg.len > 0) {\n            pq.push(seg);\n        }\n    }\n    // Distribute remaining area arbitrarily (benefit 0)\n    if (total_remaining > 0) {\n        for (int k = 0; k < N && total_remaining > 0; ++k) {\n            long long add = min(total_remaining, (long long)1);\n            B[k] += add;\n            total_remaining -= add;\n        }\n    }\n    return B;\n}\n\n// Shelf packing for rectangles with target areas B\nvector<Rect> packRectangles(const vector<long long>& B) {\n    int N = B.size();\n    vector<Rect> rects(N);\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    // For each rectangle, choose dimensions to achieve at least B[k] with minimal waste\n    vector<pair<int, int>> dims(N); // (height, width)\n    for (int k = 0; k < N; ++k) {\n        long long area = B[k];\n        int best_h = 1, best_w = area;\n        long long best_waste = best_w * best_h - area;\n        for (int h = 1; h <= W; ++h) {\n            long long w = (area + h - 1) / h; // ceil\n            if (w > W) continue;\n            long long waste = w * h - area;\n            if (waste < best_waste) {\n                best_waste = waste;\n                best_h = h;\n                best_w = w;\n            }\n        }\n        dims[k] = {best_h, best_w};\n    }\n    // Sort indices by height descending\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return dims[i].first > dims[j].first;\n    });\n    // Shelf packing\n    struct Shelf {\n        int y1, y2; // vertical range\n        int x;      // current x position\n    };\n    vector<Shelf> shelves;\n    int current_y = 0;\n    for (int idx : indices) {\n        int h = dims[idx].first, w = dims[idx].second;\n        bool placed = false;\n        for (auto& shelf : shelves) {\n            if (shelf.y2 - shelf.y1 >= h && shelf.x + w <= W) {\n                rects[idx] = {shelf.x, shelf.y1, shelf.x + w, shelf.y1 + h};\n                shelf.x += w;\n                placed = true;\n                break;\n            }\n        }\n        if (!placed) {\n            // Create new shelf at current_y\n            int y2 = min(W, current_y + h);\n            Shelf shelf{current_y, y2, 0};\n            rects[idx] = {0, current_y, w, y2};\n            shelf.x = w;\n            shelves.push_back(shelf);\n            current_y = y2;\n            placed = true;\n        }\n    }\n    return rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int 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) {\n            cin >> A[d][k];\n        }\n    }\n\n    vector<long long> B = allocateB(A, D, N);\n    vector<Rect> rects = packRectangles(B);\n\n    // Compute actual areas and sort indices by area ascending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return rects[i].area() < rects[j].area();\n    });\n\n    // Output for each day\n    for (int d = 0; d < D; ++d) {\n        // Sort reservations by desired area ascending\n        vector<int> day_order(N);\n        iota(day_order.begin(), day_order.end(), 0);\n        sort(day_order.begin(), day_order.end(), [&](int i, int j) {\n            return A[d][i] < A[d][j];\n        });\n        // Create assignment: smallest rect to smallest desire\n        vector<Rect> assigned(N);\n        for (int i = 0; i < N; ++i) {\n            int k = day_order[i];          // reservation index\n            int rect_idx = order[i];       // rectangle index\n            assigned[k] = rects[rect_idx];\n        }\n        // Output in reservation order (0..N-1)\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = assigned[k];\n            cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\nstruct Move {\n    int m, p, q;\n    vector<pair<int, int>> cells; // (index, value)\n};\n\nstruct State {\n    array<int, N*N> board;\n    long long score;\n    State* parent;\n    int m, p, q; // move that led to this state, or -1 for initial\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    vector<int> a(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i*N + j];\n        }\n    }\n\n    vector<array<array<int, 3>, 3>> 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][i][j];\n            }\n        }\n    }\n\n    // Precompute all possible moves\n    vector<Move> moves;\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                Move move;\n                move.m = m;\n                move.p = p;\n                move.q = q;\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        int idx = (p+i)*N + (q+j);\n                        int val = stamps[m][i][j] % MOD;\n                        move.cells.emplace_back(idx, val);\n                    }\n                }\n                moves.push_back(move);\n            }\n        }\n    }\n\n    // Beam search\n    const int beam_width = 25;\n    vector<State*> all_states;\n    State* initial = new State;\n    initial->parent = nullptr;\n    initial->m = initial->p = initial->q = -1;\n    copy(a.begin(), a.end(), initial->board.begin());\n    initial->score = accumulate(a.begin(), a.end(), 0LL);\n    all_states.push_back(initial);\n\n    State* global_best = initial;\n    long long global_best_score = initial->score;\n\n    vector<State*> current_beam;\n    current_beam.push_back(initial);\n\n    for (int step = 0; step < K; ++step) {\n        vector<State*> candidates;\n\n        for (State* s : current_beam) {\n            // Option: do nothing\n            candidates.push_back(s);\n\n            // Try every move\n            for (const Move& move : moves) {\n                array<int, N*N> new_board = s->board;\n                long long gain = 0;\n\n                for (auto [idx, val] : move.cells) {\n                    int old_rem = new_board[idx];\n                    int new_rem = (old_rem + val) % MOD;\n                    gain += new_rem - old_rem;\n                    new_board[idx] = new_rem;\n                }\n\n                long long new_score = s->score + gain;\n\n                State* new_state = new State;\n                new_state->board = new_board;\n                new_state->score = new_score;\n                new_state->parent = s;\n                new_state->m = move.m;\n                new_state->p = move.p;\n                new_state->q = move.q;\n\n                candidates.push_back(new_state);\n                all_states.push_back(new_state);\n\n                if (new_score > global_best_score) {\n                    global_best = new_state;\n                    global_best_score = new_score;\n                }\n            }\n        }\n\n        // Select top beam_width states\n        sort(candidates.begin(), candidates.end(),\n             [](State* a, State* b) { return a->score > b->score; });\n\n        if (!candidates.empty() && candidates[0]->score > global_best_score) {\n            global_best = candidates[0];\n            global_best_score = candidates[0]->score;\n        }\n\n        current_beam.clear();\n        for (int i = 0; i < beam_width && i < candidates.size(); ++i) {\n            current_beam.push_back(candidates[i]);\n        }\n    }\n\n    // Reconstruct the sequence of moves\n    vector<tuple<int, int, int>> sequence;\n    State* cur = global_best;\n    while (cur->parent != nullptr) {\n        sequence.emplace_back(cur->m, cur->p, cur->q);\n        cur = cur->parent;\n    }\n    reverse(sequence.begin(), sequence.end());\n\n    // Output\n    cout << sequence.size() << \"\\n\";\n    for (auto [m, p, q] : sequence) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    // Clean up\n    for (State* s : all_states) {\n        delete s;\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Crane {\n    int r, c;\n    int holding = -1; // container ID or -1\n    enum State { IDLE, MOVING_TO_PICKUP, PICKING_UP, MOVING_TO_DROPOFF, DROPPING_OFF, WAITING };\n    State state = IDLE;\n    int target_r = -1, target_c = -1;\n    int dest_row = -1; // for large crane: destination row for parking\n    vector<pair<int,int>> path;\n    int path_idx = 0;\n    \n    Crane(int r, int c) : r(r), c(c) {}\n};\n\nint grid[N][N]; // -1 empty, else container ID\nint gate_next_idx[N]; // next index to place for each left gate\nvector<int> gate_queues[N]; // A[i][0..4]\nint dispatch_next_needed[N]; // next needed ID for each row\nvector<int> dispatched[N]; // dispatched IDs per row\nbool container_dispatched[N*N] = {false};\nCrane cranes[N] = {Crane(0,0), Crane(1,0), Crane(2,0), Crane(3,0), Crane(4,0)};\n\n// Check if a cell is occupied by a container\nbool has_container(int r, int c) {\n    return grid[r][c] != -1;\n}\n\n// Check if a cell is occupied by another crane (excluding self)\nbool has_other_crane(int r, int c, int self_idx) {\n    for (int i = 0; i < N; ++i) {\n        if (i != self_idx && cranes[i].r == r && cranes[i].c == c) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a crane can move to a cell\nbool can_move_to(int r, int c, int crane_idx, bool carrying) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return false;\n    if (has_other_crane(r, c, crane_idx)) return false;\n    if (carrying && has_container(r, c)) return false; // small crane with container can't move to occupied\n    // Large crane (index 0) can move to cells with containers even while carrying\n    if (crane_idx == 0) return true;\n    return true;\n}\n\n// BFS to find next move direction from (sr,sc) to (tr,tc)\npair<int,int> find_next_move(int sr, int sc, int tr, int tc, int crane_idx, bool carrying) {\n    if (sr == tr && sc == tc) return {0, 0};\n    \n    // BFS\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    visited[sr][sc] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) break;\n        \n        int dr[] = {-1, 1, 0, 0};\n        int dc[] = {0, 0, -1, 1};\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (can_move_to(nr, nc, crane_idx, carrying) && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                prev[nr][nc] = {r, c};\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path and return first step\n    if (!visited[tr][tc]) return {0, 0}; // no path, stay\n    \n    // Trace back\n    int r = tr, c = tc;\n    while (prev[r][c] != make_pair(sr, sc)) {\n        auto [pr, pc] = prev[r][c];\n        r = pr; c = pc;\n    }\n    // Now (r,c) is one step from (sr,sc)\n    return {r - sr, c - sc};\n}\n\n// Find free parking spot in row (columns 1-3)\nint find_free_parking(int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (!has_container(row, c) && !has_other_crane(row, c, -1)) {\n            return c;\n        }\n    }\n    return -1;\n}\n\n// Check if a container is parked in a given row\nbool is_parked_in_row(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return true;\n    }\n    return false;\n}\n\n// Find the cell where a container is parked in a row\npair<int,int> find_parked_cell(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return {row, c};\n    }\n    return {-1, -1};\n}\n\nvoid simulate(vector<string>& actions) {\n    // Initialize\n    memset(grid, -1, sizeof(grid));\n    fill(gate_next_idx, gate_next_idx + N, 0);\n    fill(dispatch_next_needed, dispatch_next_needed + N, 0);\n    for (int i = 0; i < N; ++i) dispatched[i].clear();\n    fill(container_dispatched, container_dispatched + N*N, false);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].holding = -1;\n        cranes[i].state = Crane::IDLE;\n        cranes[i].path.clear();\n    }\n    \n    actions.resize(N);\n    for (int t = 0; t < MAX_TURNS; ++t) {\n        // Step 1: Place containers at gates\n        for (int i = 0; i < N; ++i) {\n            if (gate_next_idx[i] >= N) continue;\n            bool can_place = true;\n            if (has_container(i, 0)) can_place = false;\n            for (int k = 0; k < N; ++k) {\n                if (cranes[k].r == i && cranes[k].c == 0 && cranes[k].holding != -1) {\n                    can_place = false;\n                    break;\n                }\n            }\n            if (can_place) {\n                int container_id = gate_queues[i][gate_next_idx[i]];\n                grid[i][0] = container_id;\n                gate_next_idx[i]++;\n            }\n        }\n        \n        // Step 2: Crane actions\n        vector<char> turn_actions(N, '.');\n        \n        // Process large crane (index 0) first\n        auto& lc = cranes[0];\n        switch (lc.state) {\n            case Crane::IDLE: {\n                // Look for a container at a left gate that needs to be moved to parking\n                for (int i = 0; i < N; ++i) {\n                    if (!has_container(i, 0)) continue;\n                    int container_id = grid[i][0];\n                    int dest = container_id / N;\n                    int free_c = find_free_parking(dest);\n                    if (free_c != -1) {\n                        // Set target to pick up this container\n                        lc.target_r = i;\n                        lc.target_c = 0;\n                        lc.dest_row = dest;\n                        lc.state = Crane::MOVING_TO_PICKUP;\n                        break;\n                    }\n                }\n                break;\n            }\n            case Crane::MOVING_TO_PICKUP: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, lc.holding != -1);\n                if (dr == 0 && dc == 0) {\n                    // Reached, pick up\n                    turn_actions[0] = 'P';\n                    lc.holding = grid[lc.r][lc.c];\n                    grid[lc.r][lc.c] = -1;\n                    lc.state = Crane::PICKING_UP;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::PICKING_UP: {\n                // Set target for dropoff\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c == -1) {\n                    // No free spot, wait\n                    lc.state = Crane::WAITING;\n                } else {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n            case Crane::MOVING_TO_DROPOFF: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, true);\n                if (dr == 0 && dc == 0) {\n                    // Reached, drop\n                    turn_actions[0] = 'Q';\n                    grid[lc.r][lc.c] = lc.holding;\n                    lc.holding = -1;\n                    lc.state = Crane::DROPPING_OFF;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::DROPPING_OFF: {\n                lc.state = Crane::IDLE;\n                break;\n            }\n            case Crane::WAITING: {\n                // Check if a free spot became available\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c != -1) {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n        }\n        \n        // Process small cranes (indices 1-4)\n        for (int i = 1; i < N; ++i) {\n            auto& sc = cranes[i];\n            switch (sc.state) {\n                case Crane::IDLE: {\n                    int need = dispatch_next_needed[i];\n                    if (need < i*N || need >= (i+1)*N) break; // invalid\n                    if (container_dispatched[need]) break;\n                    auto [pr, pc] = find_parked_cell(need, i);\n                    if (pr != -1) {\n                        sc.target_r = pr;\n                        sc.target_c = pc;\n                        sc.state = Crane::MOVING_TO_PICKUP;\n                    }\n                    break;\n                }\n                case Crane::MOVING_TO_PICKUP: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, sc.holding != -1);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'P';\n                        sc.holding = grid[sc.r][sc.c];\n                        grid[sc.r][sc.c] = -1;\n                        sc.state = Crane::PICKING_UP;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::PICKING_UP: {\n                    sc.target_r = i;\n                    sc.target_c = N-1;\n                    sc.state = Crane::MOVING_TO_DROPOFF;\n                    break;\n                }\n                case Crane::MOVING_TO_DROPOFF: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, true);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'Q';\n                        grid[sc.r][sc.c] = sc.holding;\n                        sc.holding = -1;\n                        sc.state = Crane::DROPPING_OFF;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::DROPPING_OFF: {\n                    sc.state = Crane::IDLE;\n                    break;\n                }\n                case Crane::WAITING: {\n                    break;\n                }\n            }\n        }\n        \n        // Step 3: Dispatch containers from right gates\n        for (int i = 0; i < N; ++i) {\n            if (has_container(i, N-1)) {\n                int container_id = grid[i][N-1];\n                dispatched[i].push_back(container_id);\n                container_dispatched[container_id] = true;\n                grid[i][N-1] = -1;\n                // Update next needed for this row\n                while (dispatch_next_needed[i] < (i+1)*N && container_dispatched[dispatch_next_needed[i]]) {\n                    dispatch_next_needed[i]++;\n                }\n            }\n        }\n        \n        // Record actions\n        for (int i = 0; i < N; ++i) {\n            actions[i] += turn_actions[i];\n        }\n        \n        // Check if all containers dispatched\n        bool all_done = true;\n        for (int id = 0; id < N*N; ++id) {\n            if (!container_dispatched[id]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; ++i) {\n        gate_queues[i].resize(N);\n        for (int j = 0; j < N; ++j) {\n            cin >> gate_queues[i][j];\n        }\n    }\n    \n    vector<string> actions;\n    simulate(actions);\n    \n    // Pad shorter strings with '.'\n    size_t max_len = 0;\n    for (const string& s : actions) {\n        max_len = max(max_len, s.size());\n    }\n    for (string& s : actions) {\n        if (s.size() < max_len) {\n            s.append(max_len - s.size(), '.');\n        }\n    }\n    \n    for (const string& s : actions) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 20;\n\n// Generate snake path by rows: (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> ... -> (N-1,0)\nvector<pair<int, int>> generate_path_rows() {\n    vector<pair<int, int>> path;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) path.emplace_back(i, j);\n        } else {\n            for (int j = N - 1; j >= 0; --j) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate snake path by columns: (0,0) -> (1,0) -> ... -> (N-1,0) -> (N-1,1) -> ... -> (0,N-1)\nvector<pair<int, int>> generate_path_cols() {\n    vector<pair<int, int>> path;\n    for (int j = 0; j < N; ++j) {\n        if (j % 2 == 0) {\n            for (int i = 0; i < N; ++i) path.emplace_back(i, j);\n        } else {\n            for (int i = N - 1; i >= 0; --i) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate clockwise spiral path starting at (0,0)\nvector<pair<int, int>> generate_spiral_cw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) path.emplace_back(top, j);\n        top++;\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, right);\n        right--;\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(bottom, j);\n            bottom--;\n        }\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, left);\n            left++;\n        }\n    }\n    return path;\n}\n\n// Generate counterclockwise spiral path starting at (0,0)\nvector<pair<int, int>> generate_spiral_ccw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, left);\n        left++;\n        for (int j = left; j <= right; ++j) path.emplace_back(bottom, j);\n        bottom--;\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, right);\n            right--;\n        }\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(top, j);\n            top++;\n        }\n    }\n    return path;\n}\n\n// Compute the total load-distance for a loading tour along the given path\nint compute_load_distance(const vector<pair<int, int>>& path, const vector<vector<int>>& h) {\n    int load = 0;\n    int total = 0;\n    for (int idx = 0; idx < (int)path.size(); ++idx) {\n        int i = path[idx].first, j = path[idx].second;\n        if (h[i][j] > 0) load += h[i][j];\n        if (idx < (int)path.size() - 1) total += load;\n    }\n    return total;\n}\n\n// Determine move direction from (i,j) to (ni,nj) assuming they are adjacent\nstring get_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return \"U\";\n    if (ni == i + 1) return \"D\";\n    if (nj == j - 1) return \"L\";\n    if (nj == j + 1) return \"R\";\n    assert(false);\n    return \"\";\n}\n\nint main() {\n    // Read input\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    // Generate candidate paths\n    vector<vector<pair<int, int>>> candidates;\n    candidates.push_back(generate_path_rows());\n    candidates.push_back(generate_path_cols());\n    candidates.push_back(generate_spiral_cw());\n    candidates.push_back(generate_spiral_ccw());\n\n    // Choose the path with smallest load-distance for loading tour\n    int best_dist = 1e9;\n    vector<pair<int, int>> best_path;\n    for (const auto& path : candidates) {\n        int dist = compute_load_distance(path, h);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_path = path;\n        }\n    }\n\n    // Make a copy of heights for simulation\n    vector<vector<int>> cur_h = h;\n    vector<string> ops;\n    int load = 0;\n\n    // Loading tour along best_path\n    int cur_i = best_path[0].first, cur_j = best_path[0].second;\n    for (int idx = 0; idx < (int)best_path.size(); ++idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Load if positive\n        if (cur_h[i][j] > 0) {\n            int d = cur_h[i][j];\n            ops.push_back(\"+\" + to_string(d));\n            load += d;\n            cur_h[i][j] = 0;\n        }\n        // Move to next cell if not last\n        if (idx < (int)best_path.size() - 1) {\n            int ni = best_path[idx+1].first, nj = best_path[idx+1].second;\n            ops.push_back(get_move(cur_i, cur_j, ni, nj));\n            cur_i = ni;\n            cur_j = nj;\n        }\n    }\n\n    // Unloading tour along the reverse of best_path\n    for (int idx = (int)best_path.size() - 1; idx >= 0; --idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Unload if negative\n        if (cur_h[i][j] < 0) {\n            int amount = min(load, -cur_h[i][j]);\n            if (amount > 0) {\n                ops.push_back(\"-\" + to_string(amount));\n                load -= amount;\n                cur_h[i][j] += amount;\n            }\n        }\n        // Move to previous cell if not first\n        if (idx > 0) {\n            int pi = best_path[idx-1].first, pj = best_path[idx-1].second;\n            ops.push_back(get_move(cur_i, cur_j, pi, pj));\n            cur_i = pi;\n            cur_j = pj;\n        }\n    }\n\n    // Output the operation sequence\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <utility>\n#include <set>\n#include <cstdlib>\n#include <ctime>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int T = 10;\nconst int K = 2 * N * (N - 1); // 60\nconst int MAX_ITER = 1000;     // iterations for local optimization\n\n// Global seeds for current turn\nvector<vector<int>> seeds(K, vector<int>(M));\n\n// Compute potential max sum for a pair of seeds (indices)\nint potential_max(int a, int b) {\n    int sum = 0;\n    for (int l = 0; l < M; ++l) {\n        sum += max(seeds[a][l], seeds[b][l]);\n    }\n    return sum;\n}\n\n// Compute total edge score for the grid\nint compute_total_score(const vector<vector<int>>& grid) {\n    int total = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i + 1 < N) total += potential_max(grid[i][j], grid[i + 1][j]);\n            if (j + 1 < N) total += potential_max(grid[i][j], grid[i][j + 1]);\n        }\n    }\n    return total;\n}\n\nint main() {\n    srand(time(0));\n\n    // Read initial seeds\n    for (int i = 0; i < K; ++i) {\n        for (int l = 0; l < M; ++l) {\n            cin >> seeds[i][l];\n        }\n    }\n\n    // Center of the grid (0-indexed)\n    const int center_i = 3, center_j = 3;\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Compute total sums\n        vector<int> sums(K, 0);\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                sums[i] += seeds[i][l];\n            }\n        }\n\n        // Select top 35 seeds by sum\n        vector<int> indices(K);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(),\n             [&](int i, int j) { return sums[i] > sums[j]; });\n        vector<int> top35(indices.begin(), indices.begin() + 35);\n        int champion_idx = top35[0];\n\n        // Choose one extra seed that is most complementary to the champion\n        int best_extra = -1;\n        int best_extra_P = -1;\n        for (int i = 35; i < K; ++i) {\n            int idx = indices[i];\n            int P_val = 0;\n            for (int l = 0; l < M; ++l) {\n                P_val += max(seeds[champion_idx][l], seeds[idx][l]);\n            }\n            if (P_val > best_extra_P) {\n                best_extra_P = P_val;\n                best_extra = idx;\n            }\n        }\n        // Combine to form the 36 seeds to plant\n        vector<int> plant_indices = top35;\n        plant_indices.push_back(best_extra);\n\n        // Recompute champion if the extra seed happens to be better (unlikely)\n        for (int idx : plant_indices) {\n            if (sums[idx] > sums[champion_idx]) {\n                champion_idx = idx;\n            }\n        }\n\n        // Compute complementarity for mates (only from plant_indices, excluding champion)\n        vector<pair<int, int>> candidate_P; // (P, index)\n        for (int idx : plant_indices) {\n            if (idx == champion_idx) continue;\n            int P_val = 0;\n            for (int l = 0; l < M; ++l) {\n                P_val += max(seeds[champion_idx][l], seeds[idx][l]);\n            }\n            candidate_P.emplace_back(P_val, idx);\n        }\n        sort(candidate_P.begin(), candidate_P.end(), greater<>());\n\n        // Choose up to 4 mates\n        vector<int> mate_indices;\n        for (int i = 0; i < min(4, (int)candidate_P.size()); ++i) {\n            mate_indices.push_back(candidate_P[i].second);\n        }\n\n        // Initial grid assignment\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> seed_used(K, false);\n\n        // Place champion at center\n        grid[center_i][center_j] = champion_idx;\n        seed_used[champion_idx] = true;\n\n        // Place mates in the four orthogonal neighbours\n        vector<pair<int, int>> offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        for (int i = 0; i < (int)mate_indices.size(); ++i) {\n            int ni = center_i + offsets[i].first;\n            int nj = center_j + offsets[i].second;\n            grid[ni][nj] = mate_indices[i];\n            seed_used[mate_indices[i]] = true;\n        }\n\n        // Collect remaining seeds from plant_indices\n        vector<int> remaining_seeds;\n        for (int idx : plant_indices) {\n            if (!seed_used[idx]) {\n                remaining_seeds.push_back(idx);\n            }\n        }\n\n        // Collect empty cells\n        vector<pair<int, int>> empty_cells;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == -1) {\n                    empty_cells.emplace_back(i, j);\n                }\n            }\n        }\n\n        // Fill the remaining cells\n        for (size_t i = 0; i < remaining_seeds.size(); ++i) {\n            auto [r, c] = empty_cells[i];\n            grid[r][c] = remaining_seeds[i];\n        }\n\n        // Local optimization: improve the assignment by swapping seeds\n        int total_score = compute_total_score(grid);\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            // Randomly select two distinct cells\n            int i1 = rand() % N, j1 = rand() % N;\n            int i2 = rand() % N, j2 = rand() % N;\n            while (i1 == i2 && j1 == j2) {\n                i2 = rand() % N; j2 = rand() % N;\n            }\n\n            // Collect affected edges (unique)\n            auto edge_key = [](int i1, int j1, int i2, int j2) {\n                if (i1 > i2 || (i1 == i2 && j1 > j2)) {\n                    swap(i1, i2);\n                    swap(j1, j2);\n                }\n                return make_pair(i1 * N + j1, i2 * N + j2);\n            };\n            set<pair<int, int>> edge_set;\n\n            // Edges incident to (i1,j1)\n            if (i1 + 1 < N) edge_set.insert(edge_key(i1, j1, i1 + 1, j1));\n            if (i1 - 1 >= 0) edge_set.insert(edge_key(i1 - 1, j1, i1, j1));\n            if (j1 + 1 < N) edge_set.insert(edge_key(i1, j1, i1, j1 + 1));\n            if (j1 - 1 >= 0) edge_set.insert(edge_key(i1, j1 - 1, i1, j1));\n            // Edges incident to (i2,j2)\n            if (i2 + 1 < N) edge_set.insert(edge_key(i2, j2, i2 + 1, j2));\n            if (i2 - 1 >= 0) edge_set.insert(edge_key(i2 - 1, j2, i2, j2));\n            if (j2 + 1 < N) edge_set.insert(edge_key(i2, j2, i2, j2 + 1));\n            if (j2 - 1 >= 0) edge_set.insert(edge_key(i2, j2 - 1, i2, j2));\n\n            // Compute old contribution\n            int old_contrib = 0;\n            for (auto& e : edge_set) {\n                int a = e.first, b = e.second;\n                int i_a = a / N, j_a = a % N;\n                int i_b = b / N, j_b = b % N;\n                old_contrib += potential_max(grid[i_a][j_a], grid[i_b][j_b]);\n            }\n\n            // Swap the two seeds\n            swap(grid[i1][j1], grid[i2][j2]);\n\n            // Compute new contribution\n            int new_contrib = 0;\n            for (auto& e : edge_set) {\n                int a = e.first, b = e.second;\n                int i_a = a / N, j_a = a % N;\n                int i_b = b / N, j_b = b % N;\n                new_contrib += potential_max(grid[i_a][j_a], grid[i_b][j_b]);\n            }\n\n            int delta = new_contrib - old_contrib;\n            if (delta > 0) {\n                total_score += delta;\n                // Accept swap\n            } else {\n                // Revert swap\n                swap(grid[i1][j1], grid[i2][j2]);\n            }\n        }\n\n        // Output comments for debugging (ignored by judge)\n        cout << \"# Turn \" << turn << endl;\n        cout << \"# Champion: index=\" << champion_idx << \" sum=\" << sums[champion_idx] << endl;\n        cout << \"# Mates: \";\n        for (size_t i = 0; i < mate_indices.size(); ++i) {\n            int idx = mate_indices[i];\n            cout << idx << \" (sum=\" << sums[idx] << \", P=\" << candidate_P[i].first << \") \";\n        }\n        cout << endl;\n        cout << \"# Final edge score: \" << total_score << endl;\n\n        // Output the grid\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j > 0) cout << \" \";\n                cout << grid[i][j];\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read the next set of seeds (for the next turn)\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                cin >> seeds[i][l];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <climits>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Point& other) const { return !(*this == other); }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// direction encoding: 0: right (0,+1), 1: down (+1,0), 2: left (0,-1), 3: up (-1,0)\nint get_dir(const Point& from, const Point& to) {\n    int dx = to.x - from.x;\n    int dy = to.y - from.y;\n    if (dx == 1 && dy == 0) return 1; // down\n    if (dx == -1 && dy == 0) return 3; // up\n    if (dx == 0 && dy == 1) return 0; // right\n    if (dx == 0 && dy == -1) return 2; // left\n    // not adjacent\n    return -1;\n}\n\n// minimal rotation steps from cur_dir to target_dir (0..3)\nint rot_steps(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 0) return 0;\n    if (diff == 2) return 2;\n    return 1; // diff == 1 or 3\n}\n\n// choose rotation character to go from cur_dir to target_dir in one step (if possible)\nchar rot_char(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 1) return 'R';\n    if (diff == 3) return 'L';\n    return '.'; // no rotation or need two steps (handled separately)\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\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 sources and targets\n    vector<Point> 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.emplace_back(i, j);\n            if (t_grid[i][j] == '1') targets.emplace_back(i, j);\n        }\n    }\n\n    // pair sources and targets greedily\n    vector<bool> used_target(M, false);\n    vector<pair<Point, Point>> pairs;\n    for (const Point& src : sources) {\n        int best_idx = -1;\n        int best_dist = INT_MAX;\n        for (int i = 0; i < M; ++i) {\n            if (used_target[i]) continue;\n            int d = manhattan(src, targets[i]);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        pairs.emplace_back(src, targets[best_idx]);\n        used_target[best_idx] = true;\n    }\n\n    // design tree: star with root 0 and leaves 1..V-1, all length 1\n    cout << V << '\\n';\n    for (int i = 1; i < V; ++i) {\n        cout << 0 << ' ' << 1 << '\\n';\n    }\n\n    // initial root position (choose center for convenience)\n    int init_x = N / 2, init_y = N / 2;\n    cout << init_x << ' ' << init_y << '\\n';\n\n    // simulation state\n    int rx = init_x, ry = init_y;\n    int leaf_dir = 0; // initially right\n    bool leaf_holding = false;\n\n    // track current takoyaki positions (initially all sources)\n    vector<vector<bool>> has_takoyaki(N, vector<bool>(N, false));\n    for (const Point& p : sources) has_takoyaki[p.x][p.y] = true;\n    // track filled targets\n    vector<vector<bool>> target_filled(N, vector<bool>(N, false));\n\n    vector<string> ops;\n\n    // helper to add a turn\n    auto add_turn = [&](char move, int rot_vertex, char rot, int grab_vertex, char grab) {\n        string s(2 * V, '.');\n        s[0] = move;\n        if (rot_vertex != -1) {\n            s[1 + rot_vertex] = rot; // rotation slots start at index 1\n        }\n        if (grab_vertex != -1) {\n            s[V + grab_vertex] = grab; // grab slots start at index V\n        }\n        ops.push_back(s);\n    };\n\n    // process each pair\n    for (const auto& p : pairs) {\n        const Point& src = p.first;\n        const Point& dst = p.second;\n\n        // --- pickup ---\n        // find best neighbor for pickup\n        int best_pick_dist = INT_MAX;\n        int best_pick_rot_diff = INT_MAX;\n        Point best_pick_root;\n        int best_pick_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = src.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = src.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_pick_root = Point(nx, ny);\n                best_pick_dir = dir_from_root;\n            }\n        }\n        // move to best_pick_root\n        int px = best_pick_root.x, py = best_pick_root.y;\n        // generate moves\n        vector<char> moves;\n        while (rx != px) {\n            if (rx > px) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != py) {\n            if (ry > py) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        // execute moves, with rotations as needed\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: also rotate and grab\n                int steps = rot_steps(leaf_dir, best_pick_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_pick_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else { // steps == 2\n                    // first rotation in this move (no grab)\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4); // arbitrary direction\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and grab in next turn\n                    char rot2 = rot_char(leaf_dir, best_pick_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // remove takoyaki from source\n        has_takoyaki[src.x][src.y] = false;\n\n        // --- drop ---\n        // find best neighbor for drop (must be empty target)\n        best_pick_dist = INT_MAX;\n        best_pick_rot_diff = INT_MAX;\n        Point best_drop_root;\n        int best_drop_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = dst.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = dst.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (target_filled[nx][ny]) continue; // cannot land on filled target\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_drop_root = Point(nx, ny);\n                best_drop_dir = dir_from_root;\n            }\n        }\n        // move to best_drop_root\n        int dx = best_drop_root.x, dy = best_drop_root.y;\n        moves.clear();\n        while (rx != dx) {\n            if (rx > dx) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != dy) {\n            if (ry > dy) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: rotate and release\n                int steps = rot_steps(leaf_dir, best_drop_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_drop_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else { // steps == 2\n                    // first rotation\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4);\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and release\n                    char rot2 = rot_char(leaf_dir, best_drop_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // mark target filled\n        target_filled[dst.x][dst.y] = true;\n    }\n\n    // output operations\n    for (const string& s : ops) {\n        cout << s << '\\n';\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_PERIMETER = 400000;\nconst vector<int> GRID_SIZES = {500, 250};  // try two grid sizes\n\n// Rectangle structure for the simple rectangle search\nstruct Rectangle {\n    int left, right, top, bottom;  // grid indices\n    int net;\n    int x_min, x_max, y_min, y_max;\n\n    Rectangle() : net(0) {}\n    Rectangle(int l, int r, int t, int b, int net_val,\n              const vector<int>& x_start, const vector<int>& x_end,\n              const vector<int>& y_start, const vector<int>& y_end)\n        : left(l), right(r), top(t), bottom(b), net(net_val) {\n        x_min = x_start[left];\n        x_max = x_end[right];\n        y_min = y_start[top];\n        y_max = y_end[bottom];\n    }\n\n    int perimeter() const {\n        int width = x_max - x_min + 1;\n        int height = y_max - y_min + 1;\n        return 2 * (width + height);\n    }\n};\n\n// Find the best rectangle in the grid using Kadane's algorithm in 2D\nRectangle find_best_rectangle(const vector<vector<int>>& net, int G) {\n    int rows = net.size();\n    int cols = net[0].size();\n\n    // Precompute boundaries for each grid index\n    vector<int> x_start(cols), x_end(cols);\n    for (int j = 0; j < cols; ++j) {\n        x_start[j] = j * G;\n        x_end[j] = (j == cols - 1) ? MAX_COORD : (j + 1) * G - 1;\n    }\n    vector<int> y_start(rows), y_end(rows);\n    for (int i = 0; i < rows; ++i) {\n        y_start[i] = i * G;\n        y_end[i] = (i == rows - 1) ? MAX_COORD : (i + 1) * G - 1;\n    }\n\n    // Default: an empty cell with net = 0\n    Rectangle best;\n    best.net = 0;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (net[i][j] == 0) {\n                best = Rectangle(j, j, i, i, 0, x_start, x_end, y_start, y_end);\n                break;\n            }\n        }\n        if (best.net == 0) break;\n    }\n\n    // 2D Kadane\n    for (int top = 0; top < rows; ++top) {\n        vector<int> col_sum(cols, 0);\n        for (int bottom = top; bottom < rows; ++bottom) {\n            for (int c = 0; c < cols; ++c) {\n                col_sum[c] += net[bottom][c];\n            }\n            // Kadane on col_sum\n            int cur = 0, best_cur = 0;\n            int start = 0, best_start = 0, best_end = -1;\n            for (int c = 0; c < cols; ++c) {\n                if (cur <= 0) {\n                    cur = col_sum[c];\n                    start = c;\n                } else {\n                    cur += col_sum[c];\n                }\n                if (cur > best_cur) {\n                    best_cur = cur;\n                    best_start = start;\n                    best_end = c;\n                }\n            }\n            if (best_end == -1) continue;\n\n            Rectangle candidate(best_start, best_end, top, bottom, best_cur,\n                                x_start, x_end, y_start, y_end);\n            if (candidate.perimeter() <= MAX_PERIMETER && candidate.net > best.net) {\n                best = candidate;\n            }\n        }\n    }\n    return best;\n}\n\n// Greedy region growing on a grid to maximize sum of net with perimeter constraint\nstruct RegionGrower {\n    int G, rows, cols;\n    const vector<vector<int>>& net;\n    vector<vector<bool>> in_region;\n    int perimeter, total_net;\n    vector<pair<int, int>> region_cells;\n\n    static const int dx[4];\n    static const int dy[4];\n\n    RegionGrower(int G, const vector<vector<int>>& net)\n        : G(G), net(net), rows(net.size()), cols(net[0].size()) {\n        in_region.assign(rows, vector<bool>(cols, false));\n        perimeter = 0;\n        total_net = 0;\n    }\n\n    void add_cell(int i, int j) {\n        in_region[i][j] = true;\n        region_cells.emplace_back(i, j);\n        total_net += net[i][j];\n        int neighbors = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                ++neighbors;\n        }\n        perimeter += 4 - 2 * neighbors;\n    }\n\n    void grow() {\n        // Find seed with maximum net\n        int best_i = -1, best_j = -1, best_val = -1e9;\n        for (int i = 0; i < rows; ++i) {\n            for (int j = 0; j < cols; ++j) {\n                if (net[i][j] > best_val) {\n                    best_val = net[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        if (best_val <= 0) return;  // no positive cell\n        add_cell(best_i, best_j);\n\n        set<pair<int, int>> candidates;\n        for (int d = 0; d < 4; ++d) {\n            int ni = best_i + dx[d], nj = best_j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                candidates.insert({ni, nj});\n        }\n\n        while (!candidates.empty() && perimeter <= MAX_PERIMETER) {\n            // Find the candidate with the best benefit per perimeter cost\n            double best_priority = -1e18;\n            pair<int, int> best_cand;\n            for (const auto& cand : candidates) {\n                int i = cand.first, j = cand.second;\n                int delta_net = net[i][j];\n                int neighbors = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                        ++neighbors;\n                }\n                int delta_perim = 4 - 2 * neighbors;\n                double priority;\n                if (delta_perim > 0)\n                    priority = delta_net / (double)delta_perim;\n                else\n                    priority = delta_net * 1000.0;  // strongly favor perimeter reduction\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_cand = cand;\n                }\n            }\n            if (best_priority <= 0) break;  // no beneficial cell left\n\n            int i = best_cand.first, j = best_cand.second;\n            candidates.erase(best_cand);\n\n            // Recompute delta_perim with current region\n            int neighbors = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                    ++neighbors;\n            }\n            int delta_perim = 4 - 2 * neighbors;\n            if (perimeter + delta_perim > MAX_PERIMETER)\n                continue;\n\n            add_cell(i, j);\n            // Add new candidates from the newly added cell\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                    candidates.insert({ni, nj});\n            }\n        }\n    }\n};\n\nconst int RegionGrower::dx[4] = {1, -1, 0, 0};\nconst int RegionGrower::dy[4] = {0, 0, 1, -1};\n\n// Trace the outer boundary of a simply connected region of cells\nvector<pair<int, int>> trace_boundary(const vector<vector<bool>>& in_region, int G, int rows, int cols) {\n    map<pair<int, int>, vector<pair<int, int>>> graph;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (!in_region[i][j]) continue;\n            // Bottom edge\n            if (j == 0 || !in_region[i][j - 1]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, j * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            // Top edge\n            if (j == cols - 1 || !in_region[i][j + 1]) {\n                pair<int, int> p1 = {i * G, (j + 1) * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            // Left edge\n            if (i == 0 || !in_region[i - 1][j]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {i * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            // Right edge\n            if (i == rows - 1 || !in_region[i + 1][j]) {\n                pair<int, int> p1 = {(i + 1) * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n        }\n    }\n    if (graph.empty()) return {};\n\n    // Extract the cycle\n    auto start = graph.begin()->first;\n    vector<pair<int, int>> cycle;\n    pair<int, int> cur = start;\n    pair<int, int> prev = {-1, -1};\n    do {\n        cycle.push_back(cur);\n        const auto& neighbors = graph[cur];\n        pair<int, int> next;\n        for (const auto& nb : neighbors) {\n            if (nb != prev) {\n                next = nb;\n                break;\n            }\n        }\n        prev = cur;\n        cur = next;\n    } while (cur != start);\n\n    // Simplify collinear points\n    vector<pair<int, int>> simplified;\n    int n = cycle.size();\n    for (int i = 0; i < n; ++i) {\n        auto prev = cycle[(i - 1 + n) % n];\n        auto cur = cycle[i];\n        auto next = cycle[(i + 1) % n];\n        // Check collinearity: same x or same y\n        if (prev.first == cur.first && cur.first == next.first) continue;\n        if (prev.second == cur.second && cur.second == next.second) continue;\n        simplified.push_back(cur);\n    }\n    return simplified;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) cin >> mackerels[i].first >> mackerels[i].second;\n    for (int i = 0; i < N; ++i) cin >> sardines[i].first >> sardines[i].second;\n\n    // Best overall solution\n    int best_net = 0;\n    vector<pair<int, int>> best_polygon;\n    bool found_nonempty = false;\n\n    // Try each grid size\n    for (int G : GRID_SIZES) {\n        int rows = (MAX_COORD + G) / G;\n        int cols = rows;\n\n        vector<vector<int>> count_m(rows, vector<int>(cols, 0));\n        vector<vector<int>> count_s(rows, vector<int>(cols, 0));\n\n        for (auto& p : mackerels) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_m[i][j];\n        }\n        for (auto& p : sardines) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_s[i][j];\n        }\n\n        vector<vector<int>> net(rows, vector<int>(cols));\n        for (int i = 0; i < rows; ++i)\n            for (int j = 0; j < cols; ++j)\n                net[i][j] = count_m[i][j] - count_s[i][j];\n\n        // 1) Simple rectangle search\n        Rectangle rect = find_best_rectangle(net, G);\n        if (rect.net > best_net) {\n            best_net = rect.net;\n            best_polygon = {\n                {rect.x_min, rect.y_min},\n                {rect.x_max, rect.y_min},\n                {rect.x_max, rect.y_max},\n                {rect.x_min, rect.y_max}\n            };\n            found_nonempty = (best_net > 0);\n        }\n\n        // 2) Greedy region growing\n        RegionGrower grower(G, net);\n        grower.grow();\n        if (grower.total_net > best_net) {\n            best_net = grower.total_net;\n            best_polygon = trace_boundary(grower.in_region, G, rows, cols);\n            found_nonempty = (best_net > 0);\n        }\n    }\n\n    // If no positive net region found, output a small empty rectangle (score = 1)\n    if (!found_nonempty) {\n        best_polygon = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};\n        best_net = 0;  // score = max(0, 0-0+1) = 1\n    }\n\n    // Output the polygon\n    cout << best_polygon.size() << \"\\n\";\n    for (auto& p : best_polygon) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <map>\n#include <set>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Normal distribution with given mean and stddev, rounded to integer, clamped to [1,1e9]\nint normal_int(double mean, double stddev, mt19937& rng) {\n    normal_distribution<double> dist(mean, stddev);\n    double val = dist(rng);\n    int res = (int)round(val);\n    if (res < 1) res = 1;\n    if (res > 1000000000) res = 1000000000;\n    return res;\n}\n\n// Structure for a placement instruction\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference index or -1\n};\n\n// Simulation state: bounding boxes of placed rectangles\nstruct Rect {\n    double x1, y1, x2, y2;\n};\n\n// Check if two rectangles overlap (allowing touching)\nbool overlap(const Rect& a, const Rect& b) {\n    return (a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1);\n}\n\n// Simulate the placement sequence using estimated dimensions.\n// Returns true if valid (no overlap, all coordinates non-negative).\n// Also returns the bounding box (W, H).\nbool simulate(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est,\n              double& W, double& H, map<int, Rect>& boxes) {\n    boxes.clear();\n    W = 0.0;\n    H = 0.0;\n    set<int> placed;\n    for (const Placement& pl : seq) {\n        int id = pl.p;\n        double w, h;\n        if (pl.r == 0) {\n            w = w_est[id];\n            h = h_est[id];\n        } else {\n            w = h_est[id];\n            h = w_est[id];\n        }\n        Rect r;\n        if (pl.d == 'U') {\n            if (pl.b == -1) {\n                r.x1 = 0.0;\n                r.y1 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x1 = ref.x2;\n                r.y1 = ref.y2;\n            }\n            r.x2 = r.x1 + w;\n            r.y2 = r.y1 + h;\n        } else if (pl.d == 'L') {\n            if (pl.b == -1) {\n                r.x2 = 0.0;\n                r.y2 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x2 = ref.x1;\n                r.y2 = ref.y1;\n            }\n            r.x1 = r.x2 - w;\n            r.y1 = r.y2 - h;\n        } else {\n            return false; // invalid direction\n        }\n        // Check bounds\n        if (r.x1 < 0.0 || r.y1 < 0.0) return false;\n        // Check overlap with existing rectangles\n        for (const auto& kv : boxes) {\n            if (overlap(r, kv.second)) return false;\n        }\n        boxes[id] = r;\n        placed.insert(id);\n        W = max(W, r.x2);\n        H = max(H, r.y2);\n    }\n    return true;\n}\n\n// Greedy packing based on estimated dimensions.\n// Returns a placement sequence.\nvector<Placement> greedy_packing(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, bool randomize = true) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Try all options for rectangle i\n        struct Option {\n            double delta; // increase in W+H\n            Placement pl;\n        };\n        vector<Option> options;\n\n        for (int rot = 0; rot < 2; ++rot) {\n            for (char dir : {'U', 'L'}) {\n                // Try all possible references: -1 and all placed indices\n                vector<int> refs = {-1};\n                for (int idx : placed) refs.push_back(idx);\n                for (int b : refs) {\n                    // Skip invalid combinations: L with b=-1 likely leads to negative coordinates\n                    if (dir == 'L' && b == -1) {\n                        // Only allow if w_est[i] == 0 (impossible) -> skip\n                        continue;\n                    }\n                    Placement pl{ i, rot, dir, b };\n                    // Simulate with this new rectangle appended\n                    vector<Placement> test_seq = seq;\n                    test_seq.push_back(pl);\n                    map<int, Rect> test_boxes;\n                    double newW, newH;\n                    if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                        double delta = (newW + newH) - (curW + curH);\n                        options.push_back({ delta, pl });\n                    }\n                }\n            }\n        }\n        // Consider skipping\n        double skip_penalty = w_est[i] + h_est[i]; // estimated penalty if skipped\n\n        if (options.empty()) {\n            // must skip\n            continue;\n        }\n        // Find option with minimum delta\n        double best_delta = 1e30;\n        for (const auto& opt : options) {\n            if (opt.delta < best_delta) best_delta = opt.delta;\n        }\n        // Collect all options with delta close to best (within 1e-6) to randomize\n        vector<Option> best_options;\n        for (const auto& opt : options) {\n            if (abs(opt.delta - best_delta) < 1e-6) best_options.push_back(opt);\n        }\n        // Choose one randomly if randomize, otherwise the first\n        Option chosen = best_options[0];\n        if (randomize && best_options.size() > 1) {\n            uniform_int_distribution<int> dist(0, best_options.size() - 1);\n            chosen = best_options[dist(rng)];\n        }\n        // Decide to place or skip based on greedy criterion\n        if (best_delta < skip_penalty) {\n            // Place it\n            seq.push_back(chosen.pl);\n            // Update current state by re-simulating from scratch (could be optimized but N is small)\n            simulate(seq, w_est, h_est, curW, curH, current_boxes);\n            placed.insert(i);\n        }\n        // else skip\n    }\n    return seq;\n}\n\n// Mutate a sequence: randomly change one parameter of one placement, or add/remove a rectangle.\n// Returns a new sequence (might be invalid, to be checked by caller)\nvector<Placement> mutate_sequence(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> new_seq = seq;\n    if (new_seq.empty() || uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n        // Try to add a rectangle not yet placed\n        set<int> placed_ids;\n        for (const auto& pl : new_seq) placed_ids.insert(pl.p);\n        vector<int> not_placed;\n        for (int i = 0; i < N; ++i) if (placed_ids.count(i) == 0) not_placed.push_back(i);\n        if (!not_placed.empty()) {\n            int id = not_placed[uniform_int_distribution<int>(0, not_placed.size()-1)(rng)];\n            // Generate random placement for this rectangle\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_int_distribution<int>(0,1)(rng) == 0) ? 'U' : 'L';\n            int b = -1;\n            if (dir == 'L') {\n                // need a reference with positive left edge\n                if (!new_seq.empty()) {\n                    // choose a random placed index as reference\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n                // else b remains -1, but that will likely be invalid, so skip addition\n                if (b == -1) return new_seq; // no change\n            } else {\n                if (!new_seq.empty() && uniform_int_distribution<int>(0,1)(rng) == 0) {\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n            }\n            // Insert in correct order (increasing p)\n            Placement pl{id, rot, dir, b};\n            auto it = lower_bound(new_seq.begin(), new_seq.end(), pl, \n                [](const Placement& a, const Placement& b) { return a.p < b.p; });\n            new_seq.insert(it, pl);\n        }\n    } else if (new_seq.size() < N && uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n        // Try to remove a random rectangle\n        int idx = uniform_int_distribution<int>(0, new_seq.size()-1)(rng);\n        new_seq.erase(new_seq.begin() + idx);\n    } else {\n        // Modify one random placement\n        int idx = uniform_int_distribution<int>(0, new_seq.size()-1)(rng);\n        Placement& pl = new_seq[idx];\n        int choice = uniform_int_distribution<int>(0,2)(rng);\n        if (choice == 0) {\n            // flip rotation\n            pl.r = 1 - pl.r;\n        } else if (choice == 1) {\n            // change direction\n            pl.d = (pl.d == 'U') ? 'L' : 'U';\n            // if direction becomes L and b == -1, set b to some reference (or skip)\n            if (pl.d == 'L' && pl.b == -1 && !new_seq.empty()) {\n                // choose a random earlier placed rectangle as reference\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                }\n                // else keep -1, but likely invalid\n            }\n        } else {\n            // change reference\n            if (pl.b == -1) {\n                // try to set to some earlier placed rectangle\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                }\n            } else {\n                // change to another reference or -1\n                vector<int> candidates = {-1};\n                for (int j = 0; j < idx; ++j) candidates.push_back(new_seq[j].p);\n                pl.b = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(rng)];\n            }\n        }\n    }\n    return new_seq;\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    vector<int> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Convert to double for estimates\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = w_obs[i];\n        h_est[i] = h_obs[i];\n    }\n\n    // Precompute total penalty estimate (using observed values)\n    double total_penalty_est = 0.0;\n    for (int i = 0; i < N; ++i) {\n        total_penalty_est += w_est[i] + h_est[i];\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Placement> best_seq;\n    double best_score = 1e30;\n\n    for (int t = 0; t < T; ++t) {\n        vector<Placement> cur_seq;\n        if (t == 0 || uniform_real_distribution<double>(0,1)(rng) < 0.7) {\n            // Generate a new greedy packing with perturbed estimates\n            vector<double> pert_w = w_est, pert_h = h_est;\n            normal_distribution<double> noise(0.0, sigma * 0.5);\n            for (int i = 0; i < N; ++i) {\n                pert_w[i] += noise(rng);\n                pert_h[i] += noise(rng);\n                // clamp to positive\n                if (pert_w[i] < 1.0) pert_w[i] = 1.0;\n                if (pert_h[i] < 1.0) pert_h[i] = 1.0;\n            }\n            cur_seq = greedy_packing(pert_w, pert_h, rng, true);\n        } else {\n            // Mutate best sequence\n            cur_seq = mutate_sequence(best_seq, w_est, h_est, rng);\n        }\n\n        // Ensure sequence is valid under current estimates; if not, fallback to greedy\n        {\n            map<int, Rect> dummy_boxes;\n            double dummyW, dummyH;\n            if (!simulate(cur_seq, w_est, h_est, dummyW, dummyH, dummy_boxes)) {\n                cur_seq = greedy_packing(w_est, h_est, rng, true);\n            }\n        }\n\n        // Output the sequence\n        cout << cur_seq.size() << '\\n';\n        for (const Placement& pl : cur_seq) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout.flush();\n\n        // Read measurement\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n\n        // Compute observed score\n        set<int> placed_ids;\n        for (const Placement& pl : cur_seq) placed_ids.insert(pl.p);\n        double penalty = 0.0;\n        for (int i = 0; i < N; ++i) {\n            if (placed_ids.count(i) == 0) {\n                penalty += w_est[i] + h_est[i]; // use estimated penalty\n            }\n        }\n        double score = W_meas + H_meas + penalty;\n\n        // Update best\n        if (score < best_score) {\n            best_score = score;\n            best_seq = cur_seq;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // All-pairs shortest distances (BFS from each vertex)\n    vector<vector<short>> dist(N, vector<short>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        queue<int> q;\n        dist[s][s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // cover[v] = bitset of vertices within distance H from v\n    vector<bitset<MAXN>> cover(N);\n    for (int v = 0; v < N; ++v) {\n        for (int u = 0; u < N; ++u) {\n            if (dist[v][u] != -1 && dist[v][u] <= H) {\n                cover[v].set(u);\n            }\n        }\n    }\n\n    // Greedy weighted set cover to select roots (minimize sum of A of roots)\n    bitset<MAXN> uncovered;\n    uncovered.set();\n    vector<int> roots;\n    while (uncovered.any()) {\n        int best = -1;\n        double best_ratio = 1e18;\n        for (int v = 0; v < N; ++v) {\n            bitset<MAXN> cur = cover[v] & uncovered;\n            if (cur.none()) continue;\n            int gain = cur.count();\n            double ratio = (double)A[v] / gain;\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best = v;\n            }\n        }\n        if (best == -1) break;   // should never happen\n        roots.push_back(best);\n        uncovered &= ~cover[best];\n    }\n\n    // Assign each vertex to the nearest root (break ties arbitrarily)\n    vector<int> root_of(N, -1);\n    vector<int> dist_to_root(N, 1000);\n    for (int v = 0; v < N; ++v) {\n        int best_r = -1, best_d = 1000;\n        for (int r : roots) {\n            int d = dist[v][r];\n            if (d < best_d) {\n                best_d = d;\n                best_r = r;\n            }\n        }\n        root_of[v] = best_r;\n        dist_to_root[v] = best_d;\n    }\n\n    // Build the parent array (forest)\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (root_of[v] == v) {\n            parent[v] = -1;\n            continue;\n        }\n        int r = root_of[v];\n        int d = dist_to_root[v];\n        bool found = false;\n        for (int u : adj[v]) {\n            if (root_of[u] == r && dist[u][r] == d - 1) {\n                parent[v] = u;\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            // Fallback: any neighbor with same root and smaller distance\n            for (int u : adj[v]) {\n                if (root_of[u] == r && dist[u][r] < d) {\n                    parent[v] = u;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i];\n        if (i < N - 1) cout << ' ';\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<pair<char, int>> moves;\n\n    // Helper functions to perform a single shift and record the move\n    auto shiftRowLeft = [&](int i) {\n        char removed = board[i][0]; // not used\n        for (int j = 0; j < N - 1; ++j) {\n            board[i][j] = board[i][j + 1];\n        }\n        board[i][N - 1] = '.';\n        moves.push_back({'L', i});\n    };\n\n    auto shiftRowRight = [&](int i) {\n        char removed = board[i][N - 1];\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n        moves.push_back({'R', i});\n    };\n\n    auto shiftColUp = [&](int j) {\n        char removed = board[0][j];\n        for (int i = 0; i < N - 1; ++i) {\n            board[i][j] = board[i + 1][j];\n        }\n        board[N - 1][j] = '.';\n        moves.push_back({'U', j});\n    };\n\n    auto shiftColDown = [&](int j) {\n        char removed = board[N - 1][j];\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n        moves.push_back({'D', j});\n    };\n\n    while (true) {\n        // Collect all current Oni positions\n        vector<pair<int, int>> oniList;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    oniList.emplace_back(i, j);\n                }\n            }\n        }\n        if (oniList.empty()) {\n            break;\n        }\n\n        // Find the best Oni and direction to remove with best ratio of removed Oni per shift\n        int bestIdx = -1;\n        char bestDir = ' ';\n        double bestScore = -1.0;\n\n        for (size_t idx = 0; idx < oniList.size(); ++idx) {\n            auto [i, j] = oniList[idx];\n\n            // Check safety in each direction\n            bool safeUp = true;\n            for (int r = 0; r < i; ++r) {\n                if (board[r][j] == 'o') safeUp = false;\n            }\n            bool safeDown = true;\n            for (int r = i + 1; r < N; ++r) {\n                if (board[r][j] == 'o') safeDown = false;\n            }\n            bool safeLeft = true;\n            for (int c = 0; c < j; ++c) {\n                if (board[i][c] == 'o') safeLeft = false;\n            }\n            bool safeRight = true;\n            for (int c = j + 1; c < N; ++c) {\n                if (board[i][c] == 'o') safeRight = false;\n            }\n\n            // Evaluate each safe direction\n            if (safeUp) {\n                int shifts = i + 1;\n                int removed = 0;\n                for (int r = 0; r <= i; ++r) {\n                    if (board[r][j] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'U';\n                }\n            }\n            if (safeDown) {\n                int shifts = N - i;\n                int removed = 0;\n                for (int r = i; r < N; ++r) {\n                    if (board[r][j] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'D';\n                }\n            }\n            if (safeLeft) {\n                int shifts = j + 1;\n                int removed = 0;\n                for (int c = 0; c <= j; ++c) {\n                    if (board[i][c] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'L';\n                }\n            }\n            if (safeRight) {\n                int shifts = N - j;\n                int removed = 0;\n                for (int c = j; c < N; ++c) {\n                    if (board[i][c] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'R';\n                }\n            }\n        }\n\n        // According to the problem guarantee, there should always be a safe direction.\n        if (bestIdx == -1) {\n            break;\n        }\n\n        auto [i, j] = oniList[bestIdx];\n\n        // Perform the shifts in the chosen direction\n        if (bestDir == 'U') {\n            for (int k = 0; k < i + 1; ++k) {\n                shiftColUp(j);\n            }\n        } else if (bestDir == 'D') {\n            for (int k = 0; k < N - i; ++k) {\n                shiftColDown(j);\n            }\n        } else if (bestDir == 'L') {\n            for (int k = 0; k < j + 1; ++k) {\n                shiftRowLeft(i);\n            }\n        } else if (bestDir == 'R') {\n            for (int k = 0; k < N - j; ++k) {\n                shiftRowRight(i);\n            }\n        }\n    }\n\n    // Output the moves\n    for (auto [d, p] : moves) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Dinic's max flow\nstruct Edge {\n    int to, rev;\n    long long cap;\n};\n\nclass Dinic {\npublic:\n    vector<vector<Edge>> graph;\n    vector<int> level, iter;\n    Dinic(int n) : graph(n), level(n), iter(n) {}\n    void add_edge(int from, int to, long long cap) {\n        graph[from].push_back({to, (int)graph[to].size(), cap});\n        graph[to].push_back({from, (int)graph[from].size() - 1, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto& e : graph[v]) {\n                if (e.cap > 0 && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    long long dfs(int v, int t, long long f) {\n        if (v == t) return f;\n        for (int& i = iter[v]; i < (int)graph[v].size(); ++i) {\n            Edge& e = graph[v][i];\n            if (e.cap > 0 && level[v] < level[e.to]) {\n                long long d = dfs(e.to, t, min(f, e.cap));\n                if (d > 0) {\n                    e.cap -= d;\n                    graph[e.to][e.rev].cap += d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    long long max_flow(int s, int t) {\n        long long flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            long long f;\n            while ((f = dfs(s, t, 1e18)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\n// Simulation function\nlong long simulate(const vector<int>& a, const vector<int>& b, const vector<long long>& T, int N, long long L) {\n    vector<int> cnt(N, 0);\n    int current = 0;\n    cnt[current] = 1;\n    for (long long week = 2; week <= L; ++week) {\n        if (cnt[current] % 2 == 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        cnt[current]++;\n    }\n    long long error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(cnt[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    const int N = 100;\n    const long long L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Build flow network\n    int source = 0;\n    int left_start = 1;                     // 1 .. 200\n    int right_start = left_start + 2 * N;   // 201 .. 300\n    int sink = right_start + N;             // 301\n    Dinic dinic(sink + 1);\n\n    // Source to left nodes (two per employee)\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n        dinic.add_edge(source, node1, T[i]);\n        dinic.add_edge(source, node2, T[i]);\n    }\n\n    // Right nodes to sink\n    for (int j = 0; j < N; ++j) {\n        int node = right_start + j;\n        dinic.add_edge(node, sink, 2 * T[j]);\n    }\n\n    // Left nodes to right nodes (infinite capacity)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node1 = left_start + 2 * i;\n            int node2 = left_start + 2 * i + 1;\n            int right_node = right_start + j;\n            dinic.add_edge(node1, right_node, L);\n            dinic.add_edge(node2, right_node, L);\n        }\n    }\n\n    // Compute max flow\n    long long flow = dinic.max_flow(source, sink);\n\n    // Extract a[i] and b[i] by rounding to the dominant assignment\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n\n        // Find best j for node1\n        long long max_fl1 = -1;\n        int best_j1 = 0;\n        for (auto& e : dinic.graph[node1]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl1) {\n                    max_fl1 = fl;\n                    best_j1 = e.to - right_start;\n                }\n            }\n        }\n        a[i] = best_j1;\n\n        // Find best j for node2\n        long long max_fl2 = -1;\n        int best_j2 = 0;\n        for (auto& e : dinic.graph[node2]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl2) {\n                    max_fl2 = fl;\n                    best_j2 = e.to - right_start;\n                }\n            }\n        }\n        b[i] = best_j2;\n    }\n\n    // Compute initial error\n    long long best_error = simulate(a, b, T, N, L);\n    vector<int> best_a = a, best_b = b;\n\n    // Local search\n    const int max_iter = 1000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < max_iter; ++iter) {\n        // Randomly choose an employee i\n        int i = rng() % N;\n        // Randomly choose whether to change a[i] or b[i]\n        bool change_a = (rng() % 2 == 0);\n        // Generate random new value\n        int new_val = rng() % N;\n        // Store old value\n        int old_val = change_a ? best_a[i] : best_b[i];\n        // Temporarily change\n        if (change_a) {\n            a[i] = new_val;\n        } else {\n            b[i] = new_val;\n        }\n        // Simulate\n        long long new_error = simulate(a, b, T, N, L);\n        // If improved, update best; otherwise revert\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a[i] = change_a ? new_val : best_a[i];\n            best_b[i] = change_a ? best_b[i] : new_val;\n        } else {\n            // revert\n            if (change_a) {\n                a[i] = old_val;\n            } else {\n                b[i] = old_val;\n            }\n        }\n    }\n\n    // Output the best solution\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\nusing pii = pair<int, int>;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\n\nvector<vector<int>> groups;\nvector<vector<pii>> group_edges;\n\n// Fortune\u2011telling query\nvector<pii> query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    vector<pii> edges;\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\n// Hilbert curve index for integer coordinates (14\u2011bit precision)\nuint64_t hilbertOrder(int x, int y) {\n    int pow = 14;\n    uint64_t d = 0;\n    int s = 1 << (pow - 1);\n    for (int i = pow - 1; i >= 0; --i) {\n        int rx = (x & s) ? 1 : 0;\n        int ry = (y & s) ? 1 : 0;\n        d = (d << 2) | ((rx * 3) ^ ry);\n        if (!ry) {\n            if (rx) {\n                x = (1 << pow) - 1 - x;\n                y = (1 << pow) - 1 - y;\n            }\n            swap(x, y);\n        }\n        s >>= 1;\n    }\n    return d;\n}\n\n// Approximate MST order for a group using Euclidean distances between centers\nvector<int> approximateMSTorder(const vector<int>& group) {\n    int n = group.size();\n    vector<double> dist(n, 1e18);\n    vector<bool> visited(n, false);\n    vector<int> parent(n, -1);\n    dist[0] = 0;\n    for (int i = 0; i < n; ++i) {\n        int u = -1;\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v] && (u == -1 || dist[v] < dist[u]))\n                u = v;\n        }\n        visited[u] = true;\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v]) {\n                double dx = cx[group[u]] - cx[group[v]];\n                double dy = cy[group[u]] - cy[group[v]];\n                double d = sqrt(dx*dx + dy*dy);\n                if (d < dist[v]) {\n                    dist[v] = d;\n                    parent[v] = u;\n                }\n            }\n        }\n    }\n    // Build adjacency list of the MST\n    vector<vector<int>> adj(n);\n    for (int i = 1; i < n; ++i) {\n        int u = i, v = parent[i];\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // DFS traversal to obtain a linear order\n    vector<int> order;\n    function<void(int,int)> dfs = [&](int u, int p) {\n        order.push_back(group[u]);\n        for (int v : adj[u]) {\n            if (v != p)\n                dfs(v, u);\n        }\n    };\n    dfs(0, -1);\n    return order;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Global ordering by Hilbert curve index\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n    });\n\n    // Partition into groups according to G\n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n\n    int total_queries = 0;\n    for (int i = 0; i < M; ++i) {\n        int s = groups[i].size();\n        if (s == 1) continue;\n        if (s <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n            ++total_queries;\n        } else {\n            // Reorder cities within the group using approximate MST order\n            vector<int> reordered = approximateMSTorder(groups[i]);\n            int start = 0;\n            while (start < s) {\n                int end = min(start + L, s);\n                int window_size = end - start;\n                if (window_size >= 2) {\n                    vector<int> window(reordered.begin() + start, reordered.begin() + end);\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                    ++total_queries;\n                }\n                start += L - 1;  // overlap by exactly one city\n            }\n        }\n        if (total_queries > Q) break;  // safety, should not happen\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // City list of the group (using the original grouping order for output)\n        for (size_t j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> points(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n\n    pair<int, int> cur = points[0];\n    vector<pair<int, int>> targets(points.begin() + 1, points.end());\n    vector<string> actions;\n\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n    const string dir_name[4] = {\"D\", \"U\", \"R\", \"L\"};\n\n    for (size_t k = 0; k < targets.size(); ++k) {\n        auto [ti, tj] = targets[k];\n\n        // Build blocked cells: future targets (index > k)\n        vector<vector<bool>> blocked(N, vector<bool>(N, false));\n        for (size_t i = k + 1; i < targets.size(); ++i) {\n            int x = targets[i].first, y = targets[i].second;\n            blocked[x][y] = true;\n        }\n\n        // Case 1: already aligned and target on boundary -> direct slide\n        if (cur.first == ti) {\n            if (tj == 0) {\n                actions.push_back(\"S L\");\n                cur.second = tj;\n                continue;\n            } else if (tj == N - 1) {\n                actions.push_back(\"S R\");\n                cur.second = tj;\n                continue;\n            }\n        } else if (cur.second == tj) {\n            if (ti == 0) {\n                actions.push_back(\"S U\");\n                cur.first = ti;\n                continue;\n            } else if (ti == N - 1) {\n                actions.push_back(\"S D\");\n                cur.first = ti;\n                continue;\n            }\n        }\n\n        // Case 2: target on a boundary, try align-then-slide if straight path clear\n        bool used_align_slide = false;\n        if (ti == 0 || ti == N-1 || tj == 0 || tj == N-1) {\n            // Target on top/bottom boundary: move horizontally to column tj, then slide vertically\n            if (ti == 0 || ti == N-1) {\n                // Check horizontal segment from (cur.first, cur.second) to (cur.first, tj)\n                bool clear = true;\n                if (cur.second != tj) {\n                    int step = (cur.second < tj) ? 1 : -1;\n                    for (int j = cur.second; j != tj; j += step) {\n                        if (blocked[cur.first][j]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                // Also ensure the destination cell (cur.first, tj) is not a future target\n                if (clear && blocked[cur.first][tj]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform horizontal moves\n                    if (cur.second < tj) {\n                        for (int j = cur.second; j < tj; ++j) actions.push_back(\"M R\");\n                    } else if (cur.second > tj) {\n                        for (int j = cur.second; j > tj; --j) actions.push_back(\"M L\");\n                    }\n                    cur.second = tj;\n                    // Perform slide\n                    if (ti == 0) {\n                        actions.push_back(\"S U\");\n                        cur.first = ti;\n                    } else {\n                        actions.push_back(\"S D\");\n                        cur.first = ti;\n                    }\n                    used_align_slide = true;\n                }\n            }\n            // If not used, try the other orientation if target on left/right boundary\n            if (!used_align_slide && (tj == 0 || tj == N-1)) {\n                // Move vertically to row ti, then slide horizontally\n                bool clear = true;\n                if (cur.first != ti) {\n                    int step = (cur.first < ti) ? 1 : -1;\n                    for (int i = cur.first; i != ti; i += step) {\n                        if (blocked[i][cur.second]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                if (clear && blocked[ti][cur.second]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform vertical moves\n                    if (cur.first < ti) {\n                        for (int i = cur.first; i < ti; ++i) actions.push_back(\"M D\");\n                    } else if (cur.first > ti) {\n                        for (int i = cur.first; i > ti; --i) actions.push_back(\"M U\");\n                    }\n                    cur.first = ti;\n                    // Perform slide\n                    if (tj == 0) {\n                        actions.push_back(\"S L\");\n                        cur.second = tj;\n                    } else {\n                        actions.push_back(\"S R\");\n                        cur.second = tj;\n                    }\n                    used_align_slide = true;\n                }\n            }\n        }\n        if (used_align_slide) {\n            continue;\n        }\n\n        // Case 3: fallback to BFS (move-only, avoiding future targets)\n        vector<vector<int>> prev_x(N, vector<int>(N, -1));\n        vector<vector<int>> prev_y(N, vector<int>(N, -1));\n        vector<vector<int>> dir_idx(N, vector<int>(N, -1));\n        queue<pair<int, int>> q;\n        q.push(cur);\n        prev_x[cur.first][cur.second] = cur.first;\n        prev_y[cur.first][cur.second] = cur.second;\n\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            if (x == ti && y == tj) break;\n\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                if (blocked[nx][ny]) continue;\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                dir_idx[nx][ny] = d;\n                q.push({nx, ny});\n            }\n        }\n\n        // Reconstruct path\n        vector<string> path_actions;\n        int x = ti, y = tj;\n        while (x != cur.first || y != cur.second) {\n            int d = dir_idx[x][y];\n            path_actions.push_back(\"M \" + dir_name[d]);\n            int px = prev_x[x][y];\n            int py = prev_y[x][y];\n            x = px;\n            y = py;\n        }\n        reverse(path_actions.begin(), path_actions.end());\n\n        for (const string& a : path_actions) {\n            actions.push_back(a);\n        }\n\n        cur = {ti, tj};\n    }\n\n    // Output actions\n    for (const string& a : actions) {\n        cout << a << \"\\n\";\n    }\n\n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <climits>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r, idx;\n};\n\nvector<Company> companies;\nvector<int> a, b, c, d;\n\n// assign a rectangle to a single company within given rect\nvoid assign_single(int i, int rect_l, int rect_b, int rect_r, int rect_t) {\n    long long r = companies[i].r;\n    int x = companies[i].x;\n    int y = companies[i].y;\n    int w_max = rect_r - rect_l;\n    int h_max = rect_t - rect_b;\n    double best_sat = -1.0;\n    int best_a = 0, best_b = 0, best_c = 0, best_d = 0;\n\n    // try all possible widths\n    for (int w = 1; w <= w_max; ++w) {\n        int h = (r + w / 2) / w; // round(r/w)\n        if (h > h_max) h = h_max;\n        if (h < 1) h = 1;\n        long long s = w * (long long)h;\n        double ratio = min(r, s) / (double)max(r, s);\n        double sat = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n\n        // check if placement is possible\n        int a_min = max(rect_l, x - w + 1);\n        int a_max = min(x, rect_r - w);\n        if (a_min > a_max) continue;\n        int b_min = max(rect_b, y - h + 1);\n        int b_max = min(y, rect_t - h);\n        if (b_min > b_max) continue;\n\n        int a = a_min;\n        int b = b_min;\n        if (sat > best_sat) {\n            best_sat = sat;\n            best_a = a;\n            best_b = b;\n            best_c = a + w;\n            best_d = b + h;\n        }\n    }\n\n    // assign the best found rectangle\n    a[companies[i].idx] = best_a;\n    b[companies[i].idx] = best_b;\n    c[companies[i].idx] = best_c;\n    d[companies[i].idx] = best_d;\n}\n\n// fallback: column packing within given rect\nvoid fallback_column_packing(int rect_l, int rect_b, int rect_r, int rect_t,\n                             vector<int> indices) {\n    if (indices.empty()) return;\n\n    // sort indices by x coordinate\n    sort(indices.begin(), indices.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    int n = indices.size();\n    vector<int> w(n);\n    long long cur_start = rect_l;\n\n    // initial widths\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        long long w_min_cov = max(1LL, (long long)companies[i].x - cur_start + 1);\n        long long w_min_area = (companies[i].r + 9999) / 10000;\n        w[k] = max(w_min_cov, w_min_area);\n        cur_start += w[k];\n    }\n\n    long long total_width = cur_start - rect_l;\n    long long avail_width = rect_r - rect_l;\n    long long excess = total_width - avail_width;\n\n    // precompute satisfaction for each possible width (1..10000) for each company\n    vector<vector<double>> sat(n, vector<double>(10001, 0.0));\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        long long ri = companies[i].r;\n        for (int width = 1; width <= 10000; ++width) {\n            int h = (ri + width / 2) / width;\n            if (h > 10000) h = 10000;\n            if (h < 1) h = 1;\n            long long s = width * (long long)h;\n            double ratio = min(ri, s) / (double)max(ri, s);\n            sat[k][width] = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        }\n    }\n\n    // reduce widths if total exceeds available width\n    while (excess > 0) {\n        // recompute current starts\n        vector<long long> start_pos(n);\n        cur_start = rect_l;\n        for (int k = 0; k < n; ++k) {\n            start_pos[k] = cur_start;\n            cur_start += w[k];\n        }\n\n        int best_k = -1;\n        double best_loss = 1e18;\n        for (int k = 0; k < n; ++k) {\n            int i = indices[k];\n            long long w_min_cov = max(1LL, (long long)companies[i].x - start_pos[k] + 1);\n            if (w[k] <= w_min_cov) continue;\n            double p_curr = sat[k][w[k]];\n            double p_red = sat[k][w[k] - 1];\n            double loss = p_curr - p_red;\n            if (loss < best_loss) {\n                best_loss = loss;\n                best_k = k;\n            }\n        }\n        if (best_k == -1) break;\n        w[best_k]--;\n        excess--;\n    }\n\n    // assign rectangles\n    cur_start = rect_l;\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        int wi = w[k];\n        long long ri = companies[i].r;\n        int h = (ri + wi / 2) / wi;\n        if (h > 10000) h = 10000;\n        if (h < 1) h = 1;\n\n        int ai = cur_start;\n        int ci = ai + wi;\n        int bi = max(rect_b, companies[i].y - h + 1);\n        int di = bi + h;\n        // ensure within rect vertically\n        if (bi < rect_b) bi = rect_b;\n        if (di > rect_t) {\n            di = rect_t;\n            bi = di - h;\n        }\n\n        a[companies[i].idx] = ai;\n        b[companies[i].idx] = bi;\n        c[companies[i].idx] = ci;\n        d[companies[i].idx] = di;\n\n        cur_start += wi;\n    }\n}\n\n// recursive splitting\nvoid solve(int rect_l, int rect_b, int rect_r, int rect_t, vector<int> indices) {\n    if (indices.empty()) return;\n    if (indices.size() == 1) {\n        assign_single(indices[0], rect_l, rect_b, rect_r, rect_t);\n        return;\n    }\n\n    // try vertical split\n    bool vertical_ok = false;\n    int best_s = -1;\n    double best_error = 1e18;\n    vector<int> best_left, best_right;\n\n    // sort indices by x\n    vector<int> sorted_idx = indices;\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> left(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> right(sorted_idx.begin() + k, sorted_idx.end());\n        int max_x_left = companies[left.back()].x;\n        int min_x_right = companies[right.front()].x;\n        if (max_x_left + 1 > min_x_right) continue;\n\n        long long sum_left = 0, sum_right = 0;\n        for (int i : left) sum_left += companies[i].r;\n        for (int i : right) sum_right += companies[i].r;\n        long long height = rect_t - rect_b;\n        double s_ideal = (double)sum_left / height;\n        int s_low = max_x_left + 1;\n        int s_high = min_x_right;\n        int s = max(s_low, min(s_high, (int)round(s_ideal)));\n        double error = abs(sum_left - s * height) + abs(sum_right - (rect_r - s) * height);\n        if (error < best_error) {\n            best_error = error;\n            best_s = s;\n            best_left = left;\n            best_right = right;\n            vertical_ok = true;\n        }\n    }\n\n    if (vertical_ok) {\n        solve(rect_l, rect_b, best_s, rect_t, best_left);\n        solve(best_s, rect_b, rect_r, rect_t, best_right);\n        return;\n    }\n\n    // try horizontal split\n    bool horizontal_ok = false;\n    int best_t = -1;\n    double best_error_h = 1e18;\n    vector<int> best_bottom, best_top;\n\n    // sort indices by y\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].y < companies[j].y; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> bottom(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> top(sorted_idx.begin() + k, sorted_idx.end());\n        int max_y_bottom = companies[bottom.back()].y;\n        int min_y_top = companies[top.front()].y;\n        if (max_y_bottom + 1 > min_y_top) continue;\n\n        long long sum_bottom = 0, sum_top = 0;\n        for (int i : bottom) sum_bottom += companies[i].r;\n        for (int i : top) sum_top += companies[i].r;\n        long long width = rect_r - rect_l;\n        double t_ideal = (double)sum_bottom / width;\n        int t_low = max_y_bottom + 1;\n        int t_high = min_y_top;\n        int t = max(t_low, min(t_high, (int)round(t_ideal)));\n        double error = abs(sum_bottom - t * width) + abs(sum_top - (rect_t - t) * width);\n        if (error < best_error_h) {\n            best_error_h = error;\n            best_t = t;\n            best_bottom = bottom;\n            best_top = top;\n            horizontal_ok = true;\n        }\n    }\n\n    if (horizontal_ok) {\n        solve(rect_l, rect_b, rect_r, best_t, best_bottom);\n        solve(rect_l, best_t, rect_r, rect_t, best_top);\n        return;\n    }\n\n    // no feasible split found, fallback to column packing for the whole region\n    fallback_column_packing(rect_l, rect_b, rect_r, rect_t, indices);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].idx = i;\n    }\n\n    a.resize(n);\n    b.resize(n);\n    c.resize(n);\n    d.resize(n);\n\n    vector<int> all_idx(n);\n    iota(all_idx.begin(), all_idx.end(), 0);\n\n    solve(0, 0, 10000, 10000, all_idx);\n\n    for (int i = 0; i < n; ++i) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <random>\n#include <tuple>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> tile(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tile[i][j];\n        }\n    }\n\n    vector<vector<int>> value(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> value[i][j];\n        }\n    }\n\n    // Find total number of tiles (M)\n    int M = 0;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            M = max(M, tile[i][j] + 1);\n        }\n    }\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n    // Timestamp technique to avoid resetting visited array each trial\n    vector<int> visited_tiles(M, 0);\n    int cur_timestamp = 0;\n\n    random_device rd;\n    mt19937 gen(rd());\n\n    string best_path = \"\";\n    int best_score = -1;\n\n    const int num_trials = 20000; // will be plus one greedy trial\n    for (int trial = 0; trial <= num_trials; ++trial) {\n        ++cur_timestamp;\n        int policy; // 0: uniform random, 1: weighted random, 2: greedy\n        if (trial == num_trials) {\n            policy = 2; // greedy at the end\n        } else {\n            policy = (gen() % 2); // 50% uniform, 50% weighted\n        }\n\n        int cur_r = si, cur_c = sj;\n        visited_tiles[tile[cur_r][cur_c]] = cur_timestamp;\n        int score = value[cur_r][cur_c];\n        string path = \"\";\n\n        while (true) {\n            // Collect unvisited neighbors\n            // Fixed: Changed to tuple with 5 elements to match emplace_back\n            vector<tuple<int, int, int, int, char>> candidates; // value, nr, nc, tid, dir\n            for (int d = 0; d < 4; ++d) {\n                int nr = cur_r + dr[d];\n                int nc = cur_c + dc[d];\n                if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n                int tid = tile[nr][nc];\n                if (visited_tiles[tid] == cur_timestamp) continue;\n                candidates.emplace_back(value[nr][nc], nr, nc, tid, dir_char[d]);\n            }\n            if (candidates.empty()) break;\n\n            int chosen_idx = 0;\n            if (policy == 2) {\n                // Greedy: choose the candidate with maximum value\n                for (int i = 1; i < (int)candidates.size(); ++i) {\n                    if (get<0>(candidates[i]) > get<0>(candidates[chosen_idx])) {\n                        chosen_idx = i;\n                    }\n                }\n            } else {\n                if (policy == 0) {\n                    // Uniform random\n                    chosen_idx = gen() % candidates.size();\n                } else {\n                    // Weighted random (weights = value)\n                    int total = 0;\n                    for (const auto& cand : candidates) {\n                        total += get<0>(cand);\n                    }\n                    if (total == 0) {\n                        chosen_idx = gen() % candidates.size();\n                    } else {\n                        int r = gen() % total;\n                        int cum = 0;\n                        for (int i = 0; i < (int)candidates.size(); ++i) {\n                            cum += get<0>(candidates[i]);\n                            if (cum > r) {\n                                chosen_idx = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Execute the chosen move\n            // Fixed: Updated structured binding to match 5-element tuple\n            auto [val, nr, nc, tid, dir] = candidates[chosen_idx];\n            path += dir;\n            cur_r = nr;\n            cur_c = nc;\n            visited_tiles[tid] = cur_timestamp;\n            score += val;\n        }\n\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n        }\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    const int N = 30;\n    // Base estimates for rows and columns\n    vector<double> row_base(N, 5000.0);\n    vector<double> col_base(N, 5000.0);\n    \n    // Helper to compute edge estimate from base values\n    auto get_edge_weight = [&](bool is_horizontal, int i, int j) {\n        return is_horizontal ? row_base[i] : col_base[j];\n    };\n\n    double lr = 0.2;  // initial learning rate\n    int total_updates = 0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        int start = si * N + sj;\n        int target = ti * N + tj;\n\n        const double INF = 1e18;\n        vector<double> dist(N*N, INF);\n        vector<int> prev(N*N, -1);\n        vector<char> prev_move(N*N);\n        dist[start] = 0.0;\n        priority_queue<pair<double, int>,\n                       vector<pair<double, int>>,\n                       greater<pair<double, int>>> pq;\n        pq.emplace(0.0, start);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            int ui = u / N, uj = u % N;\n\n            // Up\n            if (ui > 0) {\n                int v = (ui-1)*N + uj;\n                double w = get_edge_weight(false, ui-1, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'U';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Down\n            if (ui < N-1) {\n                int v = (ui+1)*N + uj;\n                double w = get_edge_weight(false, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'D';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Left\n            if (uj > 0) {\n                int v = ui*N + (uj-1);\n                double w = get_edge_weight(true, ui, uj-1);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'L';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Right\n            if (uj < N-1) {\n                int v = ui*N + (uj+1);\n                double w = get_edge_weight(true, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'R';\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        // Reconstruct path and collect row/column usage\n        vector<char> moves;\n        vector<pair<bool, int>> path_edges; // (is_horizontal, index)\n        map<int, int> row_count, col_count;\n\n        int cur = target;\n        while (cur != start) {\n            int p = prev[cur];\n            char dir = prev_move[cur];\n            moves.push_back(dir);\n\n            int pi = p / N, pj = p % N;\n            int ci = cur / N, cj = cur % N;\n\n            if (pi == ci) { // horizontal move\n                int j = min(pj, cj);\n                path_edges.push_back({true, pi});\n                row_count[pi]++;\n            } else { // vertical move\n                int i = min(pi, ci);\n                path_edges.push_back({false, pj});\n                col_count[pj]++;\n            }\n            cur = p;\n        }\n        reverse(moves.begin(), moves.end());\n\n        // Output\n        for (char c : moves) cout << c;\n        cout << endl;\n\n        // Read result\n        int res;\n        cin >> res;\n\n        // Compute predicted length using current base estimates\n        double L_est = 0.0;\n        for (auto& [is_h, idx] : path_edges) {\n            L_est += is_h ? row_base[idx] : col_base[idx];\n        }\n        int len = path_edges.size();\n        double measured = res;\n\n        // Multiplicative update factor\n        double factor = pow(measured / L_est, lr / len);\n\n        // Update row and column base values\n        for (auto& [is_h, idx] : path_edges) {\n            if (is_h) {\n                row_base[idx] *= factor;\n                row_base[idx] = max(1000.0, min(9000.0, row_base[idx]));\n            } else {\n                col_base[idx] *= factor;\n                col_base[idx] = max(1000.0, min(9000.0, col_base[idx]));\n            }\n        }\n\n        total_updates += len;\n        // Decay learning rate more slowly\n        lr = 0.2 / (1 + total_updates * 0.0001);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int BASE = 131;\n\nstruct SubInfo {\n    int start;\n    int k;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n    \n    // Hash each string\n    auto compute_hash_string = [](const string &s) -> uint64_t {\n        uint64_t h = 0;\n        for (char ch : s) {\n            h = h * BASE + (ch - 'A' + 1);\n        }\n        return h;\n    };\n    vector<uint64_t> str_hash(M);\n    unordered_map<uint64_t, int> hash_to_str;\n    for (int i = 0; i < M; ++i) {\n        str_hash[i] = compute_hash_string(strs[i]);\n        hash_to_str[str_hash[i]] = i;\n    }\n    \n    // Precompute for each cell the list of row/column substrings that contain it\n    vector<vector<SubInfo>> cell_row_info(N * N);\n    vector<vector<SubInfo>> cell_col_info(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cell = r * N + c;\n            for (int k = 2; k <= 12; ++k) {\n                // row substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (c >= s && c < s + k) in = true;\n                    } else {\n                        if (c >= s || c < (s + k) % N) in = true;\n                    }\n                    if (in) cell_row_info[cell].push_back({s, k});\n                }\n                // column substrings\n                for (int s = 0; s < N; ++s) {\n                    bool in = false;\n                    if (s + k <= N) {\n                        if (r >= s && r < s + k) in = true;\n                    } else {\n                        if (r >= s || r < (s + k) % N) in = true;\n                    }\n                    if (in) cell_col_info[cell].push_back({s, k});\n                }\n            }\n        }\n    }\n    \n    // Initialize random grid\n    vector<vector<char>> grid(N, vector<char>(N));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_letter(0, 7);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + dist_letter(rng);\n        }\n    }\n    \n    // Helper functions for row/column hash using the current grid\n    auto compute_hash_row = [&](int r, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int col = (start + i) % N;\n            h = h * BASE + (grid[r][col] - 'A' + 1);\n        }\n        return h;\n    };\n    auto compute_hash_col = [&](int c, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int row = (start + i) % N;\n            h = h * BASE + (grid[row][c] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    // Initialize count map for all substring hashes\n    unordered_map<uint64_t, int> cnt;\n    for (int r = 0; r < N; ++r) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_row(r, s, k)]++;\n            }\n        }\n    }\n    for (int c = 0; c < N; ++c) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= 12; ++k) {\n                cnt[compute_hash_col(c, s, k)]++;\n            }\n        }\n    }\n    \n    // Initial satisfaction\n    vector<bool> satisfied(M, false);\n    int c_sat = 0;\n    for (int i = 0; i < M; ++i) {\n        if (cnt[str_hash[i]] > 0) {\n            satisfied[i] = true;\n            ++c_sat;\n        }\n    }\n    \n    // Simulated annealing parameters\n    const int iterations = 200000;\n    double temp = 10.0;\n    const double cooling = 0.99995;\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    uniform_int_distribution<int> dist_cell(0, N - 1);\n    uniform_int_distribution<int> dist_newchar(0, 7);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int r = dist_cell(rng);\n        int col = dist_cell(rng);\n        int cell = r * N + col;\n        char old_char = grid[r][col];\n        char new_char = 'A' + dist_newchar(rng);\n        if (new_char == old_char) continue;\n        \n        // Collect old hashes for row and column substrings through this cell\n        vector<uint64_t> old_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            old_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            old_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        \n        // Temporarily change the cell to compute new hashes\n        grid[r][col] = new_char;\n        vector<uint64_t> new_hashes;\n        for (auto &info : cell_row_info[cell]) {\n            new_hashes.push_back(compute_hash_row(r, info.start, info.k));\n        }\n        for (auto &info : cell_col_info[cell]) {\n            new_hashes.push_back(compute_hash_col(col, info.start, info.k));\n        }\n        grid[r][col] = old_char;  // revert\n        \n        // Compute net changes in hash counts\n        unordered_map<uint64_t, int> delta_count;\n        for (size_t i = 0; i < old_hashes.size(); ++i) {\n            if (old_hashes[i] != new_hashes[i]) {\n                delta_count[old_hashes[i]]--;\n                delta_count[new_hashes[i]]++;\n            }\n        }\n        \n        // Estimate change in number of satisfied strings\n        int delta_c = 0;\n        for (auto &[hash, d] : delta_count) {\n            int old_cnt = cnt[hash];\n            int new_cnt = old_cnt + d;\n            if (old_cnt == 0 && new_cnt > 0) delta_c++;\n            if (old_cnt > 0 && new_cnt == 0) delta_c--;\n        }\n        \n        // Acceptance probability\n        bool accept = false;\n        if (delta_c > 0) {\n            accept = true;\n        } else if (temp > 1e-6) {\n            double prob = exp(delta_c / temp);\n            if (prob > dist_real(rng)) accept = true;\n        }\n        \n        if (accept) {\n            grid[r][col] = new_char;\n            for (auto &[hash, d] : delta_count) {\n                int old_cnt = cnt[hash];\n                cnt[hash] = old_cnt + d;\n                if (old_cnt == 0 && cnt[hash] > 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = true;\n                        ++c_sat;\n                    }\n                }\n                if (old_cnt > 0 && cnt[hash] == 0) {\n                    auto it = hash_to_str.find(hash);\n                    if (it != hash_to_str.end()) {\n                        satisfied[it->second] = false;\n                        --c_sat;\n                    }\n                }\n            }\n        }\n        \n        temp *= cooling;\n        if (c_sat == M) break;  // early exit if all satisfied\n    }\n    \n    // Output the matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n};\n\n// Hopcroft\u2013Karp for bipartite matching\nint hopcroft_karp(const vector<vector<int>>& adj, int L, int R,\n                  vector<int>& matchL, vector<int>& matchR) {\n    vector<int> dist(L, -1);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            dist[u] = 0;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (matchR[v] != -1 && dist[matchR[v]] == -1) {\n                dist[matchR[v]] = dist[u] + 1;\n                q.push(matchR[v]);\n            }\n        }\n    }\n    function<bool(int)> dfs = [&](int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 ||\n                (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n    int matching = 0;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1 && dfs(u)) ++matching;\n    }\n    return matching;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; ++i) cin >> grid_str[i];\n\n    // Convert grid: -1 for obstacle, otherwise cost (5-9)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Point> roads;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid_str[i][j];\n            if (c != '#') {\n                grid[i][j] = c - '0';\n                roads.push_back({i, j});\n            }\n        }\n    }\n\n    // ---------- row segments ----------\n    vector<vector<int>> row_seg(N, vector<int>(N, -1));\n    int L = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != -1) {\n                int start = j;\n                while (j < N && grid[i][j] != -1) ++j;\n                int end = j - 1;\n                for (int k = start; k <= end; ++k) row_seg[i][k] = L;\n                ++L;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ---------- column segments ----------\n    vector<vector<int>> col_seg(N, vector<int>(N, -1));\n    int R = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != -1) {\n                int start = i;\n                while (i < N && grid[i][j] != -1) ++i;\n                int end = i - 1;\n                for (int k = start; k <= end; ++k) col_seg[k][j] = R;\n                ++R;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ---------- bipartite graph (row segments vs column segments) ----------\n    vector<vector<int>> adj(L);\n    vector<vector<pair<int, Point>>> edge_coord(L); // for each row segment: (col_segment, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        adj[u].push_back(v);\n        edge_coord[u].push_back({v, {p.i, p.j}});\n    }\n\n    // ---------- minimum vertex cover (via maximum matching) ----------\n    vector<int> matchL(L, -1), matchR(R, -1);\n    hopcroft_karp(adj, L, R, matchL, matchR);\n\n    vector<bool> visL(L, false), visR(R, false);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            visL[u] = true;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (!visR[v]) {\n                visR[v] = true;\n                if (matchR[v] != -1 && !visL[matchR[v]]) {\n                    visL[matchR[v]] = true;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n    }\n    vector<bool> selected_row(L, false), selected_col(R, false);\n    for (int u = 0; u < L; ++u) selected_row[u] = !visL[u];\n    for (int v = 0; v < R; ++v) selected_col[v] = visR[v];\n\n    // ---------- selected segments ----------\n    vector<int> sel_row_list, sel_col_list;\n    for (int u = 0; u < L; ++u) if (selected_row[u]) sel_row_list.push_back(u);\n    for (int v = 0; v < R; ++v) if (selected_col[v]) sel_col_list.push_back(v);\n    int L2 = sel_row_list.size(), R2 = sel_col_list.size();\n    map<int, int> row_idx, col_idx;\n    for (int i = 0; i < L2; ++i) row_idx[sel_row_list[i]] = i;\n    for (int i = 0; i < R2; ++i) col_idx[sel_col_list[i]] = i;\n\n    // ---------- induced graph on selected segments ----------\n    vector<vector<int>> adj2(L2);\n    vector<vector<int>> radj2(R2);\n    vector<vector<pair<int, Point>>> edge_coord2(L2); // (col_idx, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        if (selected_row[u] && selected_col[v]) {\n            int u2 = row_idx[u];\n            int v2 = col_idx[v];\n            adj2[u2].push_back(v2);\n            radj2[v2].push_back(u2);\n            edge_coord2[u2].push_back({v2, {p.i, p.j}});\n        }\n    }\n\n    // ---------- minimum edge cover on induced graph ----------\n    vector<int> matchL2(L2, -1), matchR2(R2, -1);\n    hopcroft_karp(adj2, L2, R2, matchL2, matchR2);\n\n    vector<Point> S; // squares to visit\n    vector<bool> row_covered(L2, false), col_covered(R2, false);\n\n    // 1. take all matching edges\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (matchL2[u2] != -1) {\n            int v2 = matchL2[u2];\n            for (auto& e : edge_coord2[u2]) {\n                if (e.first == v2) {\n                    S.push_back(e.second);\n                    break;\n                }\n            }\n            row_covered[u2] = true;\n            col_covered[v2] = true;\n        }\n    }\n\n    // 2. cover unmatched rows\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (!row_covered[u2]) {\n            if (!adj2[u2].empty()) {\n                int v2 = adj2[u2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n                col_covered[v2] = true;\n            } else { // isolated row segment\n                int u_orig = sel_row_list[u2];\n                for (auto& p : roads) {\n                    if (row_seg[p.i][p.j] == u_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n            }\n        }\n    }\n\n    // 3. cover unmatched columns\n    for (int v2 = 0; v2 < R2; ++v2) {\n        if (!col_covered[v2]) {\n            if (!radj2[v2].empty()) {\n                int u2 = radj2[v2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            } else { // isolated column segment\n                int v_orig = sel_col_list[v2];\n                for (auto& p : roads) {\n                    if (col_seg[p.i][p.j] == v_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            }\n        }\n    }\n\n    // ---------- nodes for TSP (start + S without duplicates) ----------\n    vector<Point> nodes;\n    nodes.push_back({si, sj});\n    set<pair<int, int>> visited_set;\n    for (auto& p : S) {\n        if (p.i == si && p.j == sj) continue;\n        if (visited_set.insert({p.i, p.j}).second) {\n            nodes.push_back(p);\n        }\n    }\n    int n = nodes.size();\n\n    // ---------- Dijkstra from each node, build distance matrix and predecessors ----------\n    const int INF = 1e9;\n    vector<vector<int>> dist_mat(n, vector<int>(n, INF));\n    vector<vector<vector<char>>> pred(n, vector<vector<char>>(N, vector<char>(N, 0)));\n\n    auto dijkstra = [&](int src_idx) {\n        int si = nodes[src_idx].i, sj = nodes[src_idx].j;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        dist[si][sj] = 0;\n        pred[src_idx][si][sj] = 0; // 0 marks the source\n        priority_queue<pair<int, pair<int, int>>,\n                       vector<pair<int, pair<int, int>>>,\n                       greater<>> pq;\n        pq.push({0, {si, sj}});\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dir[4] = {'U', 'D', 'L', 'R'};\n        while (!pq.empty()) {\n            auto [d, pos] = pq.top(); pq.pop();\n            int i = pos.first, j = pos.second;\n            if (d != dist[i][j]) continue;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid[ni][nj] == -1) continue;\n                int nd = d + grid[ni][nj];\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    pred[src_idx][ni][nj] = dir[k];\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n        for (int t = 0; t < n; ++t) {\n            int ti = nodes[t].i, tj = nodes[t].j;\n            dist_mat[src_idx][t] = dist[ti][tj];\n        }\n    };\n    for (int s = 0; s < n; ++s) dijkstra(s);\n\n    // ---------- TSP heuristic (nearest neighbour + 2\u2011opt + or\u2011opt) ----------\n    vector<int> tour;\n    vector<bool> vis(n, false);\n    tour.push_back(0); // start at index 0\n    vis[0] = true;\n    int cur = 0;\n    for (int iter = 0; iter < n - 1; ++iter) {\n        int nxt = -1, best = INF;\n        for (int v = 0; v < n; ++v) {\n            if (!vis[v] && dist_mat[cur][v] < best) {\n                best = dist_mat[cur][v];\n                nxt = v;\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = true;\n        cur = nxt;\n    }\n    tour.push_back(0); // return to start\n\n    auto tour_cost = [&](const vector<int>& t) {\n        int cost = 0;\n        for (size_t i = 0; i < t.size() - 1; ++i) cost += dist_mat[t[i]][t[i+1]];\n        return cost;\n    };\n\n    int best_cost = tour_cost(tour);\n    vector<int> best_tour = tour;\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // 2\u2011opt\n        for (size_t i = 0; i < best_tour.size() - 2; ++i) {\n            for (size_t j = i + 2; j < best_tour.size() - 1; ++j) {\n                int a = best_tour[i], b = best_tour[i+1], c = best_tour[j], d = best_tour[j+1];\n                int cur_cost = dist_mat[a][b] + dist_mat[c][d];\n                int seg_orig = 0;\n                for (size_t k = i+1; k < j; ++k) seg_orig += dist_mat[best_tour[k]][best_tour[k+1]];\n                int new_cost = dist_mat[a][c] + dist_mat[b][d];\n                int seg_rev = 0;\n                for (size_t k = j; k > i+1; --k) seg_rev += dist_mat[best_tour[k]][best_tour[k-1]];\n                if (cur_cost + seg_orig > new_cost + seg_rev) {\n                    reverse(best_tour.begin() + i + 1, best_tour.begin() + j + 1);\n                    best_cost += (new_cost + seg_rev) - (cur_cost + seg_orig);\n                    improved = true;\n                }\n            }\n        }\n        // or\u2011opt: relocate single nodes\n        for (size_t i = 1; i < best_tour.size() - 1; ++i) { // i is index of node to move (non\u2011start)\n            int u = best_tour[i];\n            int a = best_tour[i-1], c = best_tour[i+1];\n            for (size_t j = 1; j < best_tour.size() - 1; ++j) {\n                if (j == i-1 || j == i || j == i+1) continue;\n                int d = best_tour[j-1], e = best_tour[j];\n                int delta = -dist_mat[a][u] - dist_mat[u][c] + dist_mat[a][c]\n                            - dist_mat[d][e] + dist_mat[d][u] + dist_mat[u][e];\n                if (delta < 0) {\n                    // apply move: remove u from i, insert at j\n                    best_tour.erase(best_tour.begin() + i);\n                    if (j > i) j--;\n                    best_tour.insert(best_tour.begin() + j, u);\n                    best_cost += delta;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n    }\n    tour = best_tour;\n\n    // ---------- build move string ----------\n    string moves;\n    for (size_t idx = 0; idx < tour.size() - 1; ++idx) {\n        int src_idx = tour[idx];\n        int tgt_idx = tour[idx+1];\n        int ci = nodes[tgt_idx].i, cj = nodes[tgt_idx].j;\n        vector<char> path;\n        while (!(ci == nodes[src_idx].i && cj == nodes[src_idx].j)) {\n            char d = pred[src_idx][ci][cj];\n            path.push_back(d);\n            // move to parent\n            if (d == 'U') ci++;\n            else if (d == 'D') ci--;\n            else if (d == 'L') cj++;\n            else if (d == 'R') cj--;\n        }\n        reverse(path.begin(), path.end());\n        for (char c : path) moves.push_back(c);\n    }\n\n    cout << moves << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Function to compute expected completion time given estimated deficit w\ndouble expected_time(double w) {\n    if (w <= 0.0) return 1.0;\n    if (w >= 4.0) return w;\n    // Precomputed expected times for integer w (0 to 4)\n    const double E0 = 1.0;\n    const double E1 = 13.0 / 7.0;\n    const double E2 = 17.0 / 7.0;\n    const double E3 = 22.0 / 7.0;\n    const double E4 = 4.0;\n    int floor_w = (int)w;\n    double frac = w - floor_w;\n    if (floor_w == 0) return E0 + frac * (E1 - E0);\n    if (floor_w == 1) return E1 + frac * (E2 - E1);\n    if (floor_w == 2) return E2 + frac * (E3 - E2);\n    if (floor_w == 3) return E3 + frac * (E4 - E3);\n    return w; // fallback\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            cin >> d[i][k];\n        }\n    }\n\n    vector<vector<int>> children(N);\n    vector<int> prereq_count(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        prereq_count[v]++;\n    }\n\n    // Critical path length L[i]\n    vector<int> L(N, 1);\n    for (int i = N - 1; i >= 0; --i) {\n        for (int v : children[i]) {\n            L[i] = max(L[i], 1 + L[v]);\n        }\n    }\n\n    // Available tasks (prerequisites satisfied)\n    vector<int> avail;\n    for (int i = 0; i < N; ++i) {\n        if (prereq_count[i] == 0) {\n            avail.push_back(i);\n        }\n    }\n\n    // Task status: 0=not started, 1=started, 2=completed\n    vector<int> task_status(N, 0);\n\n    // Team member state\n    vector<int> current_task(M, -1);      // -1 if idle\n    vector<int> start_day(M, -1);\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));  // estimated skill levels\n\n    int cur_day = 1;\n\n    while (true) {\n        // Collect idle members\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // Collect currently available tasks (status 0)\n        vector<int> today_avail;\n        for (int i : avail) {\n            if (task_status[i] == 0) {\n                today_avail.push_back(i);\n            }\n        }\n\n        // Sort by critical path length descending\n        sort(today_avail.begin(), today_avail.end(),\n             [&](int a, int b) { return L[a] > L[b]; });\n\n        vector<pair<int, int>> assignments; // (member, task)\n        vector<bool> member_used(M, false);\n\n        for (int i : today_avail) {\n            if (idle_members.empty()) break;\n\n            int best_j = -1;\n            double best_expected = 1e9;\n            for (int j : idle_members) {\n                if (member_used[j]) continue;\n                double w_est = 0.0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        w_est += d[i][k] - s_est[j][k];\n                    }\n                }\n                double exp_t = expected_time(w_est);\n                if (exp_t < best_expected) {\n                    best_expected = exp_t;\n                    best_j = j;\n                }\n            }\n            if (best_j != -1) {\n                assignments.emplace_back(best_j, i);\n                member_used[best_j] = true;\n                // Update current task and start day immediately\n                current_task[best_j] = i;\n                start_day[best_j] = cur_day;\n                task_status[i] = 1; // mark as started\n            }\n        }\n\n        // Output assignments\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        // Read response line\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        istringstream iss(line);\n        int n;\n        iss >> n;\n        vector<int> completing;\n        for (int i = 0; i < n; ++i) {\n            int f;\n            iss >> f;\n            completing.push_back(f - 1); // to 0-index\n        }\n\n        // Process completions\n        for (int j : completing) {\n            int i = current_task[j];\n            if (i == -1) continue; // should not happen\n\n            int t = cur_day - start_day[j] + 1; // actual duration\n\n            // Update skill estimates for member j\n            double w_est = 0.0;\n            int num_deficient = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    w_est += d[i][k] - s_est[j][k];\n                    num_deficient++;\n                }\n            }\n            if (num_deficient > 0) {\n                double delta = (w_est - t) / num_deficient;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        s_est[j][k] += delta;\n                        if (s_est[j][k] < 0.0) s_est[j][k] = 0.0;\n                    }\n                }\n            }\n\n            // Mark task as completed\n            task_status[i] = 2;\n            current_task[j] = -1;\n\n            // Update dependent tasks\n            for (int v : children[i]) {\n                prereq_count[v]--;\n                if (prereq_count[v] == 0) {\n                    avail.push_back(v);\n                }\n            }\n        }\n\n        ++cur_day;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <ctime>\n#include <cassert>\n\nusing namespace std;\n\nstruct Order {\n    int id;          // original index (0-based)\n    int a, b, c, d;  // restaurant and destination\n    int cx, cy;      // centroid\n};\n\nvector<Order> orders; // all 1000 orders\n\n// Manhattan distance\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Point in the route: (order_index, type) type: 0=restaurant, 1=destination\nusing Point = pair<int, int>;\n\n// Compute total distance for a sequence of points\nint total_distance(const vector<Point>& seq, const vector<Order>& sel) {\n    int cur_x = 400, cur_y = 400;\n    int total = 0;\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) { // restaurant\n            total += dist(cur_x, cur_y, sel[idx].a, sel[idx].b);\n            cur_x = sel[idx].a;\n            cur_y = sel[idx].b;\n        } else { // destination\n            total += dist(cur_x, cur_y, sel[idx].c, sel[idx].d);\n            cur_x = sel[idx].c;\n            cur_y = sel[idx].d;\n        }\n    }\n    total += dist(cur_x, cur_y, 400, 400);\n    return total;\n}\n\n// Check precedence constraints: for each order, restaurant before destination\nbool is_valid(const vector<Point>& seq, int m) {\n    vector<int> rest_pos(m, -1), dest_pos(m, -1);\n    for (size_t i = 0; i < seq.size(); ++i) {\n        int idx = seq[i].first;\n        if (seq[i].second == 0) {\n            rest_pos[idx] = i;\n        } else {\n            dest_pos[idx] = i;\n        }\n    }\n    for (int i = 0; i < m; ++i) {\n        if (rest_pos[i] == -1 || dest_pos[i] == -1) return false;\n        if (rest_pos[i] >= dest_pos[i]) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read all orders\n    orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n        // Compute centroid\n        orders[i].cx = (orders[i].a + orders[i].c) / 2;\n        orders[i].cy = (orders[i].b + orders[i].d) / 2;\n    }\n\n    // Selection: pick 50 orders with centroid closest to office (400,400)\n    vector<int> indices(1000);\n    for (int i = 0; i < 1000; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int di = dist(400, 400, orders[i].cx, orders[i].cy);\n        int dj = dist(400, 400, orders[j].cx, orders[j].cy);\n        return di < dj;\n    });\n    vector<Order> selected;\n    vector<bool> used(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        selected.push_back(orders[indices[i]]);\n        used[indices[i]] = true;\n    }\n    int m = 50;\n\n    // Generate initial sequence using nearest neighbor with precedence\n    vector<Point> seq;\n    vector<bool> rest_done(m, false), dest_done(m, false);\n    vector<int> available; // orders whose restaurant done but destination not\n    int cur_x = 400, cur_y = 400;\n\n    for (int step = 0; step < 2 * m; ++step) {\n        int best_idx = -1;\n        int best_type = -1;\n        int best_cost = 1e9;\n\n        // Consider restaurants of unvisited orders\n        for (int i = 0; i < m; ++i) {\n            if (rest_done[i]) continue;\n            int cost = dist(cur_x, cur_y, selected[i].a, selected[i].b);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 0;\n            }\n        }\n        // Consider destinations of available orders\n        for (int i : available) {\n            int cost = dist(cur_x, cur_y, selected[i].c, selected[i].d);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 1;\n            }\n        }\n        assert(best_idx != -1);\n        seq.emplace_back(best_idx, best_type);\n        if (best_type == 0) {\n            rest_done[best_idx] = true;\n            available.push_back(best_idx);\n        } else {\n            dest_done[best_idx] = true;\n            // Remove from available\n            auto it = find(available.begin(), available.end(), best_idx);\n            if (it != available.end()) available.erase(it);\n        }\n        // Update current position\n        if (best_type == 0) {\n            cur_x = selected[best_idx].a;\n            cur_y = selected[best_idx].b;\n        } else {\n            cur_x = selected[best_idx].c;\n            cur_y = selected[best_idx].d;\n        }\n    }\n    assert(is_valid(seq, m));\n    int total = total_distance(seq, selected);\n\n    // Local search: 2-opt (segment reversal) and point swaps\n    clock_t start = clock();\n    const double time_limit = 1.9 * CLOCKS_PER_SEC;\n    bool improved = true;\n    while (improved && (clock() - start) < time_limit) {\n        improved = false;\n        // Try all segment reversals\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                vector<Point> new_seq = seq;\n                reverse(new_seq.begin() + i, new_seq.begin() + j + 1);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n        // Try all point swaps\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                if (i == j) continue;\n                vector<Point> new_seq = seq;\n                swap(new_seq[i], new_seq[j]);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n    }\n\n    // Output selected orders (1-based indices)\n    cout << m;\n    for (const auto& order : selected) {\n        cout << ' ' << order.id + 1;\n    }\n    cout << '\\n';\n\n    // Output route: office, then points in seq, then office\n    cout << 1 + 2 * m + 1; // start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) {\n            cout << ' ' << selected[idx].a << ' ' << selected[idx].b;\n        } else {\n            cout << ' ' << selected[idx].c << ' ' << selected[idx].d;\n        }\n    }\n    cout << \" 400 400\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct DSU {\n    vector<int> parent, rank;\n    int components;\n    DSU(int n) : parent(n), rank(n, 0), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        components--;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (accepted == 399) {\n            cout << 0 << endl;\n            continue;\n        }\n        if (dsu.find(u[i]) == dsu.find(v[i])) {\n            cout << 0 << endl;\n            continue;\n        }\n        cout << 1 << endl;\n        dsu.unite(u[i], v[i]);\n        accepted++;\n        cout.flush();\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 30;\nconst double WALL_BONUS = 0.5;  // Bonus for placing any wall\nconst double PET_PENALTY = 2.0; // Penalty per pet in component\n\nint N, M;\nint px[20], py[20], pt[20];\nint hx[10], hy[10];\nbool passable[31][31];\n\nbool pet_at[31][31];\nbool human_at[31][31];\nbool adj_to_pet[31][31];\n\nbool blocked_this_turn[31][31];\n\nrandom_device rd;\nmt19937 rng(rd());\n\n// BFS that counts pets and returns size\nint bfs(int sx, int sy, int& pet_count, bool temp_blocked = false, int tbx = -1, int tby = -1) {\n    static bool visited[31][31];\n    memset(visited, 0, sizeof(visited));\n    queue<pair<int,int>> q;\n    if (passable[sx][sy] && !blocked_this_turn[sx][sy] && \n        !(temp_blocked && sx==tbx && sy==tby)) {\n        q.push({sx, sy});\n        visited[sx][sy] = true;\n    }\n    int size = 0;\n    pet_count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        size++;\n        if (pet_at[x][y]) pet_count++;\n        for (int dx = -1; dx <= 1; dx++) {\n            for (int dy = -1; dy <= 1; dy++) {\n                if (abs(dx) + abs(dy) != 1) continue;\n                int nx = x + dx, ny = y + dy;\n                if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) continue;\n                if (!passable[nx][ny]) continue;\n                if (blocked_this_turn[nx][ny]) continue;\n                if (temp_blocked && nx==tbx && ny==tby) continue;\n                if (visited[nx][ny]) continue;\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return size;\n}\n\n// Simulate pet movement for one step to estimate future pet positions\nvoid simulate_pet_step(int& x, int& y, int type) {\n    // Simplified: for now, just move randomly (can be improved per type)\n    vector<pair<int,int>> moves = {{-1,0},{1,0},{0,-1},{0,1}};\n    vector<pair<int,int>> valid;\n    for (auto [dx, dy] : moves) {\n        int nx = x + dx, ny = y + dy;\n        if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN && passable[nx][ny]) {\n            valid.push_back({nx, ny});\n        }\n    }\n    if (!valid.empty()) {\n        auto [nx, ny] = valid[rng() % valid.size()];\n        x = nx; y = ny;\n    }\n}\n\nint main() {\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> px[i] >> py[i] >> pt[i];\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> hx[i] >> hy[i];\n    }\n\n    // Initialize passable grid\n    for (int i = 1; i <= MAXN; i++) {\n        for (int j = 1; j <= MAXN; j++) {\n            passable[i][j] = true;\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        // Precompute grids\n        memset(pet_at, 0, sizeof(pet_at));\n        for (int i = 0; i < N; i++) pet_at[px[i]][py[i]] = true;\n        memset(human_at, 0, sizeof(human_at));\n        for (int i = 0; i < M; i++) human_at[hx[i]][hy[i]] = true;\n        memset(adj_to_pet, 0, sizeof(adj_to_pet));\n        for (int i = 0; i < N; i++) {\n            int x = px[i], y = py[i];\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    if (abs(dx) + abs(dy) != 1) continue;\n                    int nx = x + dx, ny = y + dy;\n                    if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN) {\n                        adj_to_pet[nx][ny] = true;\n                    }\n                }\n            }\n        }\n\n        memset(blocked_this_turn, 0, sizeof(blocked_this_turn));\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        string actions(M, '.');\n\n        for (int idx : order) {\n            int x = hx[idx], y = hy[idx];\n            double best_value = -1e9;\n            char best_action = '.';\n\n            // Compute current pet count for reference\n            int P0;\n            bfs(x, y, P0);\n\n            auto evaluate = [&](char action) -> double {\n                int nx = x, ny = y;\n                bool is_block = false;\n                bool is_move = false;\n                int tbx = -1, tby = -1;\n\n                if (action == '.') {\n                    // Stay\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    // Block\n                    is_block = true;\n                    if (action == 'u') { nx = x-1; ny = y; }\n                    else if (action == 'd') { nx = x+1; ny = y; }\n                    else if (action == 'l') { nx = x; ny = y-1; }\n                    else if (action == 'r') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (pet_at[nx][ny]) return -1e9;\n                    if (human_at[nx][ny]) return -1e9;\n                    if (adj_to_pet[nx][ny]) return -1e9;\n                    tbx = nx; tby = ny;\n                } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // Move\n                    is_move = true;\n                    if (action == 'U') { nx = x-1; ny = y; }\n                    else if (action == 'D') { nx = x+1; ny = y; }\n                    else if (action == 'L') { nx = x; ny = y-1; }\n                    else if (action == 'R') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (blocked_this_turn[nx][ny]) return -1e9;\n                } else {\n                    return -1e9;\n                }\n\n                // Compute component after action\n                int start_x = is_move ? nx : x;\n                int start_y = is_move ? ny : y;\n                int pet_count;\n                int comp_size = bfs(start_x, start_y, pet_count, is_block, tbx, tby);\n                \n                // Base value with heavy pet penalty\n                double value = (comp_size / 900.0) * pow(0.5, pet_count * PET_PENALTY);\n                \n                // Bonus for placing a wall\n                if (is_block) {\n                    value += WALL_BONUS;\n                    // Additional bonus for removing pets\n                    if (P0 > pet_count) {\n                        value += 2.0 * (P0 - pet_count);\n                    }\n                }\n                \n                // Small random noise to break ties\n                value += (rng() % 1000) / 1000000.0;\n                return value;\n            };\n\n            vector<char> actions_list = {'.', 'u', 'd', 'l', 'r', 'U', 'D', 'L', 'R'};\n            for (char a : actions_list) {\n                double val = evaluate(a);\n                if (val > best_value) {\n                    best_value = val;\n                    best_action = a;\n                }\n            }\n\n            actions[idx] = best_action;\n\n            if (best_action == 'u' || best_action == 'd' || best_action == 'l' || best_action == 'r') {\n                int bx = x, by = y;\n                if (best_action == 'u') bx = x-1;\n                else if (best_action == 'd') bx = x+1;\n                else if (best_action == 'l') by = y-1;\n                else if (best_action == 'r') by = y+1;\n                blocked_this_turn[bx][by] = true;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        // Read and apply 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') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n            }\n        }\n\n        // Update passable grid with walls\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'u' || a == 'd' || a == 'l' || a == 'r') {\n                int bx = hx[i], by = hy[i];\n                if (a == 'u') bx = hx[i]-1;\n                else if (a == 'd') bx = hx[i]+1;\n                else if (a == 'l') by = hy[i]-1;\n                else if (a == 'r') by = hy[i]+1;\n                passable[bx][by] = false;\n            }\n        }\n\n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') hx[i]--;\n            else if (a == 'D') hx[i]++;\n            else if (a == 'L') hy[i]--;\n            else if (a == 'R') hy[i]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0:U, 1:D, 2:L, 3:R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Precompute next cell for each cell and direction\nvector<vector<vector<pair<int, int>>>> precompute_next(\n    const vector<vector<int>>& h,\n    const vector<vector<int>>& v) {\n    vector<vector<vector<pair<int, int>>>> next(4, vector<vector<pair<int, int>>>(20, vector<pair<int, int>>(20)));\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            // U\n            if (i > 0 && v[i-1][j] == 0)\n                next[0][i][j] = {i-1, j};\n            else\n                next[0][i][j] = {i, j};\n            // D\n            if (i < 19 && v[i][j] == 0)\n                next[1][i][j] = {i+1, j};\n            else\n                next[1][i][j] = {i, j};\n            // L\n            if (j > 0 && h[i][j-1] == 0)\n                next[2][i][j] = {i, j-1};\n            else\n                next[2][i][j] = {i, j};\n            // R\n            if (j < 19 && h[i][j] == 0)\n                next[3][i][j] = {i, j+1};\n            else\n                next[3][i][j] = {i, j};\n        }\n    }\n    return next;\n}\n\n// BFS to find a shortest path from start to target\nstring bfs_path(int si, int sj, int ti, int tj,\n                const vector<vector<int>>& h,\n                const vector<vector<int>>& v) {\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move(20, vector<char>(20, ' '));\n    queue<pair<int, int>> q;\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        // Try four directions\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            // Check walls\n            if (d == 0 && (i == 0 || v[i-1][j] == 1)) continue;\n            if (d == 1 && (i == 19 || v[i][j] == 1)) continue;\n            if (d == 2 && (j == 0 || h[i][j-1] == 1)) continue;\n            if (d == 3 && (j == 19 || h[i][j] == 1)) continue;\n            if (!visited[ni][nj]) {\n                visited[ni][nj] = true;\n                parent[ni][nj] = {i, j};\n                move[ni][nj] = dir_char[d];\n                q.emplace(ni, nj);\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path = \"\";\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        char m = move[i][j];\n        path += m;\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Simulate the stochastic process and compute expected score\ndouble simulate(const string& s,\n                const vector<vector<vector<pair<int, int>>>>& next,\n                int si, int sj, int ti, int tj, double p) {\n    vector<vector<double>> dist(20, vector<double>(20, 0.0));\n    dist[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int t = 1; t <= L; ++t) {\n        char c = s[t-1];\n        int d = -1;\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        vector<vector<double>> new_dist(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob = dist[i][j];\n                if (prob == 0.0) continue;\n                // With probability p, forget and stay\n                new_dist[i][j] += prob * p;\n                // With probability 1-p, try to move\n                auto [ni, nj] = next[d][i][j];\n                if (ni == ti && nj == tj) {\n                    score += prob * (1-p) * (401 - t);\n                } else {\n                    new_dist[ni][nj] += prob * (1-p);\n                }\n            }\n        }\n        dist = new_dist;\n    }\n    return score;\n}\n\n// Generate greedy nominal string (always try to move towards target)\nstring greedy_nominal(int si, int sj, int ti, int tj,\n                      const vector<vector<int>>& h,\n                      const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';  // arbitrary after reaching target\n            continue;\n        }\n        char best = 'R';\n        bool moved = false;\n        // Try right\n        if (cur_c < tj && h[cur_r][cur_c] == 0) {\n            best = 'R';\n            moved = true;\n        }\n        // Try down\n        if (!moved && cur_r < ti && v[cur_r][cur_c] == 0) {\n            best = 'D';\n            moved = true;\n        }\n        // Try left\n        if (!moved && cur_c > tj && (cur_c > 0 && h[cur_r][cur_c-1] == 0)) {\n            best = 'L';\n            moved = true;\n        }\n        // Try up\n        if (!moved && cur_r > ti && (cur_r > 0 && v[cur_r-1][cur_c] == 0)) {\n            best = 'U';\n            moved = true;\n        }\n        // If no move reduces Manhattan distance, try any possible move\n        if (!moved) {\n            if (cur_c < 19 && h[cur_r][cur_c] == 0) best = 'R';\n            else if (cur_r < 19 && v[cur_r][cur_c] == 0) best = 'D';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) best = 'L';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) best = 'U';\n            else best = 'R'; // should not happen\n        }\n        cand += best;\n        // Update nominal position\n        if (best == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (best == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (best == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n        else if (best == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n    }\n    return cand;\n}\n\n// Generate alternating direction string (prioritize down then right)\nstring alternating_string(int si, int sj, int ti, int tj,\n                          const vector<vector<int>>& h,\n                          const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char dir = 'D';\n        if (cur_r > ti) dir = 'U';\n        else if (cur_c < tj) dir = 'R';\n        else if (cur_c > tj) dir = 'L';\n        // else cur_r < ti already set to 'D'\n        bool possible = false;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) possible = true;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) possible = true;\n        if (!possible) {\n            // Try any possible direction\n            if (cur_r < 19 && v[cur_r][cur_c] == 0) dir = 'D';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) dir = 'U';\n            else if (cur_c < 19 && h[cur_r][cur_c] == 0) dir = 'R';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) dir = 'L';\n            else dir = 'R';\n        }\n        cand += dir;\n        // Update nominal position\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n    }\n    return cand;\n}\n\n// DP for optimal adaptive value function V[t][i][j] (t steps remaining)\nvector<vector<vector<double>>> compute_V(int ti, int tj, double p,\n                                         const vector<vector<vector<pair<int, int>>>>& next) {\n    vector<vector<vector<double>>> V(201, vector<vector<double>>(20, vector<double>(20, 0.0)));\n    for (int t = 1; t <= 200; ++t) {\n        int step_num = 201 - t;   // the step number if we take this step now\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    V[t][i][j] = 0.0;\n                    continue;\n                }\n                double best = -1e9;\n                for (int a = 0; a < 4; ++a) {\n                    double val = 0.0;\n                    // stay (forget)\n                    val += p * V[t-1][i][j];\n                    // move (no forget)\n                    auto [ni, nj] = next[a][i][j];\n                    if (ni == ti && nj == tj) {\n                        val += (1-p) * (401 - step_num);\n                    } else {\n                        val += (1-p) * V[t-1][ni][nj];\n                    }\n                    if (val > best) best = val;\n                }\n                V[t][i][j] = best;\n            }\n        }\n    }\n    return V;\n}\n\n// Lookahead greedy sequence with dynamic depth and pruning\nstring lookahead_greedy_sequence_v2(int si, int sj, int ti, int tj, double p,\n                                    const vector<vector<vector<pair<int, int>>>>& next,\n                                    const vector<vector<vector<double>>>& V) {\n    vector<vector<double>> prob(20, vector<double>(20, 0.0));\n    prob[si][sj] = 1.0;\n    string s = \"\";\n    const int MAX_DEPTH = 5; // total depth including current step\n    const double EPS = 1e-12; // threshold for ignoring low probabilities\n\n    for (int t = 1; t <= 200; ++t) {\n        int remaining_after = 200 - t;   // steps after current step\n        int lookahead = min(MAX_DEPTH - 1, remaining_after); // how many more steps we will explicitly simulate\n        int terminal_rem = remaining_after - lookahead; // steps remaining after lookahead\n\n        double best_score = -1e9;\n        int best_action = 0;\n\n        for (int first_a = 0; first_a < 4; ++first_a) {\n            // Immediate reward and distribution after first action\n            double immediate = 0.0;\n            vector<vector<double>> dist1(20, vector<double>(20, 0.0));\n            for (int i = 0; i < 20; ++i) {\n                for (int j = 0; j < 20; ++j) {\n                    double prob_ij = prob[i][j];\n                    if (prob_ij < EPS) continue;\n                    // stay\n                    dist1[i][j] += prob_ij * p;\n                    // move\n                    auto [ni, nj] = next[first_a][i][j];\n                    if (ni == ti && nj == tj) {\n                        immediate += prob_ij * (1-p) * (401 - t);\n                    } else {\n                        dist1[ni][nj] += prob_ij * (1-p);\n                    }\n                }\n            }\n\n            // Prune if total probability in dist1 is negligible\n            double total_prob1 = 0.0;\n            for (int i = 0; i < 20; ++i)\n                for (int j = 0; j < 20; ++j)\n                    total_prob1 += dist1[i][j];\n            if (total_prob1 < EPS) {\n                // This branch is almost impossible, skip\n                double total = immediate;\n                if (total > best_score) {\n                    best_score = total;\n                    best_action = first_a;\n                }\n                continue;\n            }\n\n            // Lookahead for the next lookahead steps\n            double best_continuation = -1e9;\n\n            // Recursive DFS over sequences of length lookahead\n            function<void(int, vector<vector<double>>, double)> dfs = [&](int depth, vector<vector<double>> cur_dist, double cur_reward) {\n                if (depth == lookahead) {\n                    // Add terminal value\n                    double term = 0.0;\n                    if (terminal_rem > 0) {\n                        for (int i = 0; i < 20; ++i) {\n                            for (int j = 0; j < 20; ++j) {\n                                term += cur_dist[i][j] * V[terminal_rem][i][j];\n                            }\n                        }\n                    }\n                    double total = cur_reward + term;\n                    if (total > best_continuation) best_continuation = total;\n                    return;\n                }\n                // Prune if total probability in cur_dist is negligible\n                double total_prob = 0.0;\n                for (int i = 0; i < 20; ++i)\n                    for (int j = 0; j < 20; ++j)\n                        total_prob += cur_dist[i][j];\n                if (total_prob < EPS) {\n                    // This branch is almost impossible, its contribution is negligible\n                    // We still need to evaluate it with zero reward? Actually, we can just return because it won't affect best_continuation.\n                    return;\n                }\n\n                int next_step = t + 1 + depth;   // step index for this action\n                for (int a = 0; a < 4; ++a) {\n                    vector<vector<double>> new_dist(20, vector<double>(20, 0.0));\n                    double add_reward = 0.0;\n                    for (int i = 0; i < 20; ++i) {\n                        for (int j = 0; j < 20; ++j) {\n                            double prob_ij = cur_dist[i][j];\n                            if (prob_ij < EPS) continue;\n                            // stay\n                            new_dist[i][j] += prob_ij * p;\n                            // move\n                            auto [ni, nj] = next[a][i][j];\n                            if (ni == ti && nj == tj) {\n                                add_reward += prob_ij * (1-p) * (401 - next_step);\n                            } else {\n                                new_dist[ni][nj] += prob_ij * (1-p);\n                            }\n                        }\n                    }\n                    // Prune new_dist if total probability is negligible\n                    double new_total_prob = 0.0;\n                    for (int i = 0; i < 20; ++i)\n                        for (int j = 0; j < 20; ++j)\n                            new_total_prob += new_dist[i][j];\n                    if (new_total_prob < EPS) {\n                        // The branch is almost impossible, we can still evaluate it with the reward so far?\n                        // But if new_total_prob is zero, then the reward add_reward might be non-zero? Actually, if new_total_prob is zero, it means no probability mass remains, but add_reward could be non-zero if some mass reached target. However, if new_total_prob is zero, all mass either reached target or was lost? Wait, we only add to new_dist for non-target states. If all mass reached target, then new_total_prob is zero and add_reward includes all that mass. So we should still consider this branch because it yields reward.\n                        // So we should not prune based solely on new_total_prob. Instead, we should consider the branch if add_reward > 0 or new_total_prob > 0.\n                    }\n                    dfs(depth + 1, new_dist, cur_reward + add_reward);\n                }\n            };\n\n            dfs(0, dist1, 0.0);\n\n            double total = immediate + best_continuation;\n            if (total > best_score) {\n                best_score = total;\n                best_action = first_a;\n            }\n        }\n\n        s += dir_char[best_action];\n\n        // Update probability distribution for the chosen action (actual step)\n        vector<vector<double>> new_prob(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob_ij = prob[i][j];\n                if (prob_ij < EPS) continue;\n                // stay\n                new_prob[i][j] += prob_ij * p;\n                // move\n                auto [ni, nj] = next[best_action][i][j];\n                if (ni == ti && nj == tj) {\n                    // reached target, do not add\n                } else {\n                    new_prob[ni][nj] += prob_ij * (1-p);\n                }\n            }\n        }\n        prob = new_prob;\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    vector<vector<int>> h(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 19; ++j) {\n            h[i][j] = line[j] - '0';\n        }\n    }\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 20; ++j) {\n            v[i][j] = line[j] - '0';\n        }\n    }\n\n    // Precompute next cells\n    auto next_cell = precompute_next(h, v);\n\n    // Compute optimal adaptive value function V\n    auto V = compute_V(ti, tj, p, next_cell);\n\n    // Find a shortest path\n    string shortest_path = bfs_path(si, sj, ti, tj, h, v);\n    int k = shortest_path.size();\n\n    // Generate candidates\n    vector<string> candidates;\n\n    // 1. Shortest path itself\n    if (k > 0) {\n        candidates.push_back(shortest_path);\n    }\n\n    // 2. Repeat the whole path (padded to length 200)\n    if (k > 0) {\n        int t = 200 / k;\n        int rem = 200 % k;\n        string cand = \"\";\n        for (int i = 0; i < t; ++i) cand += shortest_path;\n        cand += shortest_path.substr(0, rem);\n        candidates.push_back(cand);\n    }\n\n    // 3. Repeat each move m times (m = floor(200/k))\n    if (k > 0) {\n        int m = 200 / k;\n        string cand = \"\";\n        for (char c : shortest_path) {\n            for (int i = 0; i < m; ++i) cand += c;\n        }\n        candidates.push_back(cand);\n    }\n\n    // 4. Greedy nominal moves\n    candidates.push_back(greedy_nominal(si, sj, ti, tj, h, v));\n\n    // 5. Alternating direction\n    candidates.push_back(alternating_string(si, sj, ti, tj, h, v));\n\n    // 6. Lookahead greedy with dynamic depth and pruning\n    candidates.push_back(lookahead_greedy_sequence_v2(si, sj, ti, tj, p, next_cell, V));\n\n    // Evaluate each candidate and pick the best\n    double best_score = -1.0;\n    string best_str = \"\";\n    for (const string& cand : candidates) {\n        double score = simulate(cand, next_cell, si, sj, ti, tj, p);\n        if (score > best_score) {\n            best_score = score;\n            best_str = cand;\n        }\n    }\n\n    cout << best_str << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nconst int GREEDY_PASSES = 2;\nconst int SA_STEPS = 10000;\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};\n\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nint rotate(int t, int r) {\n    for (int i = 0; i < r; i++) {\n        if (t == 0) t = 1;\n        else if (t == 1) t = 2;\n        else if (t == 2) t = 3;\n        else if (t == 3) t = 0;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else if (t == 7) t = 6;\n    }\n    return t;\n}\n\npair<int, int> compute_two_longest(const vector<vector<int>>& tiles) {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\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                if (visited[i][j][d]) continue;\n                \n                int si = i, sj = j, sd = d;\n                int ci = i, cj = j, cd = d;\n                int length = 0;\n                \n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t = tiles[ci][cj];\n                    int d2 = to[t][cd];\n                    if (d2 == -1) break;\n                    \n                    ci += di[d2];\n                    cj += dj[d2];\n                    if (ci < 0 || ci >= N || cj < 0 || cj >= N) break;\n                    \n                    cd = (d2 + 2) % 4;\n                    length++;\n                    \n                    if (ci == si && cj == sj && cd == sd) {\n                        if (length > max1) {\n                            max2 = max1;\n                            max1 = length;\n                        } else if (length > max2) {\n                            max2 = length;\n                        }\n                        break;\n                    }\n                    \n                    if (length > 4 * N * N) break;\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> tiles(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    // Initialize rotations to 0\n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Greedy hill climbing phase\n    vector<pair<int, int>> all_tiles;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            all_tiles.emplace_back(i, j);\n        }\n    }\n    \n    auto [init_max1, init_max2] = compute_two_longest(tiles);\n    long long current_score = (long long)init_max1 * init_max2;\n    \n    for (int pass = 0; pass < GREEDY_PASSES; pass++) {\n        shuffle(all_tiles.begin(), all_tiles.end(), rng);\n        bool improved = false;\n        \n        for (auto [i, j] : all_tiles) {\n            int current_rot = rotations[i][j];\n            int original_type = tiles[i][j];\n            long long best_score_here = current_score;\n            int best_rot_here = current_rot;\n            \n            for (int rot = 0; rot < 4; rot++) {\n                if (rot == current_rot) continue;\n                \n                int diff = (rot - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                \n                auto [max1, max2] = compute_two_longest(tiles);\n                long long new_score = (long long)max1 * max2;\n                \n                if (new_score > best_score_here) {\n                    best_score_here = new_score;\n                    best_rot_here = rot;\n                }\n            }\n            \n            if (best_rot_here != current_rot) {\n                int diff = (best_rot_here - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                rotations[i][j] = best_rot_here;\n                current_score = best_score_here;\n                improved = true;\n            } else {\n                tiles[i][j] = original_type;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Simulated annealing phase\n    vector<vector<int>> best_rotations = rotations;\n    vector<vector<int>> best_tiles = tiles;\n    long long best_score = current_score;\n    \n    double temperature = 500.0;\n    double cooling_rate = 0.9997;\n    \n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n    \n    for (int step = 0; step < SA_STEPS; step++) {\n        int i = pos_dist(rng);\n        int j = pos_dist(rng);\n        int old_rot = rotations[i][j];\n        int new_rot = rot_dist(rng);\n        \n        if (new_rot == old_rot) continue;\n        \n        int diff = (new_rot - old_rot + 4) % 4;\n        int old_type = tiles[i][j];\n        int new_type = rotate(old_type, diff);\n        \n        tiles[i][j] = new_type;\n        rotations[i][j] = new_rot;\n        \n        auto [new_max1, new_max2] = compute_two_longest(tiles);\n        long long new_score = (long long)new_max1 * new_max2;\n        \n        if (new_score > current_score || \n            rng() % 10000 < 10000 * exp((new_score - current_score) / temperature)) {\n            current_score = new_score;\n            \n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rotations = rotations;\n                best_tiles = tiles;\n            }\n        } else {\n            tiles[i][j] = old_type;\n            rotations[i][j] = old_rot;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    // Output the best rotations found\n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += '0' + best_rotations[i][j];\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <utility>\n#include <chrono>\n#include <limits>\n\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opposite[4] = {1, 0, 3, 2};\n\nstruct State {\n    int S;\n    int edges;\n};\n\nState compute_state() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_vertices = 0;\n    int total_edges = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            if (visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int vertices = 0;\n            int edges = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                vertices++;\n                int mask = board[x][y];\n                for (int d = 0; d < 4; ++d) {\n                    if (!(mask & (1 << d))) continue;\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    int opp_mask = board[nx][ny];\n                    int opp_bit = 1 << opposite[d];\n                    if (opp_mask & opp_bit) {\n                        if (d == 1 || d == 3) {\n                            edges++;\n                        }\n                        if (!visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            total_edges += edges;\n            if (edges == vertices - 1) {\n                max_tree_vertices = max(max_tree_vertices, vertices);\n            }\n        }\n    }\n    return {max_tree_vertices, total_edges};\n}\n\nvector<char> get_valid_moves() {\n    vector<char> moves;\n    for (int d = 0; d < 4; ++d) {\n        int ni = empty_i + di[d];\n        int nj = empty_j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            moves.push_back(dir_char[d]);\n        }\n    }\n    return moves;\n}\n\nvoid apply_move(int d) {\n    int ni = empty_i + di[d];\n    int nj = empty_j + dj[d];\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nvoid undo_move(int d) {\n    apply_move(opposite[d]);\n}\n\n// One run of simulated annealing, returns (is_full_tree, sequence)\npair<bool, string> simulated_annealing_run(mt19937& gen, uniform_real_distribution<>& dis) {\n    // Reset board to initial state\n    // We assume board and empty_i, empty_j are set to initial values before calling this function.\n    // We'll save the initial state outside and restore before each run.\n\n    State current_state = compute_state();\n    int current_score = current_state.S * 1000000 + current_state.edges;\n    string current_seq = \"\";\n    bool found_full_tree = false;\n    string full_tree_seq = \"\";\n    int best_S = current_state.S;\n    string best_seq = current_seq;\n\n    double temp = 10.0;\n    double cooling = 0.9999;\n\n    for (int iter = 0; iter < T; ++iter) {\n        vector<char> moves = get_valid_moves();\n        if (moves.empty()) break;\n        char move = moves[gen() % moves.size()];\n        int d;\n        for (int i = 0; i < 4; ++i) {\n            if (dir_char[i] == move) {\n                d = i;\n                break;\n            }\n        }\n        apply_move(d);\n        State new_state = compute_state();\n        int new_score = new_state.S * 1000000 + new_state.edges;\n        double delta = new_score - current_score;\n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            current_state = new_state;\n            current_score = new_score;\n            current_seq += move;\n            if (new_state.S > best_S) {\n                best_S = new_state.S;\n                best_seq = current_seq;\n            }\n            if (new_state.S == N * N - 1) {\n                if (!found_full_tree || current_seq.length() < full_tree_seq.length()) {\n                    found_full_tree = true;\n                    full_tree_seq = current_seq;\n                }\n                // We can break early to save time for other runs\n                break;\n            }\n        } else {\n            undo_move(d);\n        }\n        temp *= cooling;\n    }\n\n    if (found_full_tree) {\n        return {true, full_tree_seq};\n    } else {\n        return {false, best_seq};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 2.8; // seconds\n\n    cin >> N >> T;\n    // Save initial board and empty position\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int init_empty_i, init_empty_j;\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            initial_board[i][j] = val;\n            if (val == 0) {\n                init_empty_i = i;\n                init_empty_j = j;\n            }\n        }\n    }\n\n    // Overall best\n    bool overall_full_tree = false;\n    string overall_best_seq = \"\";\n    int overall_best_S = 0;\n    int overall_full_tree_len = numeric_limits<int>::max();\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n\n    int run_count = 0;\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed >= time_limit) break;\n\n        // Reset board to initial state\n        board = initial_board;\n        empty_i = init_empty_i;\n        empty_j = init_empty_j;\n\n        auto [is_full, seq] = simulated_annealing_run(gen, dis);\n        run_count++;\n\n        if (is_full) {\n            if (seq.length() < overall_full_tree_len) {\n                overall_full_tree = true;\n                overall_full_tree_len = seq.length();\n                overall_best_seq = seq;\n            }\n        } else {\n            // Evaluate the sequence's final state\n            // We need to compute S for the sequence's final state\n            // Since we don't have the state, we can simulate the sequence on a copy\n            vector<vector<int>> temp_board = initial_board;\n            int temp_empty_i = init_empty_i, temp_empty_j = init_empty_j;\n            for (char c : seq) {\n                int d;\n                for (int i = 0; i < 4; ++i) {\n                    if (dir_char[i] == c) {\n                        d = i;\n                        break;\n                    }\n                }\n                int ni = temp_empty_i + di[d];\n                int nj = temp_empty_j + dj[d];\n                swap(temp_board[temp_empty_i][temp_empty_j], temp_board[ni][nj]);\n                temp_empty_i = ni;\n                temp_empty_j = nj;\n            }\n            // Save current board and empty\n            vector<vector<int>> saved_board = board;\n            int saved_empty_i = empty_i, saved_empty_j = empty_j;\n            board = temp_board;\n            empty_i = temp_empty_i;\n            empty_j = temp_empty_j;\n            State final_state = compute_state();\n            board = saved_board;\n            empty_i = saved_empty_i;\n            empty_j = saved_empty_j;\n\n            if (final_state.S > overall_best_S) {\n                overall_best_S = final_state.S;\n                overall_best_seq = seq;\n            }\n        }\n    }\n\n    if (overall_full_tree) {\n        cout << overall_best_seq << endl;\n    } else {\n        cout << overall_best_seq << endl;\n    }\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n#include <set>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\n// Global arrays\nint a[11]; // a[1]..a[10]\n\n// Compute the score for given vertical lines V and horizontal lines H\nint compute_score(const vector<int>& V, const vector<int>& H, const vector<pair<int,int>>& points) {\n    int p = V.size();\n    int q = H.size();\n    int total_cells = (p+1)*(q+1);\n    vector<int> cell_counts(total_cells, 0);\n    \n    // Create boundary arrays including cake boundaries (-10000 and 10000)\n    vector<int> V_all(p+2), H_all(q+2);\n    V_all[0] = -10000;\n    for (int i=0; i<p; ++i) V_all[i+1] = V[i];\n    V_all[p+1] = 10000;\n    H_all[0] = -10000;\n    for (int i=0; i<q; ++i) H_all[i+1] = H[i];\n    H_all[q+1] = 10000;\n    \n    // For each point, determine its cell\n    for (const auto& pt : points) {\n        int x = pt.first, y = pt.second;\n        // Find vertical interval index i such that V_all[i] < x < V_all[i+1]\n        auto it_x = upper_bound(V_all.begin(), V_all.end(), x);\n        // Since x is strictly between -10000 and 10000, it_x cannot be begin or end\n        int i = (it_x - V_all.begin()) - 1;\n        // Find horizontal interval index j\n        auto it_y = upper_bound(H_all.begin(), H_all.end(), y);\n        int j = (it_y - H_all.begin()) - 1;\n        int cell_idx = i * (q+1) + j;\n        cell_counts[cell_idx]++;\n    }\n    \n    // Compute b_d for d=1..10\n    vector<int> b(11, 0); // index 1..10\n    for (int cnt : cell_counts) {\n        if (1 <= cnt && cnt <= 10) {\n            b[cnt]++;\n        }\n    }\n    int score = 0;\n    for (int d=1; d<=10; ++d) {\n        score += min(a[d], b[d]);\n    }\n    return score;\n}\n\n// Check if a vertical line at position x is valid (does not pass through any point)\nbool is_valid_vertical(int x, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.first == x) return false;\n    }\n    return true;\n}\n\n// Check if a horizontal line at position y is valid\nbool is_valid_horizontal(int y, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.second == y) return false;\n    }\n    return true;\n}\n\n// Find a free integer coordinate for a line, starting from a candidate and exploring nearby integers\nint find_free(int cand, const vector<int>& lines, const vector<pair<int,int>>& points, bool is_vertical) {\n    for (int d=0; ; ++d) {\n        for (int sign : {0, 1, -1}) {\n            int pos = cand + sign * d;\n            if (pos < -10000 || pos > 10000) continue;\n            // Check not already used by another line\n            if (find(lines.begin(), lines.end(), pos) != lines.end()) continue;\n            // Check not on any point\n            if (is_vertical) {\n                if (!is_valid_vertical(pos, points)) continue;\n            } else {\n                if (!is_valid_horizontal(pos, points)) continue;\n            }\n            return pos;\n        }\n    }\n}\n\n// Flexible simulated annealing that allows changing orientation and adding/removing lines\npair<vector<int>, vector<int>> sa_optimize_flexible(int initial_p, int initial_q, const vector<pair<int,int>>& points, int max_lines, int iterations=1500) {\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    uniform_int_distribution<int> dist_move(0, 3); // 0: move line, 1: change orientation, 2: add line, 3: remove line\n    uniform_int_distribution<int> dist_offset(-100, 100);\n    \n    int N = points.size();\n    \n    // Initialize vertical lines\n    vector<int> V;\n    for (int i=1; i<=initial_p; ++i) {\n        // Simple initialization: evenly spaced from -10000 to 10000, avoiding points\n        int cand = -10000 + i * 20000 / (initial_p+1);\n        int pos = find_free(cand, V, points, true);\n        V.push_back(pos);\n    }\n    sort(V.begin(), V.end());\n    \n    // Initialize horizontal lines\n    vector<int> H;\n    for (int i=1; i<=initial_q; ++i) {\n        int cand = -10000 + i * 20000 / (initial_q+1);\n        int pos = find_free(cand, H, points, false);\n        H.push_back(pos);\n    }\n    sort(H.begin(), H.end());\n    \n    int cur_score = compute_score(V, H, points);\n    vector<int> bestV = V, bestH = H;\n    int best_score = cur_score;\n    \n    double temp = 1000.0;\n    double cooling = 0.999;\n    \n    for (int iter=0; iter<iterations; ++iter) {\n        int total_lines = V.size() + H.size();\n        int move_type = dist_move(rng);\n        bool vertical = (rng()%2 == 0); // for orientation change, which orientation to target\n        \n        if (move_type == 0 && total_lines > 0) {\n            // Move a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            \n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            int new_pos = cur_pos + dist_offset(rng);\n            if (new_pos < -10000 || new_pos > 10000) continue;\n            if (new_pos == cur_pos) continue;\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                newV[idx] = new_pos;\n                if (!is_valid_vertical(new_pos, points)) continue;\n                sort(newV.begin(), newV.end());\n                if (adjacent_find(newV.begin(), newV.end()) != newV.end()) continue;\n            } else {\n                newH[idx] = new_pos;\n                if (!is_valid_horizontal(new_pos, points)) continue;\n                sort(newH.begin(), newH.end());\n                if (adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 1 && total_lines > 0) {\n            // Change orientation of a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                // Change from vertical to horizontal\n                newV.erase(newV.begin() + idx);\n                // Check if cur_pos is valid as horizontal\n                if (!is_valid_horizontal(cur_pos, points)) continue;\n                // Check not already in H\n                if (find(newH.begin(), newH.end(), cur_pos) != newH.end()) continue;\n                newH.push_back(cur_pos);\n                sort(newH.begin(), newH.end());\n            } else {\n                // Change from horizontal to vertical\n                newH.erase(newH.begin() + idx);\n                if (!is_valid_vertical(cur_pos, points)) continue;\n                if (find(newV.begin(), newV.end(), cur_pos) != newV.end()) continue;\n                newV.push_back(cur_pos);\n                sort(newV.begin(), newV.end());\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 2 && total_lines < max_lines) {\n            // Add a line (randomly vertical or horizontal)\n            bool add_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            // Generate a candidate position\n            int cand = -10000 + rng()%20001;\n            if (add_vertical) {\n                int pos = find_free(cand, newV, points, true);\n                newV.push_back(pos);\n                sort(newV.begin(), newV.end());\n            } else {\n                int pos = find_free(cand, newH, points, false);\n                newH.push_back(pos);\n                sort(newH.begin(), newH.end());\n            }\n            // Check for duplicates\n            if (adjacent_find(newV.begin(), newV.end()) != newV.end() ||\n                adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 3 && total_lines > 1) {\n            // Remove a line\n            bool remove_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (remove_vertical && !newV.empty()) {\n                int idx = rng() % newV.size();\n                newV.erase(newV.begin() + idx);\n            } else if (!newH.empty()) {\n                int idx = rng() % newH.size();\n                newH.erase(newH.begin() + idx);\n            } else {\n                continue; // cannot remove\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        }\n        temp *= cooling;\n    }\n    return {bestV, bestH};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, K;\n    cin >> N >> K;\n    for (int d=1; d<=10; ++d) cin >> a[d];\n    \n    vector<pair<int,int>> points(N);\n    for (int i=0; i<N; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Try a few initial splits and run flexible SA on each\n    vector<pair<int,int>> initial_splits = {{0,0}, {25,25}, {50,0}, {0,50}, {50,50}, {75,25}, {25,75}};\n    int best_total_score = -1;\n    vector<int> bestV, bestH;\n    \n    for (auto [p,q] : initial_splits) {\n        if (p+q > K) continue;\n        auto [V, H] = sa_optimize_flexible(p, q, points, K, 1500);\n        int score = compute_score(V, H, points);\n        if (score > best_total_score) {\n            best_total_score = score;\n            bestV = V;\n            bestH = H;\n        }\n    }\n    \n    // Output\n    cout << bestV.size() + bestH.size() << '\\n';\n    // Vertical lines\n    for (int x : bestV) {\n        cout << x << \" \" << -10000 << \" \" << x << \" \" << 10000 << '\\n';\n    }\n    // Horizontal lines\n    for (int y : bestH) {\n        cout << -10000 << \" \" << y << \" \" << 10000 << \" \" << y << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <ctime>\n#include <array>\n#include <cstring>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\n// Encode a unit segment into a 32-bit integer (canonical order)\nuint32_t encode_seg(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    // N <= 61, so 6 bits per coordinate are enough\n    return (x1 << 18) | (y1 << 12) | (x2 << 6) | y2;\n}\n\n// Check condition 2 for axis-aligned rectangle: no other dots on the perimeter (excluding corners)\nbool check_perimeter_axis(int x1, int y1, int x2, int y2, const vector<vector<bool>>& dot_grid) {\n    // vertical sides\n    for (int y = y1 + 1; y < y2; ++y) {\n        if (dot_grid[x1][y] || dot_grid[x2][y])\n            return false;\n    }\n    // horizontal sides\n    for (int x = x1 + 1; x < x2; ++x) {\n        if (dot_grid[x][y1] || dot_grid[x][y2])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for axis-aligned rectangle: no overlapping segments\nbool check_used_segments_axis(int x1, int y1, int x2, int y2, const unordered_set<uint32_t>& used_segments) {\n    // Check each unit segment along each edge\n    // Left vertical side\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x1, y, x1, y + 1)))\n            return false;\n    }\n    // Right vertical side\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x2, y, x2, y + 1)))\n            return false;\n    }\n    // Bottom horizontal side\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y1, x + 1, y1)))\n            return false;\n    }\n    // Top horizontal side\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y2, x + 1, y2)))\n            return false;\n    }\n    return true;\n}\n\n// Check condition 2 for 45-degree rectangle\nbool check_perimeter_45(int x, int y, int a, int b, const vector<vector<bool>>& dot_grid) {\n    // side P->C: (x,y) to (x+a, y+a)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + i][y + i])\n            return false;\n    }\n    // side C->Q: (x+a, y+a) to (x+a+b, y+a-b)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + a + i][y + a - i])\n            return false;\n    }\n    // side Q->D: (x+a+b, y+a-b) to (x+b, y-b)\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + a + b - i][y + a - b - i])\n            return false;\n    }\n    // side D->P: (x+b, y-b) to (x,y)\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + b - i][y - b + i])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for 45-degree rectangle\nbool check_used_segments_45(int x, int y, int a, int b, const unordered_set<uint32_t>& used_segments) {\n    // side P->C\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + i, y + i, x + i + 1, y + i + 1)))\n            return false;\n    }\n    // side C->Q\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + a + i, y + a - i, x + a + i + 1, y + a - i - 1)))\n            return false;\n    }\n    // side Q->D\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + a + b - i, y + a - b - i, x + a + b - i - 1, y + a - b - i - 1)))\n            return false;\n    }\n    // side D->P\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + b - i, y - b + i, x + b - i - 1, y - b + i + 1)))\n            return false;\n    }\n    return true;\n}\n\n// Add all unit segments of a rectangle to used_segments\nvoid add_rectangle_segments(const array<int, 8>& op, unordered_set<uint32_t>& used_segments) {\n    for (int k = 0; k < 4; ++k) {\n        int k2 = (k + 1) % 4;\n        int x1 = op[2*k], y1 = op[2*k+1];\n        int x2 = op[2*k2], y2 = op[2*k2+1];\n        \n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        int sx = (dx == 0) ? 0 : (dx > 0 ? 1 : -1);\n        int sy = (dy == 0) ? 0 : (dy > 0 ? 1 : -1);\n        int num_steps = max(abs(dx), abs(dy));\n        \n        for (int step = 0; step < num_steps; ++step) {\n            int cur_x = x1 + step * sx;\n            int cur_y = y1 + step * sy;\n            int next_x = cur_x + sx;\n            int next_y = cur_y + sy;\n            used_segments.insert(encode_seg(cur_x, cur_y, next_x, next_y));\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    vector<Point> initial(M);\n    vector<vector<bool>> dot_grid(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        cin >> initial[i].x >> initial[i].y;\n        dot_grid[initial[i].x][initial[i].y] = true;\n    }\n\n    vector<Point> dots = initial;\n    unordered_set<uint32_t> used_segments;\n    vector<array<int, 8>> operations;\n\n    int c = (N - 1) / 2;\n    clock_t start_time = clock();\n\n    while (true) {\n        // Check time limit (4.5 seconds margin)\n        if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.5)\n            break;\n\n        int best_weight = -1;\n        array<int, 8> best_op;\n        bool found = false;\n\n        int Mcurr = dots.size();\n        for (int i = 0; i < Mcurr; ++i) {\n            for (int j = i + 1; j < Mcurr; ++j) {\n                Point A = dots[i], B = dots[j];\n\n                // ---------- Axis-aligned rectangle ----------\n                int x1 = min(A.x, B.x), x2 = max(A.x, B.x);\n                int y1 = min(A.y, B.y), y2 = max(A.y, B.y);\n                if (x1 < x2 && y1 < y2) {\n                    bool c1 = dot_grid[x1][y1];\n                    bool c2 = dot_grid[x1][y2];\n                    bool c3 = dot_grid[x2][y1];\n                    bool c4 = dot_grid[x2][y2];\n                    int cnt = c1 + c2 + c3 + c4;\n                    if (cnt == 3) {\n                        Point D;\n                        if (!c1) D = {x1, y1};\n                        else if (!c2) D = {x1, y2};\n                        else if (!c3) D = {x2, y1};\n                        else D = {x2, y2};\n\n                        if (check_perimeter_axis(x1, y1, x2, y2, dot_grid) &&\n                            check_used_segments_axis(x1, y1, x2, y2, used_segments)) {\n                            int w = (D.x - c) * (D.x - c) + (D.y - c) * (D.y - c) + 1;\n                            if (w > best_weight) {\n                                best_weight = w;\n                                // Build operation in cyclic order\n                                array<Point, 4> corners;\n                                corners[0] = {x1, y1};\n                                corners[1] = {x1, y2};\n                                corners[2] = {x2, y2};\n                                corners[3] = {x2, y1};\n                                \n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                            }\n                        }\n                    }\n                }\n\n                // ---------- 45-degree rectangle ----------\n                for (int order = 0; order < 2; ++order) {\n                    Point start = (order == 0) ? A : B;\n                    Point opposite = (order == 0) ? B : A;\n                    int dx = opposite.x - start.x;\n                    int dy = opposite.y - start.y;\n                    int sum_diff = dx + dy;\n                    int sub_diff = dx - dy;\n                    if (sum_diff % 2 != 0 || sub_diff % 2 != 0) continue;\n                    int a = sum_diff / 2;\n                    int b = sub_diff / 2;\n                    if (a <= 0 || b <= 0) continue;\n\n                    Point C = {start.x + a, start.y + a};\n                    Point D = {start.x + b, start.y - b};\n                    if (C.x < 0 || C.x >= N || C.y < 0 || C.y >= N ||\n                        D.x < 0 || D.x >= N || D.y < 0 || D.y >= N) continue;\n\n                    bool cC = dot_grid[C.x][C.y];\n                    bool cD = dot_grid[D.x][D.y];\n                    if (cC + cD != 1) continue;\n\n                    Point missing = cC ? D : C;\n                    array<Point, 4> corners;\n                    corners[0] = start;\n                    corners[1] = C;\n                    corners[2] = opposite;\n                    corners[3] = D;\n\n                    if (check_perimeter_45(start.x, start.y, a, b, dot_grid) &&\n                        check_used_segments_45(start.x, start.y, a, b, used_segments)) {\n                        int w = (missing.x - c) * (missing.x - c) + (missing.y - c) * (missing.y - c) + 1;\n                        if (w > best_weight) {\n                            best_weight = w;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (!found) break;\n\n        // Perform the operation\n        operations.push_back(best_op);\n        Point new_dot = {best_op[0], best_op[1]};\n        dot_grid[new_dot.x][new_dot.y] = true;\n        dots.push_back(new_dot);\n\n        // Add all unit segments of the rectangle to used_segments\n        add_rectangle_segments(best_op, used_segments);\n    }\n\n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            cout << op[i];\n            if (i < 7) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int SIZE = 10;\nusing Grid = vector<vector<int>>; // 1\u2011indexed, 11x11\n\n// Apply a tilt in the given direction and return the new grid.\nGrid apply_tilt(const Grid& grid, char dir) {\n    Grid new_grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n    if (dir == 'L') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][i + 1] = flavors[i];\n        }\n    } else if (dir == 'R') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][SIZE - k + 1 + i] = flavors[i];\n        }\n    } else if (dir == 'F') { // forward = up\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[i + 1][c] = flavors[i];\n        }\n    } else { // 'B' \u2013 backward = down\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[SIZE - k + 1 + i][c] = flavors[i];\n        }\n    }\n    return new_grid;\n}\n\n// Evaluate a grid using a combined heuristic: connectivity + compactness.\ndouble evaluate_state(const Grid& grid) {\n    bool visited[SIZE + 1][SIZE + 1] = {false};\n    long long connectivity = 0;\n    const int dr[] = {1, -1, 0, 0};\n    const int dc[] = {0, 0, 1, -1};\n\n    // Compute connectivity (sum of squares of component sizes).\n    for (int r = 1; r <= SIZE; ++r) {\n        for (int c = 1; c <= SIZE; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                vector<pair<int, int>> queue = {{r, c}};\n                visited[r][c] = true;\n                int idx = 0;\n                while (idx < queue.size()) {\n                    auto [cr, cc] = queue[idx++];\n                    ++size;\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = cr + dr[d];\n                        int nc = cc + dc[d];\n                        if (nr >= 1 && nr <= SIZE && nc >= 1 && nc <= SIZE &&\n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            queue.push_back({nr, nc});\n                        }\n                    }\n                }\n                connectivity += (long long)size * size;\n            }\n        }\n    }\n\n    // Compute compactness (density of each flavor's bounding box).\n    double compactness = 0.0;\n    for (int flavor = 1; flavor <= 3; ++flavor) {\n        int min_r = SIZE + 1, max_r = 0, min_c = SIZE + 1, max_c = 0;\n        int count = 0;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == flavor) {\n                    ++count;\n                    min_r = min(min_r, r);\n                    max_r = max(max_r, r);\n                    min_c = min(min_c, c);\n                    max_c = max(max_c, c);\n                }\n            }\n        }\n        if (count > 0) {\n            int area = (max_r - min_r + 1) * (max_c - min_c + 1);\n            compactness += (double)count / area;\n        }\n    }\n\n    const double beta = 1000.0; // weight for compactness\n    return connectivity + beta * compactness;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) cin >> f[i];\n\n    Grid grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n\n    for (int t = 1; t <= 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Locate the p\u2011th empty cell (front\u2011to\u2011back, left\u2011to\u2011right).\n        int count = 0;\n        int placed_r = -1, placed_c = -1;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == 0) {\n                    ++count;\n                    if (count == p) {\n                        placed_r = r;\n                        placed_c = c;\n                        break;\n                    }\n                }\n            }\n            if (placed_r != -1) break;\n        }\n        grid[placed_r][placed_c] = f[t];\n\n        if (t == 100) break; // last candy \u2013 no tilt needed\n\n        // One\u2011step lookahead with combined heuristic.\n        char best_dir = 'F';\n        double best_expected = -1.0;\n\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid grid1 = apply_tilt(grid, dir);\n\n            // Collect empty cells in grid1.\n            vector<pair<int, int>> empties;\n            for (int r = 1; r <= SIZE; ++r)\n                for (int c = 1; c <= SIZE; ++c)\n                    if (grid1[r][c] == 0) empties.emplace_back(r, c);\n\n            double total = 0.0;\n            for (auto [r, c] : empties) {\n                Grid grid2 = grid1;\n                grid2[r][c] = f[t + 1];\n\n                double best_next = 0.0;\n                for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                    Grid grid3 = apply_tilt(grid2, next_dir);\n                    double sc = evaluate_state(grid3);\n                    if (sc > best_next) best_next = sc;\n                }\n                total += best_next;\n            }\n            double expected = total / empties.size();\n            if (expected > best_expected) {\n                best_expected = expected;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        grid = apply_tilt(grid, best_dir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Precompute expected sorted degree lists for each possible a (1..N)\n    vector<vector<double>> exp_sorted(N + 1);\n    for (int a = 1; a <= N; ++a) {\n        vector<double> degs;\n        if (a == N) {\n            double mu = (N - 1) * (1 - epsilon);\n            degs.assign(N, mu);\n        } else {\n            double muA = (a - 1) * (1 - epsilon) + (N - a) * epsilon;\n            double muB = (N - a - 1) * (1 - epsilon) + a * epsilon;\n            for (int i = 0; i < a; ++i) degs.push_back(muA);\n            for (int i = 0; i < N - a; ++i) degs.push_back(muB);\n            sort(degs.begin(), degs.end());\n        }\n        exp_sorted[a] = degs;\n    }\n\n    // Precompute L1 distances between any two a\n    vector<vector<double>> dist(N + 1, vector<double>(N + 1, 0.0));\n    for (int a1 = 1; a1 <= N; ++a1) {\n        for (int a2 = a1 + 1; a2 <= N; ++a2) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(exp_sorted[a1][i] - exp_sorted[a2][i]);\n            }\n            dist[a1][a2] = d;\n            dist[a2][a1] = d;\n        }\n    }\n\n    // Greedy selection of M a values\n    vector<int> selected;\n    selected.push_back(50);  // start with middle to cover the range\n    vector<bool> used(N + 1, false);\n    used[50] = true;\n    for (int step = 1; step < M; ++step) {\n        int best_a = -1;\n        double best_min_dist = -1.0;\n        for (int a = 1; a <= N; ++a) {\n            if (used[a]) continue;\n            double min_dist = 1e18;\n            for (int b : selected) {\n                min_dist = min(min_dist, dist[a][b]);\n            }\n            if (min_dist > best_min_dist) {\n                best_min_dist = min_dist;\n                best_a = a;\n            }\n        }\n        selected.push_back(best_a);\n        used[best_a] = true;\n    }\n\n    // Sort selected a in increasing order for output order\n    sort(selected.begin(), selected.end());\n\n    // Create mapping from a to index\n    vector<int> index_of_a(N + 1, -1);\n    for (int i = 0; i < M; ++i) {\n        index_of_a[selected[i]] = i;\n    }\n\n    // Output N\n    cout << N << endl;\n\n    // Output M graphs\n    for (int a : selected) {\n        string graph;\n        graph.resize(N * (N - 1) / 2, '0');\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool same_clique = false;\n                if (a == N) {\n                    same_clique = true;  // complete graph\n                } else {\n                    if (i < a && j < a) same_clique = true;\n                    else if (i >= a && j >= a) same_clique = true;\n                }\n                if (same_clique) graph[pos] = '1';\n                pos++;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        // Compute degrees\n        vector<int> deg(N, 0);\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[pos] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                pos++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n\n        // Find the a with minimum L1 distance\n        int best_idx = -1;\n        double best_dist = 1e18;\n        for (int a : selected) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                d += abs(deg[i] - exp_sorted[a][i]);\n            }\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = index_of_a[a];\n            }\n        }\n\n        cout << best_idx << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll INF = 1e18;\nconst int MAXN = 1000;\n\nint N, M, D, K;\nvector<vector<pair<int, int>>> adj; // neighbor, edge index\nvector<int> u, v, w;\nvector<double> mid_x, mid_y;\nvector<ll> cnt;\nvector<vector<char>> removed; // removed[day][edge]\nvector<int> day_assign;\nvector<ll> day_sum; // sum of cnt per day\nvector<int> day_cnt;\nvector<double> sum_mid_x, sum_mid_y;\n\nint vis[MAXN];\nint cur_mark = 0;\n\nbool isConnected(int d) {\n    cur_mark++;\n    queue<int> q;\n    q.push(0);\n    vis[0] = cur_mark;\n    int count = 1;\n    while (!q.empty()) {\n        int node = q.front(); q.pop();\n        for (auto [nbr, eidx] : adj[node]) {\n            if (removed[d][eidx]) continue;\n            if (vis[nbr] != cur_mark) {\n                vis[nbr] = cur_mark;\n                q.push(nbr);\n                count++;\n            }\n        }\n    }\n    return count == N;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> D >> K;\n    u.resize(M); v.resize(M); w.resize(M);\n    adj.resize(N);\n    vector<vector<int>> edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        edge_idx[u[i]][v[i]] = i;\n        edge_idx[v[i]][u[i]] = i;\n        adj[u[i]].emplace_back(v[i], i);\n        adj[v[i]].emplace_back(u[i], i);\n    }\n\n    vector<int> coord_x(N), coord_y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coord_x[i] >> coord_y[i];\n    }\n\n    mid_x.resize(M); mid_y.resize(M);\n    for (int i = 0; i < M; ++i) {\n        mid_x[i] = (coord_x[u[i]] + coord_x[v[i]]) * 0.5;\n        mid_y[i] = (coord_y[u[i]] + coord_y[v[i]]) * 0.5;\n    }\n\n    // All-pairs shortest paths and parent selection\n    vector<vector<ll>> dist(N, vector<ll>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        dist[s][s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.emplace(0, s);\n        while (!pq.empty()) {\n            auto [d, node] = pq.top(); pq.pop();\n            if (d != dist[s][node]) continue;\n            for (auto [nbr, weight] : adj[node]) {\n                ll nd = d + weight;\n                if (nd < dist[s][nbr]) {\n                    dist[s][nbr] = nd;\n                    parent[s][nbr] = node;\n                    pq.emplace(nd, nbr);\n                } else if (nd == dist[s][nbr] && node < parent[s][nbr]) {\n                    parent[s][nbr] = node;\n                }\n            }\n        }\n    }\n\n    // Criticality (cnt) for each edge\n    cnt.assign(M, 0);\n    for (int s = 0; s < N; ++s) {\n        vector<vector<int>> tree(N);\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            tree[p].push_back(v);\n            tree[v].push_back(p);\n        }\n        vector<int> order;\n        vector<bool> visited(N, false);\n        stack<int> stk;\n        stk.push(s);\n        visited[s] = true;\n        while (!stk.empty()) {\n            int node = stk.top(); stk.pop();\n            order.push_back(node);\n            for (int nbr : tree[node]) {\n                if (!visited[nbr]) {\n                    visited[nbr] = true;\n                    stk.push(nbr);\n                }\n            }\n        }\n        vector<int> sz(N, 0);\n        for (int i = order.size()-1; i >= 0; --i) {\n            int node = order[i];\n            sz[node] = 1;\n            for (int nbr : tree[node]) {\n                if (nbr == s) continue;\n                if (parent[s][nbr] == node) {\n                    sz[node] += sz[nbr];\n                }\n            }\n        }\n        for (int v = 0; v < N; ++v) {\n            if (v == s) continue;\n            int p = parent[s][v];\n            int eidx = edge_idx[p][v];\n            cnt[eidx] += sz[v];\n        }\n    }\n\n    // Initialize day structures\n    day_assign.assign(M, -1);\n    day_sum.assign(D, 0);\n    day_cnt.assign(D, 0);\n    sum_mid_x.assign(D, 0.0);\n    sum_mid_y.assign(D, 0.0);\n    removed.assign(D, vector<char>(M, 0));\n\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n    sort(order_edges.begin(), order_edges.end(),\n         [&](int a, int b) { return cnt[a] > cnt[b]; });\n\n    for (int e : order_edges) {\n        // Collect all days with free slots\n        vector<int> candidates;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K) {\n                candidates.push_back(d);\n            }\n        }\n\n        // Among candidates, find those that keep connectivity\n        vector<int> connected_days;\n        for (int d : candidates) {\n            removed[d][e] = 1;\n            if (isConnected(d)) {\n                connected_days.push_back(d);\n            }\n            removed[d][e] = 0;\n        }\n\n        int best_day = -1;\n        double best_dist2 = -1.0;\n\n        if (!connected_days.empty()) {\n            // Among connected days, choose the one with smallest day_sum, then largest distance\n            ll min_sum = INF;\n            for (int d : connected_days) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                }\n            }\n            vector<int> best_candidates;\n            for (int d : connected_days) {\n                if (day_sum[d] == min_sum) {\n                    best_candidates.push_back(d);\n                }\n            }\n            if (best_candidates.size() == 1) {\n                best_day = best_candidates[0];\n            } else {\n                // tie-break by distance\n                for (int d : best_candidates) {\n                    double dist2;\n                    if (day_cnt[d] == 0) {\n                        dist2 = 1e18;\n                    } else {\n                        double avg_x = sum_mid_x[d] / day_cnt[d];\n                        double avg_y = sum_mid_y[d] / day_cnt[d];\n                        double dx = mid_x[e] - avg_x;\n                        double dy = mid_y[e] - avg_y;\n                        dist2 = dx*dx + dy*dy;\n                    }\n                    if (best_day == -1 || dist2 > best_dist2) {\n                        best_dist2 = dist2;\n                        best_day = d;\n                    }\n                }\n            }\n        } else {\n            // No day keeps connectivity; fallback to day with smallest day_sum\n            ll min_sum = INF;\n            for (int d : candidates) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                    best_day = d;\n                }\n            }\n        }\n\n        // Assign edge to best_day\n        day_assign[e] = best_day;\n        day_sum[best_day] += cnt[e];\n        day_cnt[best_day]++;\n        sum_mid_x[best_day] += mid_x[e];\n        sum_mid_y[best_day] += mid_y[e];\n        removed[best_day][e] = 1;\n    }\n\n    // Output\n    for (int i = 0; i < M; ++i) {\n        cout << day_assign[i] + 1;\n        if (i < M - 1) cout << ' ';\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;  // global, needed for canonical shape normalization\n\n// 24 rotation matrices\nvector<array<array<int, 3>, 3>> rotations;\n\n// generate all rotations (determinant = 1)\nvoid generate_rotations() {\n    vector<int> axes = {0, 1, 2};\n    do {\n        // compute sign of permutation (even -> +1, odd -> -1)\n        int inversions = 0;\n        for (int i = 0; i < 3; ++i)\n            for (int j = i + 1; j < 3; ++j)\n                if (axes[i] > axes[j]) ++inversions;\n        int perm_sign = (inversions % 2 == 0) ? 1 : -1;\n\n        for (int s0 : {-1, 1}) {\n            for (int s1 : {-1, 1}) {\n                // s2 determined by determinant = s0 * s1 * s2 * perm_sign = 1\n                int s2 = (perm_sign * s0 * s1 == 1) ? 1 : -1;\n                array<array<int, 3>, 3> mat{};\n                mat[0][axes[0]] = s0;\n                mat[1][axes[1]] = s1;\n                mat[2][axes[2]] = s2;\n                rotations.push_back(mat);\n            }\n        }\n    } while (next_permutation(axes.begin(), axes.end()));\n}\n\nusing Point = array<int, 3>;\n\n// canonical shape of a block: normalized to min (0,0,0) and all rotations considered\nvector<Point> canonical_shape(const vector<Point>& cubes) {\n    // find current min\n    Point min_point = {D, D, D};\n    for (auto& p : cubes) {\n        for (int i = 0; i < 3; ++i) min_point[i] = min(min_point[i], p[i]);\n    }\n    vector<Point> rel;\n    for (auto& p : cubes) {\n        rel.push_back({p[0] - min_point[0], p[1] - min_point[1], p[2] - min_point[2]});\n    }\n\n    vector<Point> best = rel;\n    sort(best.begin(), best.end());\n\n    // try all rotations\n    for (const auto& rot : rotations) {\n        vector<Point> rotated;\n        for (auto& p : rel) {\n            Point np;\n            for (int i = 0; i < 3; ++i) {\n                np[i] = 0;\n                for (int j = 0; j < 3; ++j) np[i] += rot[i][j] * p[j];\n            }\n            rotated.push_back(np);\n        }\n        // normalize after rotation\n        Point min_rot = {D, D, D};\n        for (auto& p : rotated) {\n            for (int i = 0; i < 3; ++i) min_rot[i] = min(min_rot[i], p[i]);\n        }\n        vector<Point> norm;\n        for (auto& p : rotated) {\n            norm.push_back({p[0] - min_rot[0], p[1] - min_rot[1], p[2] - min_rot[2]});\n        }\n        sort(norm.begin(), norm.end());\n        if (norm < best) best = norm;\n    }\n    return best;\n}\n\n// a connected component (block)\nstruct Component {\n    vector<Point> cubes;\n    int volume;\n    vector<Point> canon;  // canonical shape\n    int block_id;\n    bool used;  // for matching\n};\n\n// generate minimal object from silhouette pair\nvector<Point> generate_object(const vector<string>& f, const vector<string>& r) {\n    vector<Point> cubes;\n    for (int z = 0; z < D; ++z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (f[z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (r[z][y] == '1') Y.push_back(y);\n        // guaranteed non-empty per problem statement\n        if (X.size() <= Y.size()) {\n            // match each x to a distinct y\n            for (size_t i = 0; i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining y\n            for (size_t i = X.size(); i < Y.size(); ++i) {\n                cubes.push_back({X[0], Y[i], z});\n            }\n        } else {\n            // match each y to a distinct x\n            for (size_t i = 0; i < Y.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            // remaining x\n            for (size_t i = Y.size(); i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[0], z});\n            }\n        }\n    }\n    return cubes;\n}\n\n// extract connected components from a set of cubes\nvector<Component> get_components(const vector<Point>& cubes) {\n    // boolean grid\n    vector<vector<vector<bool>>> grid(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (auto& p : cubes) grid[p[0]][p[1]][p[2]] = true;\n\n    vector<bool> visited(D * D * D, false);\n    vector<Component> comps;\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    for (auto& p : cubes) {\n        int idx = p[0] * D * D + p[1] * D + p[2];\n        if (!visited[idx]) {\n            // BFS\n            vector<Point> comp_cubes;\n            queue<Point> q;\n            q.push(p);\n            visited[idx] = true;\n            while (!q.empty()) {\n                Point cur = q.front(); q.pop();\n                comp_cubes.push_back(cur);\n                for (int d = 0; d < 6; ++d) {\n                    int nx = cur[0] + dx[d], ny = cur[1] + dy[d], nz = cur[2] + dz[d];\n                    if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && grid[nx][ny][nz]) {\n                        int nidx = nx * D * D + ny * D + nz;\n                        if (!visited[nidx]) {\n                            visited[nidx] = true;\n                            q.push({nx, ny, nz});\n                        }\n                    }\n                }\n            }\n            Component comp;\n            comp.cubes = comp_cubes;\n            comp.volume = comp_cubes.size();\n            comp.canon = canonical_shape(comp_cubes);\n            comp.used = false;\n            comps.push_back(comp);\n        }\n    }\n    return comps;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D;\n\n    // read silhouettes\n    vector<string> f0(D), r0(D), f1(D), r1(D);\n    for (int i = 0; i < D; ++i) cin >> f0[i];\n    for (int i = 0; i < D; ++i) cin >> r0[i];\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n\n    generate_rotations();\n\n    // minimal objects\n    vector<Point> obj0_cubes = generate_object(f0, r0);\n    vector<Point> obj1_cubes = generate_object(f1, r1);\n\n    // components for each object\n    vector<Component> comp0 = get_components(obj0_cubes);\n    vector<Component> comp1 = get_components(obj1_cubes);\n\n    // sort by volume (largest first) to prioritize matching large blocks\n    sort(comp0.begin(), comp0.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n    sort(comp1.begin(), comp1.end(),\n         [](const Component& a, const Component& b) { return a.volume > b.volume; });\n\n    // map from canonical shape to list of indices in comp1\n    map<vector<Point>, vector<int>> shape_to_idx1;\n    for (size_t i = 0; i < comp1.size(); ++i) {\n        shape_to_idx1[comp1[i].canon].push_back(i);\n    }\n\n    int block_id = 1;\n    // match components with same shape\n    for (size_t i = 0; i < comp0.size(); ++i) {\n        auto it = shape_to_idx1.find(comp0[i].canon);\n        if (it != shape_to_idx1.end() && !it->second.empty()) {\n            int j = it->second.back();\n            it->second.pop_back();\n            comp0[i].block_id = block_id;\n            comp1[j].block_id = block_id;\n            comp0[i].used = true;\n            comp1[j].used = true;\n            ++block_id;\n        }\n    }\n\n    // assign ids to unmatched components\n    for (auto& comp : comp0) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    for (auto& comp : comp1) {\n        if (!comp.used) comp.block_id = block_id++;\n    }\n    int n = block_id - 1;\n\n    // build output arrays\n    vector<int> b0(D * D * D, 0), b1(D * D * D, 0);\n    for (auto& comp : comp0) {\n        for (auto& p : comp.cubes) {\n            b0[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n    for (auto& comp : comp1) {\n        for (auto& p : comp.cubes) {\n            b1[p[0] * D * D + p[1] * D + p[2]] = comp.block_id;\n        }\n    }\n\n    // output\n    cout << n << '\\n';\n    for (size_t i = 0; i < b0.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b0[i];\n    }\n    cout << '\\n';\n    for (size_t i = 0; i < b1.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <map>\n#include <set>\n#include <random>\n#include <climits>\n#include <cassert>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nconst double EPS = 1e-9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    for (int i = 0; i < N; ++i) distV[i][i] = 0;\n\n    vector<tuple<int, int, long long>> edges(M);\n    map<pair<int, int>, int> edgeIndex;\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[j] = {u, v, w};\n        if (u > v) swap(u, v);\n        edgeIndex[{u, v}] = j;\n        distV[u][v] = min(distV[u][v], w);\n        distV[v][u] = min(distV[v][u], w);\n    }\n\n    vector<vector<int>> next(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i != j && distV[i][j] < INF) {\n                next[i][j] = j;\n            }\n        }\n    }\n\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][k] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[k][j] == INF) continue;\n                if (distV[i][j] > distV[i][k] + distV[k][j]) {\n                    distV[i][j] = distV[i][k] + distV[k][j];\n                    next[i][j] = next[i][k];\n                }\n            }\n        }\n    }\n\n    vector<double> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    vector<vector<double>> distVtoR(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            distVtoR[i][k] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    vector<vector<int>> candidateVertices(K);\n    for (int k = 0; k < K; ++k) {\n        vector<pair<double, int>> distances;\n        for (int i = 0; i < N; ++i) {\n            distances.push_back({distVtoR[i][k], i});\n        }\n        sort(distances.begin(), distances.end());\n        for (int t = 0; t < min(10, N); ++t) {\n            candidateVertices[k].push_back(distances[t].second);\n        }\n    }\n\n    vector<multiset<double>> distSets(N);\n    vector<int> assign(K);\n    vector<int> P(N, 0);\n    long long sumSq = 0;\n\n    for (int k = 0; k < K; ++k) {\n        int best = 0;\n        for (int i = 1; i < N; ++i) {\n            if (distVtoR[i][k] < distVtoR[best][k] - EPS) {\n                best = i;\n            }\n        }\n        assign[k] = best;\n        distSets[best].insert(distVtoR[best][k]);  // Fixed: use best instead of i\n    }\n\n    for (int i = 0; i < N; ++i) {\n        if (!distSets[i].empty()) {\n            double maxDist = *distSets[i].rbegin();\n            P[i] = (int)ceil(maxDist);\n            if (P[i] > 5000) P[i] = 5000;\n        } else {\n            P[i] = 0;\n        }\n        sumSq += (long long)P[i] * P[i];\n    }\n\n    auto computeSteinerCost = [&](const vector<int>& T) -> long long {\n        int n = T.size();\n        if (n <= 1) return 0;\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        minDist[0] = 0;\n        long long total = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            if (u == -1) break;\n            inMST[u] = true;\n            total += minDist[u];\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[T[u]][T[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                    }\n                }\n            }\n        }\n        return total;\n    };\n\n    vector<int> currentT;\n    currentT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            currentT.push_back(i);\n        }\n    }\n    long long currentSteinerCost = computeSteinerCost(currentT);\n    long long currentCost = sumSq + currentSteinerCost;\n\n    int maxIter = 5000;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> residentDist(0, K-1);\n\n    for (int iter = 0; iter < maxIter; ++iter) {\n        int k = residentDist(gen);\n        int i = assign[k];\n        bool improved = false;\n\n        for (int j : candidateVertices[k]) {\n            if (j == i) continue;\n\n            int oldP_i = P[i], oldP_j = P[j];\n            double d_ik = distVtoR[i][k];\n            double d_jk = distVtoR[j][k];\n\n            distSets[i].erase(distSets[i].find(d_ik));\n            distSets[j].insert(d_jk);\n\n            int newP_i = 0, newP_j = 0;\n            if (!distSets[i].empty()) {\n                double maxDist = *distSets[i].rbegin();\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!distSets[j].empty()) {\n                double maxDist = *distSets[j].rbegin();\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n\n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n\n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n\n            long long newCost;\n            if (newT == currentT) {\n                newCost = newSumSq + currentSteinerCost;\n            } else {\n                long long newSteinerCost = computeSteinerCost(newT);\n                newCost = newSumSq + newSteinerCost;\n            }\n\n            if (newCost < currentCost - EPS) {\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                assign[k] = j;\n                currentT = newT;\n                if (!(newT == currentT)) {\n                    currentSteinerCost = computeSteinerCost(currentT);\n                }\n                currentCost = newCost;\n                improved = true;\n                break;\n            } else {\n                distSets[i].insert(d_ik);\n                distSets[j].erase(distSets[j].find(d_jk));\n            }\n        }\n    }\n\n    vector<int> finalT;\n    finalT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            finalT.push_back(i);\n        }\n    }\n\n    set<int> onEdges;\n    auto addPath = [&](int u, int v) {\n        while (u != v) {\n            int nxt = next[u][v];\n            int a = u, b = nxt;\n            if (a > b) swap(a, b);\n            onEdges.insert(edgeIndex[{a, b}]);\n            u = nxt;\n        }\n    };\n\n    int n = finalT.size();\n    if (n > 1) {\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[finalT[u]][finalT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u != -1) {\n                addPath(finalT[u], finalT[v]);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << P[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    for (int j = 0; j < M; ++j) {\n        cout << (onEdges.count(j) ? 1 : 0);\n        if (j < M-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint to_index(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\npair<int, int> to_coord(int idx) {\n    int x = 0;\n    while (idx >= x + 1) {\n        idx -= (x + 1);\n        x++;\n    }\n    return {x, idx};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> ball(N);\n    for (int x = 0; x < N; ++x) {\n        ball[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) {\n            cin >> ball[x][y];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n\n    // Process nodes from bottom to top (decreasing x)\n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cur_x = x;\n            int cur_y = y;\n            int cur_val = ball[cur_x][cur_y];\n\n            // Sift down until heap property satisfied\n            while (cur_x < N - 1) {\n                int left = ball[cur_x + 1][cur_y];\n                int right = ball[cur_x + 1][cur_y + 1];\n                int smaller_child = min(left, right);\n                if (cur_val <= smaller_child) break;\n\n                // Determine which child to swap with\n                int swap_y;\n                if (left < right) {\n                    swap_y = cur_y;\n                } else {\n                    swap_y = cur_y + 1;\n                }\n\n                // Perform the swap\n                swaps.emplace_back(cur_x, cur_y, cur_x + 1, swap_y);\n                swap(ball[cur_x][cur_y], ball[cur_x + 1][swap_y]);\n\n                // Move down to the swapped child position\n                cur_x = cur_x + 1;\n                cur_y = swap_y;\n                cur_val = ball[cur_x][cur_y];\n            }\n        }\n    }\n\n    // Output\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nconst int D = 9;\nconst int entrance_i = 0, entrance_j = 4;\n\nint main() {\n    int N;\n    cin >> D >> N;  // D is always 9, but read anyway\n    bool obstacle[D][D] = {false};\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N; // number of containers\n\n    bool occupied[D][D] = {false};\n    int label_of[D][D];\n    int parent_i[D][D], parent_j[D][D];\n    vector<pair<int, int>> children[D][D];\n\n    vector<int> seen_labels;\n\n    // process containers one by one\n    for (int d = 0; d < M; ++d) {\n        int t;\n        cin >> t;\n\n        // BFS from entrance through empty squares\n        int dist[D][D];\n        memset(dist, -1, sizeof(dist));\n        pair<int, int> bfs_parent[D][D];\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            const int di[4] = {1, -1, 0, 0};\n            const int dj[4] = {0, 0, 1, -1};\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                    !obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    bfs_parent[ni][nj] = {i, j};\n                    q.push({ni, nj});\n                }\n            }\n        }\n\n        // collect leaves (empty squares with exactly one empty neighbor)\n        vector<tuple<int, int, int>> leaves; // (distance, i, j)\n        const int di[4] = {1, -1, 0, 0};\n        const int dj[4] = {0, 0, 1, -1};\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == entrance_i && j == entrance_j) continue;\n                if (dist[i][j] == -1) continue;\n                int empty_neighbors = 0;\n                for (int dir = 0; dir < 4; ++dir) {\n                    int ni = i + di[dir], nj = j + dj[dir];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                        !obstacle[ni][nj] && !occupied[ni][nj]) {\n                        empty_neighbors++;\n                    }\n                }\n                if (empty_neighbors == 1) {\n                    leaves.push_back({dist[i][j], i, j});\n                }\n            }\n        }\n\n        // sort leaves by distance (closest first)\n        sort(leaves.begin(), leaves.end());\n\n        // compute quantile of current label among seen labels\n        double quantile;\n        if (seen_labels.empty()) {\n            quantile = 0.0;\n        } else {\n            int count_smaller = 0;\n            for (int lbl : seen_labels) {\n                if (lbl < t) count_smaller++;\n            }\n            quantile = (double)count_smaller / seen_labels.size();\n        }\n\n        // choose leaf according to quantile\n        int L = leaves.size();\n        int idx = (int)round(quantile * (L - 1));\n        idx = max(0, min(L - 1, idx));\n        auto [dist_val, pi, pj] = leaves[idx];\n\n        // output placement\n        cout << pi << \" \" << pj << endl;\n\n        // record placement\n        occupied[pi][pj] = true;\n        label_of[pi][pj] = t;\n        parent_i[pi][pj] = bfs_parent[pi][pj].first;\n        parent_j[pi][pj] = bfs_parent[pi][pj].second;\n        children[parent_i[pi][pj]][parent_j[pi][pj]].push_back({pi, pj});\n\n        seen_labels.push_back(t);\n    }\n\n    // determine and output transport order\n    priority_queue<pair<int, pair<int, int>>,\n                   vector<pair<int, pair<int, int>>>,\n                   greater<>> pq;\n    bool removed[D][D] = {false};\n\n    // initially, containers whose parent is the entrance are removable\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (occupied[i][j] && parent_i[i][j] == entrance_i && parent_j[i][j] == entrance_j) {\n                pq.push({label_of[i][j], {i, j}});\n            }\n        }\n    }\n\n    while (!pq.empty()) {\n        auto [lbl, coords] = pq.top(); pq.pop();\n        int i = coords.first, j = coords.second;\n        cout << i << \" \" << j << endl;\n        removed[i][j] = true;\n\n        // children of the removed container become removable\n        for (auto child : children[i][j]) {\n            int ci = child.first, cj = child.second;\n            pq.push({label_of[ci][cj], {ci, cj}});\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x < p.x || (x == p.x && y < p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\n// BFS to find shortest path between two sets in a graph defined by allowed cells\nvector<Point> bfs_path(const vector<vector<bool>>& allowed, \n                       const set<Point>& start_set, \n                       const set<Point>& end_set,\n                       int n) {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    vector<vector<Point>> prev(n, vector<Point>(n, Point(-1, -1)));\n    queue<Point> q;\n    \n    for (const Point& p : start_set) {\n        visited[p.x][p.y] = true;\n        q.push(p);\n    }\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        if (end_set.count(cur)) {\n            // Reconstruct path\n            vector<Point> path;\n            Point at = cur;\n            while (!(at.x == -1 && at.y == -1)) {\n                path.push_back(at);\n                at = prev[at.x][at.y];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && allowed[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                prev[nx][ny] = cur;\n                q.push(Point(nx, ny));\n            }\n        }\n    }\n    return {}; // No path found\n}\n\n// Check if removing a point disconnects a set of points\nbool is_articulation(const set<Point>& region, const Point& p, int n) {\n    if (!region.count(p)) return false;\n    \n    set<Point> remaining = region;\n    remaining.erase(p);\n    \n    if (remaining.empty()) return false;\n    \n    // Find first point in remaining\n    Point start = *remaining.begin();\n    set<Point> component;\n    queue<Point> q;\n    q.push(start);\n    component.insert(start);\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            Point np(nx, ny);\n            if (remaining.count(np) && !component.count(np)) {\n                component.insert(np);\n                q.push(np);\n            }\n        }\n    }\n    \n    return component.size() != remaining.size();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n = N, m = M;\n    vector<vector<int>> grid(n, vector<int>(n));\n    \n    // Read input\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    // Build adjacency information\n    vector<set<int>> adj_colors(m + 1); // neighbors for each color\n    // For each unordered pair (c,d), store a list of adjacent cell pairs\n    vector<vector<vector<pair<Point, Point>>>> adj_pairs(m + 1, vector<vector<pair<Point, Point>>>(m + 1));\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int color = grid[ni][nj];\n                    if (color != c) {\n                        // Ensure c < color for consistent ordering\n                        if (c < color) {\n                            adj_colors[c].insert(color);\n                            adj_colors[color].insert(c);\n                            adj_pairs[c][color].push_back({Point(i, j), Point(ni, nj)});\n                        } else if (c > color) {\n                            adj_colors[color].insert(c);\n                            adj_colors[c].insert(color);\n                            adj_pairs[color][c].push_back({Point(ni, nj), Point(i, j)});\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Anchor selection: for each edge (c,d), choose one pair\n    vector<set<Point>> anchors(m + 1);\n    \n    for (int c = 1; c <= m; c++) {\n        for (int d : adj_colors[c]) {\n            if (c >= d) continue; // process each edge once\n            \n            // Check if we already have an adjacent pair in anchors\n            bool already_adjacent = false;\n            for (const Point& p1 : anchors[c]) {\n                for (int dir = 0; dir < 4; dir++) {\n                    Point p2(p1.x + dx[dir], p1.y + dy[dir]);\n                    if (anchors[d].count(p2)) {\n                        already_adjacent = true;\n                        break;\n                    }\n                }\n                if (already_adjacent) break;\n            }\n            if (already_adjacent) continue;\n            \n            // Try to find a pair that uses existing anchors\n            bool found = false;\n            for (auto& pr : adj_pairs[c][d]) {\n                Point u = pr.first, v = pr.second;\n                if (anchors[c].count(u)) {\n                    anchors[d].insert(v);\n                    found = true;\n                    break;\n                } else if (anchors[d].count(v)) {\n                    anchors[c].insert(u);\n                    found = true;\n                    break;\n                }\n            }\n            if (!found && !adj_pairs[c][d].empty()) {\n                // Add both cells\n                Point u = adj_pairs[c][d][0].first;\n                Point v = adj_pairs[c][d][0].second;\n                anchors[c].insert(u);\n                anchors[d].insert(v);\n            }\n        }\n    }\n    \n    // For colors with no anchors, add an arbitrary cell\n    for (int c = 1; c <= m; c++) {\n        if (anchors[c].empty()) {\n            // Find any cell of this color\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (grid[i][j] == c) {\n                        anchors[c].insert(Point(i, j));\n                        break;\n                    }\n                }\n                if (!anchors[c].empty()) break;\n            }\n        }\n    }\n    \n    // Build Steiner trees for each color\n    vector<set<Point>> kept(m + 1); // kept cells for each color\n    \n    for (int c = 1; c <= m; c++) {\n        // Create allowed matrix for this color\n        vector<vector<bool>> allowed(n, vector<bool>(n, false));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == c) {\n                    allowed[i][j] = true;\n                }\n            }\n        }\n        \n        set<Point> terminals = anchors[c];\n        set<Point> current = terminals;\n        \n        // Connect components iteratively\n        while (true) {\n            // Find connected components of current\n            vector<set<Point>> components;\n            set<Point> visited;\n            \n            for (const Point& p : current) {\n                if (visited.count(p)) continue;\n                \n                set<Point> comp;\n                queue<Point> q;\n                q.push(p);\n                comp.insert(p);\n                visited.insert(p);\n                \n                while (!q.empty()) {\n                    Point cur = q.front();\n                    q.pop();\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point np(cur.x + dx[d], cur.y + dy[d]);\n                        if (np.x >= 0 && np.x < n && np.y >= 0 && np.y < n && \n                            allowed[np.x][np.y] && current.count(np) && !visited.count(np)) {\n                            comp.insert(np);\n                            visited.insert(np);\n                            q.push(np);\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n            \n            if (components.size() <= 1) break;\n            \n            // Connect first two components\n            set<Point> comp1 = components[0], comp2 = components[1];\n            vector<Point> path = bfs_path(allowed, comp1, comp2, n);\n            \n            if (!path.empty()) {\n                for (const Point& p : path) {\n                    current.insert(p);\n                }\n            } else {\n                // Should not happen since graph is connected\n                break;\n            }\n        }\n        \n        // Prune leaves that are not terminals\n        set<Point> tree = current;\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            vector<Point> to_remove;\n            for (const Point& p : tree) {\n                if (terminals.count(p)) continue;\n                \n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    Point np(p.x + dx[d], p.y + dy[d]);\n                    if (tree.count(np)) deg++;\n                }\n                if (deg <= 1) {\n                    to_remove.push_back(p);\n                }\n            }\n            \n            for (const Point& p : to_remove) {\n                tree.erase(p);\n                changed = true;\n            }\n        }\n        \n        kept[c] = tree;\n    }\n    \n    // Build output grid\n    vector<vector<int>> output(n, vector<int>(n, 0));\n    for (int c = 1; c <= m; c++) {\n        for (const Point& p : kept[c]) {\n            output[p.x][p.y] = c;\n        }\n    }\n    \n    // Check connectivity of 0\n    vector<vector<bool>> visited0(n, vector<bool>(n, false));\n    queue<Point> q0;\n    \n    // Start from boundary 0 cells (connected to outside)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if ((i == 0 || i == n-1 || j == 0 || j == n-1) && output[i][j] == 0) {\n                q0.push(Point(i, j));\n                visited0[i][j] = true;\n            }\n        }\n    }\n    \n    while (!q0.empty()) {\n        Point cur = q0.front();\n        q0.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                output[nx][ny] == 0 && !visited0[nx][ny]) {\n                visited0[nx][ny] = true;\n                q0.push(Point(nx, ny));\n            }\n        }\n    }\n    \n    // If there are unvisited 0 cells, try to fix\n    bool disconnected = false;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0 && !visited0[i][j]) {\n                disconnected = true;\n                break;\n            }\n        }\n        if (disconnected) break;\n    }\n    \n    if (disconnected) {\n        // Try to remove some non-zero cells to connect 0\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] != 0 && !visited0[i][j]) {\n                    int c = output[i][j];\n                    Point p(i, j);\n                    \n                    // Check if this cell can be removed\n                    bool can_remove = true;\n                    \n                    // Check if it's a leaf in its tree and not a terminal\n                    if (kept[c].count(p)) {\n                        int deg = 0;\n                        for (int d = 0; d < 4; d++) {\n                            Point np(i + dx[d], j + dy[d]);\n                            if (kept[c].count(np)) deg++;\n                        }\n                        if (deg > 1) can_remove = false;\n                        \n                        // Check if it's the only anchor for some neighbor\n                        for (int d : adj_colors[c]) {\n                            if (d == 0) continue;\n                            bool has_other = false;\n                            for (const Point& q : kept[c]) {\n                                if (q == p) continue;\n                                for (int dir = 0; dir < 4; dir++) {\n                                    Point nq(q.x + dx[dir], q.y + dy[dir]);\n                                    if (nq.x >= 0 && nq.x < n && nq.y >= 0 && nq.y < n && \n                                        output[nq.x][nq.y] == d) {\n                                        has_other = true;\n                                        break;\n                                    }\n                                }\n                                if (has_other) break;\n                            }\n                            if (!has_other) {\n                                can_remove = false;\n                                break;\n                            }\n                        }\n                    } else {\n                        can_remove = false;\n                    }\n                    \n                    if (can_remove) {\n                        // Change to 0 and update\n                        output[i][j] = 0;\n                        kept[c].erase(p);\n                        \n                        // Re-run BFS for 0 connectivity\n                        fill(visited0.begin(), visited0.end(), vector<bool>(n, false));\n                        queue<Point> q0;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if ((ii == 0 || ii == n-1 || jj == 0 || jj == n-1) && output[ii][jj] == 0) {\n                                    q0.push(Point(ii, jj));\n                                    visited0[ii][jj] = true;\n                                }\n                            }\n                        }\n                        while (!q0.empty()) {\n                            Point cur = q0.front();\n                            q0.pop();\n                            for (int d = 0; d < 4; d++) {\n                                int nx = cur.x + dx[d];\n                                int ny = cur.y + dy[d];\n                                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                                    output[nx][ny] == 0 && !visited0[nx][ny]) {\n                                    visited0[nx][ny] = true;\n                                    q0.push(Point(nx, ny));\n                                }\n                            }\n                        }\n                        \n                        // Check if still disconnected\n                        disconnected = false;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if (output[ii][jj] == 0 && !visited0[ii][jj]) {\n                                    disconnected = true;\n                                    break;\n                                }\n                            }\n                            if (disconnected) break;\n                        }\n                        if (!disconnected) break;\n                    }\n                }\n            }\n            if (!disconnected) break;\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string s;\n    cin >> s;\n    queries_used++;\n    return s[0];\n}\n\nchar compare(int i, int j) {\n    return query({i}, {j});\n}\n\n// Greedy bucket assignment using direct comparisons of bucket sums\nvoid greedy_bucket(vector<int>& ans) {\n    vector<vector<int>> buckets(D);\n    for (int i = 0; i < N; ++i) {\n        // Find a bucket to put this item\n        int best = -1;\n        // First, check if there is any empty bucket\n        for (int j = 0; j < D; ++j) {\n            if (buckets[j].empty()) {\n                best = j;\n                break;\n            }\n        }\n        if (best == -1) {\n            // All buckets are non-empty, find the lightest by comparing\n            best = 0;\n            for (int j = 1; j < D; ++j) {\n                if (queries_used >= Q) break; // cannot compare further\n                vector<int> L = buckets[best];\n                vector<int> R = buckets[j];\n                char res = query(L, R);\n                if (res == '>') {\n                    best = j;\n                }\n                // if '=', keep current best\n            }\n        }\n        buckets[best].push_back(i);\n        ans[i] = best;\n    }\n}\n\n// Sorting and snake assignment\nvoid sorting_snake(vector<int>& ans) {\n    vector<int> items;  // sorted order as much as we know\n    // Insert items one by one using binary search\n    for (int i = 0; i < N; ++i) {\n        if (queries_used >= Q) {\n            items.push_back(i);\n            continue;\n        }\n        int left = 0, right = items.size();\n        while (left < right && queries_used < Q) {\n            int mid = (left + right) / 2;\n            char res = compare(i, items[mid]);\n            if (res == '<') {\n                right = mid;\n            } else {\n                left = mid + 1;\n            }\n        }\n        items.insert(items.begin() + left, i);\n    }\n\n    // Bubble sort to improve order with remaining queries\n    bool swapped = true;\n    while (queries_used < Q && swapped) {\n        swapped = false;\n        for (size_t i = 0; i + 1 < items.size(); ++i) {\n            if (queries_used >= Q) break;\n            char res = compare(items[i], items[i+1]);\n            if (res == '>') {\n                swap(items[i], items[i+1]);\n                swapped = true;\n            }\n        }\n    }\n\n    // Snake assignment\n    for (int i = 0; i < N; ++i) {\n        int item = items[i];\n        int bucket = i % D;\n        if ((i / D) % 2 == 1) {\n            bucket = D - 1 - bucket;\n        }\n        ans[item] = bucket;\n    }\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    vector<int> ans(N, -1);\n\n    // Decide which strategy to use based on available queries\n    int max_comparisons_needed = N * (D - 1);\n    if (Q >= max_comparisons_needed) {\n        greedy_bucket(ans);\n    } else {\n        sorting_snake(ans);\n    }\n\n    // Use any remaining queries as dummy comparisons\n    while (queries_used < Q) {\n        compare(0, 1);  // always valid as N >= 2\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    int h = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    for (int v = 1; v <= n; ++v) {\n        // Find the stack and position of box v\n        int s = -1, pos = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == v) {\n                    s = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (pos == (int)stacks[s].size() - 1) {\n            // v is already on top: remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        } else {\n            // Need to move the boxes above v\n            int T = stacks[s].back();  // top of the group to be moved\n            // Choose destination stack d according to the heuristic\n            int d = -1;\n            bool found_empty = false;\n            int empty_d = -1;\n            int best_d = -1;\n            int best_top = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if (stacks[i].empty()) {\n                    found_empty = true;\n                    if (empty_d == -1) empty_d = i;\n                } else {\n                    int top = stacks[i].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        best_d = i;\n                    }\n                }\n            }\n\n            if (found_empty) {\n                if (best_d == -1 || T > best_top) {\n                    d = empty_d;\n                } else {\n                    d = best_d;\n                }\n            } else {\n                d = best_d;\n            }\n\n            // Move the suffix starting at the box just above v\n            int w = stacks[s][pos + 1];\n            cout << w << \" \" << d + 1 << \"\\n\";\n\n            vector<int> suffix(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[s].erase(stacks[s].begin() + pos + 1, stacks[s].end());\n            stacks[d].insert(stacks[d].end(), suffix.begin(), suffix.end());\n\n            // Now v is on top, remove it\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n        }\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\nusing namespace std;\n\nconst int dx[] = {1, -1, 0, 0}; // D, U, R, L\nconst int dy[] = {0, 0, 1, -1};\nconst char dir_char[] = {'D', 'U', 'R', 'L'};\nconst char opp_char[] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<bool>> visited;\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (visited[ni][nj]) continue;\n        // check wall\n        if (d == 0 && h[i][j] == '1') continue;      // down\n        if (d == 1 && h[ni][nj] == '1') continue;    // up\n        if (d == 2 && v[i][j] == '1') continue;      // right\n        if (d == 3 && v[i][nj] == '1') continue;     // left\n        cout << dir_char[d];\n        dfs(ni, nj);\n        cout << opp_char[d];\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\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    visited.assign(N, vector<bool>(N, false));\n    dfs(0, 0);\n    cout << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nstruct Candidate {\n    vector<pii> pos;      // 5 positions\n    int internal_cost;    // cost to type this occurrence from scratch\n    vector<int> tail_cost; // tail_cost[k]: cost from position k to end (including letter at k)\n};\n\nint manhattan(const pii& a, const pii& b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\n// Transition cost from candidate A to candidate B given valid overlaps\nint transition_cost(const Candidate& A, const Candidate& B, const vector<int>& valid) {\n    int best = 1e9;\n    for (int k : valid) {\n        int cost = manhattan(A.pos[4], B.pos[k]) + B.tail_cost[k];\n        if (cost < best) best = cost;\n    }\n    return best;\n}\n\nint compute_cost(const vector<int>& order_targets, \n                 const vector<int>& order_candidate_idx,\n                 const vector<vector<Candidate>>& candidates,\n                 const vector<vector<vector<int>>>& valid,\n                 const pii& start) {\n    int total = 0;\n    pii cur_pos = start;\n    int cur_target = -1;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& cand = candidates[j][order_candidate_idx[i]];\n        if (cur_target == -1) {\n            total += manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n        } else {\n            total += transition_cost(candidates[cur_target][order_candidate_idx[i-1]], cand, valid[cur_target][j]);\n        }\n        cur_target = j;\n    }\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    pii start;\n    cin >> start.first >> start.second;\n\n    vector<vector<char>> A(N, vector<char>(N));\n    vector<vector<pii>> pos_list(26); // positions for each letter\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            pos_list[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n\n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n\n    // Random number generator\n    mt19937 rng(123456);\n    uniform_int_distribution<int> dist;\n\n    const int RANDOM_CANDIDATES = 2000;\n    const int GREEDY_CANDIDATES = 200;\n    const int KEEP = 30;\n\n    vector<vector<Candidate>> candidates(M);\n\n    // Generate candidate occurrences for each target\n    for (int idx = 0; idx < M; ++idx) {\n        const string& t = targets[idx];\n        vector<Candidate> cands;\n        \n        // Random candidates\n        for (int iter = 0; iter < RANDOM_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            for (int k = 0; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                uniform_int_distribution<int> d(0, (int)lst.size() - 1);\n                pos[k] = lst[d(rng)];\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n        \n        // Greedy candidates: start from random position for first letter,\n        // then for each next letter choose closest position to current\n        for (int iter = 0; iter < GREEDY_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            // Choose random starting position for first letter\n            const auto& lst0 = pos_list[t[0] - 'A'];\n            uniform_int_distribution<int> d0(0, (int)lst0.size() - 1);\n            pos[0] = lst0[d0(rng)];\n            \n            for (int k = 1; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                // Find closest position to current position\n                int best_dist = 1e9;\n                pii best_pos = lst[0];\n                for (const pii& p : lst) {\n                    int d = manhattan(pos[k-1], p);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_pos = p;\n                    }\n                }\n                pos[k] = best_pos;\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n\n        // Keep the best KEEP candidates by internal cost\n        sort(cands.begin(), cands.end(),\n             [](const Candidate& a, const Candidate& b) { return a.internal_cost < b.internal_cost; });\n        if (cands.size() > KEEP) cands.resize(KEEP);\n        candidates[idx] = cands;\n    }\n\n    // Precompute valid overlaps between targets\n    vector<vector<vector<int>>> valid(M, vector<vector<int>>(M));\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            const string& si = targets[i];\n            const string& sj = targets[j];\n            vector<int> v;\n            for (int k = 1; k <= 4; ++k) {\n                if (si.substr(5 - k) == sj.substr(0, k)) {\n                    v.push_back(k);\n                }\n            }\n            v.push_back(0); // k=0 always allowed\n            valid[i][j] = v;\n        }\n    }\n\n    // Greedy construction of the path\n    vector<int> order_targets;\n    vector<int> order_candidate_idx;\n    vector<bool> covered(M, false);\n\n    pii cur_pos = start;\n    int cur_target = -1;\n\n    for (int step = 0; step < M; ++step) {\n        int best_add = 1e9;\n        int best_j = -1, best_c = -1;\n\n        for (int j = 0; j < M; ++j) {\n            if (covered[j]) continue;\n            for (size_t c = 0; c < candidates[j].size(); ++c) {\n                const Candidate& cand = candidates[j][c];\n                if (cur_target == -1) {\n                    int add = manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n                    if (add < best_add) {\n                        best_add = add;\n                        best_j = j;\n                        best_c = c;\n                    }\n                } else {\n                    for (int k : valid[cur_target][j]) {\n                        int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                        if (add < best_add) {\n                            best_add = add;\n                            best_j = j;\n                            best_c = c;\n                        }\n                    }\n                }\n            }\n        }\n\n        covered[best_j] = true;\n        order_targets.push_back(best_j);\n        order_candidate_idx.push_back(best_c);\n\n        cur_target = best_j;\n        cur_pos = candidates[best_j][best_c].pos[4];\n    }\n\n    // Local search with 2-opt (swap any two positions)\n    int current_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < M - 1; ++i) {\n            for (int j = i + 1; j < M; ++j) {\n                // Try swapping i and j\n                swap(order_targets[i], order_targets[j]);\n                swap(order_candidate_idx[i], order_candidate_idx[j]);\n                int new_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n                if (new_cost < current_cost) {\n                    current_cost = new_cost;\n                    improved = true;\n                } else {\n                    // Swap back\n                    swap(order_targets[i], order_targets[j]);\n                    swap(order_candidate_idx[i], order_candidate_idx[j]);\n                }\n            }\n        }\n    }\n\n    // Dynamic programming to re-select candidates for fixed order\n    vector<int> final_candidate_idx(M);\n    int final_cost = 0;\n    {\n        int n = M;\n        vector<vector<int>> dp(n, vector<int>(candidates[order_targets[0]].size(), 1e9));\n        vector<vector<int>> prev(n, vector<int>(candidates[order_targets[0]].size(), -1));\n        \n        // Initialize for first target\n        for (size_t c = 0; c < candidates[order_targets[0]].size(); ++c) {\n            const Candidate& cand = candidates[order_targets[0]][c];\n            dp[0][c] = manhattan(start, cand.pos[0]) + cand.internal_cost;\n        }\n\n        for (int i = 1; i < n; ++i) {\n            int cur_target = order_targets[i];\n            int prev_target = order_targets[i-1];\n            for (size_t c = 0; c < candidates[cur_target].size(); ++c) {\n                const Candidate& cand_cur = candidates[cur_target][c];\n                for (size_t d = 0; d < candidates[prev_target].size(); ++d) {\n                    const Candidate& cand_prev = candidates[prev_target][d];\n                    int add = transition_cost(cand_prev, cand_cur, valid[prev_target][cur_target]);\n                    int total = dp[i-1][d] + add;\n                    if (total < dp[i][c]) {\n                        dp[i][c] = total;\n                        prev[i][c] = d;\n                    }\n                }\n            }\n        }\n\n        // Find best final candidate\n        int best_c = -1;\n        int best_total = 1e9;\n        for (size_t c = 0; c < dp[n-1].size(); ++c) {\n            if (dp[n-1][c] < best_total) {\n                best_total = dp[n-1][c];\n                best_c = c;\n            }\n        }\n\n        // Backtrack\n        final_cost = best_total;\n        int cur_c = best_c;\n        for (int i = n-1; i >= 0; --i) {\n            final_candidate_idx[i] = cur_c;\n            cur_c = prev[i][cur_c];\n            if (cur_c == -1 && i > 0) break; // should not happen\n        }\n    }\n\n    // Build the output sequence of moves using final candidates\n    vector<pii> moves;\n    int cur_target_move = -1;\n    pii cur_pos_move = start;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& occ = candidates[j][final_candidate_idx[i]];\n        if (cur_target_move == -1) {\n            for (int k = 0; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        } else {\n            int best_k = 0;\n            int best_add = 1e9;\n            for (int k : valid[cur_target_move][j]) {\n                int add = manhattan(cur_pos_move, occ.pos[k]) + occ.tail_cost[k];\n                if (add < best_add) {\n                    best_add = add;\n                    best_k = k;\n                }\n            }\n            for (int k = best_k; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        }\n        cur_target_move = j;\n        cur_pos_move = occ.pos[4];\n    }\n\n    // Output the moves\n    for (const pii& p : moves) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (not used in this simple solution)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n    \n    vector<pair<int, int>> oil_cells;\n    \n    // Drill every square\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            int val;\n            cin >> val;\n            if (val > 0) {\n                oil_cells.push_back({i, j});\n            }\n        }\n    }\n    \n    // Output the guess\n    cout << \"a \" << oil_cells.size();\n    for (auto [i, j] : oil_cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    // Read response (should be 1)\n    int resp;\n    cin >> resp;\n    // If response is 0, we could try again, but drilling all should be correct.\n    // For safety, if resp == 0, we could drill again? But problem says operation ends if correct.\n    // We'll just exit.\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <cassert>\nusing namespace std;\n\nconst int W_MAX = 1000; // grid size\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    int area() const { return (x2 - x1) * (y2 - y1); }\n};\n\n// Greedy allocation of target areas B_k\nvector<long long> allocateB(const vector<vector<int>>& A, int D, int N) {\n    vector<long long> B(N, 0);\n    long long total_remaining = (long long)W_MAX * W_MAX;\n    // For each k, collect desires and sort\n    vector<vector<int>> sortedA(N);\n    for (int k = 0; k < N; ++k) {\n        for (int d = 0; d < D; ++d) {\n            sortedA[k].push_back(A[d][k]);\n        }\n        sort(sortedA[k].begin(), sortedA[k].end());\n    }\n    // Create segments: each (benefit, length, k)\n    struct Segment {\n        int benefit, len, k;\n        bool operator<(const Segment& other) const {\n            return benefit < other.benefit; // max-heap\n        }\n    };\n    vector<Segment> segments;\n    for (int k = 0; k < N; ++k) {\n        int prev = 0;\n        for (size_t i = 0; i < sortedA[k].size(); ++i) {\n            int cur = sortedA[k][i];\n            if (cur > prev) {\n                int benefit = 100 * (D - i);\n                int len = cur - prev;\n                segments.push_back({benefit, len, k});\n            }\n            prev = cur;\n        }\n    }\n    priority_queue<Segment> pq(segments.begin(), segments.end());\n    while (total_remaining > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        if (seg.benefit == 0) break;\n        long long take = min((long long)seg.len, total_remaining);\n        B[seg.k] += take;\n        total_remaining -= take;\n        seg.len -= take;\n        if (seg.len > 0) {\n            pq.push(seg);\n        }\n    }\n    // Distribute remaining area arbitrarily (benefit 0)\n    if (total_remaining > 0) {\n        for (int k = 0; k < N && total_remaining > 0; ++k) {\n            long long add = min(total_remaining, (long long)1);\n            B[k] += add;\n            total_remaining -= add;\n        }\n    }\n    return B;\n}\n\n// Recursive partition of the grid into rectangles with areas as close as possible to B\nvoid partition(Rect r, vector<int> indices, const vector<long long>& B, vector<Rect>& rects) {\n    int m = indices.size();\n    if (m == 1) {\n        rects[indices[0]] = r;\n        return;\n    }\n    long long total_target = 0;\n    for (int i : indices) total_target += B[i];\n    long long total_area = (long long)(r.x2 - r.x1) * (r.y2 - r.y1);\n    // sort indices by B to make contiguous groups\n    sort(indices.begin(), indices.end(), [&](int i, int j) { return B[i] < B[j]; });\n    long long best_waste = LLONG_MAX;\n    int best_split = -1;\n    int best_orient = 0; // 0 = horizontal, 1 = vertical\n    int best_cut = 0;\n    int width = r.x2 - r.x1;\n    int height = r.y2 - r.y1;\n    for (int i = 1; i < m; ++i) {\n        long long sum_left = 0;\n        for (int j = 0; j < i; ++j) sum_left += B[indices[j]];\n        long long sum_right = total_target - sum_left;\n        // horizontal split\n        double target_y = (double)sum_left / width;\n        int cut_y = (int)round(target_y);\n        if (cut_y < 1) cut_y = 1;\n        if (cut_y > height-1) cut_y = height-1;\n        long long top_area = (long long)width * cut_y;\n        long long bottom_area = (long long)width * (height - cut_y);\n        long long waste = llabs(top_area - sum_left) + llabs(bottom_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 0;\n            best_cut = cut_y;\n        }\n        // vertical split\n        double target_x = (double)sum_left / height;\n        int cut_x = (int)round(target_x);\n        if (cut_x < 1) cut_x = 1;\n        if (cut_x > width-1) cut_x = width-1;\n        long long left_area = (long long)cut_x * height;\n        long long right_area = (long long)(width - cut_x) * height;\n        waste = llabs(left_area - sum_left) + llabs(right_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 1;\n            best_cut = cut_x;\n        }\n    }\n    // Now split\n    if (best_orient == 0) {\n        // horizontal\n        Rect top(r.x1, r.y1, r.x2, r.y1 + best_cut);\n        Rect bottom(r.x1, r.y1 + best_cut, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(top, left_indices, B, rects);\n        partition(bottom, right_indices, B, rects);\n    } else {\n        // vertical\n        Rect left(r.x1, r.y1, r.x1 + best_cut, r.y2);\n        Rect right(r.x1 + best_cut, r.y1, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(left, left_indices, B, rects);\n        partition(right, right_indices, B, rects);\n    }\n}\n\nvector<Rect> packRectangles(const vector<long long>& B) {\n    int N = B.size();\n    vector<Rect> rects(N);\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    // Recursive partition covering the whole grid\n    partition(Rect{0, 0, W_MAX, W_MAX}, indices, B, rects);\n    return rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    // W_input should be 1000; we ignore it and use W_MAX.\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) {\n            cin >> A[d][k];\n        }\n    }\n\n    vector<long long> B = allocateB(A, D, N);\n    vector<Rect> rects = packRectangles(B);\n\n    // Compute actual areas and sort indices by area ascending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return rects[i].area() < rects[j].area();\n    });\n\n    // Output for each day\n    for (int d = 0; d < D; ++d) {\n        // Sort reservations by desired area ascending\n        vector<int> day_order(N);\n        iota(day_order.begin(), day_order.end(), 0);\n        sort(day_order.begin(), day_order.end(), [&](int i, int j) {\n            return A[d][i] < A[d][j];\n        });\n        // Create assignment: smallest rect to smallest desire\n        vector<Rect> assigned(N);\n        for (int i = 0; i < N; ++i) {\n            int k = day_order[i];          // reservation index\n            int rect_idx = order[i];       // rectangle index\n            assigned[k] = rects[rect_idx];\n        }\n        // Output in reservation order (0..N-1)\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = assigned[k];\n            cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\nstruct Move {\n    int m, p, q;\n    vector<pair<int, int>> cells; // (index, value)\n};\n\nstruct State {\n    array<int, N*N> board;\n    long long score;\n    State* parent;\n    int m, p, q; // move that led to this state, or -1 for initial\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    vector<int> a(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i*N + j];\n        }\n    }\n\n    vector<array<array<int, 3>, 3>> 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][i][j];\n            }\n        }\n    }\n\n    // Precompute all possible moves\n    vector<Move> moves;\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                Move move;\n                move.m = m;\n                move.p = p;\n                move.q = q;\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        int idx = (p+i)*N + (q+j);\n                        int val = stamps[m][i][j] % MOD;\n                        move.cells.emplace_back(idx, val);\n                    }\n                }\n                moves.push_back(move);\n            }\n        }\n    }\n\n    // Beam search\n    const int beam_width = 25;\n    vector<State*> all_states;\n    State* initial = new State;\n    initial->parent = nullptr;\n    initial->m = initial->p = initial->q = -1;\n    copy(a.begin(), a.end(), initial->board.begin());\n    initial->score = accumulate(a.begin(), a.end(), 0LL);\n    all_states.push_back(initial);\n\n    State* global_best = initial;\n    long long global_best_score = initial->score;\n\n    vector<State*> current_beam;\n    current_beam.push_back(initial);\n\n    for (int step = 0; step < K; ++step) {\n        vector<State*> candidates;\n\n        for (State* s : current_beam) {\n            // Option: do nothing\n            candidates.push_back(s);\n\n            // Try every move\n            for (const Move& move : moves) {\n                array<int, N*N> new_board = s->board;\n                long long gain = 0;\n\n                for (auto [idx, val] : move.cells) {\n                    int old_rem = new_board[idx];\n                    int new_rem = (old_rem + val) % MOD;\n                    gain += new_rem - old_rem;\n                    new_board[idx] = new_rem;\n                }\n\n                long long new_score = s->score + gain;\n\n                State* new_state = new State;\n                new_state->board = new_board;\n                new_state->score = new_score;\n                new_state->parent = s;\n                new_state->m = move.m;\n                new_state->p = move.p;\n                new_state->q = move.q;\n\n                candidates.push_back(new_state);\n                all_states.push_back(new_state);\n\n                if (new_score > global_best_score) {\n                    global_best = new_state;\n                    global_best_score = new_score;\n                }\n            }\n        }\n\n        // Select top beam_width states\n        sort(candidates.begin(), candidates.end(),\n             [](State* a, State* b) { return a->score > b->score; });\n\n        if (!candidates.empty() && candidates[0]->score > global_best_score) {\n            global_best = candidates[0];\n            global_best_score = candidates[0]->score;\n        }\n\n        current_beam.clear();\n        for (int i = 0; i < beam_width && i < candidates.size(); ++i) {\n            current_beam.push_back(candidates[i]);\n        }\n    }\n\n    // Reconstruct the sequence of moves\n    vector<tuple<int, int, int>> sequence;\n    State* cur = global_best;\n    while (cur->parent != nullptr) {\n        sequence.emplace_back(cur->m, cur->p, cur->q);\n        cur = cur->parent;\n    }\n    reverse(sequence.begin(), sequence.end());\n\n    // Output\n    cout << sequence.size() << \"\\n\";\n    for (auto [m, p, q] : sequence) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    // Clean up\n    for (State* s : all_states) {\n        delete s;\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Crane {\n    int r, c;\n    int holding = -1; // container ID or -1\n    enum State { IDLE, MOVING_TO_PICKUP, PICKING_UP, MOVING_TO_DROPOFF, DROPPING_OFF, WAITING };\n    State state = IDLE;\n    int target_r = -1, target_c = -1;\n    int dest_row = -1; // for large crane: destination row for parking\n    vector<pair<int,int>> path;\n    int path_idx = 0;\n    \n    Crane(int r, int c) : r(r), c(c) {}\n};\n\nint grid[N][N]; // -1 empty, else container ID\nint gate_next_idx[N]; // next index to place for each left gate\nvector<int> gate_queues[N]; // A[i][0..4]\nint dispatch_next_needed[N]; // next needed ID for each row\nvector<int> dispatched[N]; // dispatched IDs per row\nbool container_dispatched[N*N] = {false};\nCrane cranes[N] = {Crane(0,0), Crane(1,0), Crane(2,0), Crane(3,0), Crane(4,0)};\n\n// Check if a cell is occupied by a container\nbool has_container(int r, int c) {\n    return grid[r][c] != -1;\n}\n\n// Check if a cell is occupied by another crane (excluding self)\nbool has_other_crane(int r, int c, int self_idx) {\n    for (int i = 0; i < N; ++i) {\n        if (i != self_idx && cranes[i].r == r && cranes[i].c == c) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a crane can move to a cell\nbool can_move_to(int r, int c, int crane_idx, bool carrying) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return false;\n    if (has_other_crane(r, c, crane_idx)) return false;\n    if (carrying && has_container(r, c)) return false; // small crane with container can't move to occupied\n    // Large crane (index 0) can move to cells with containers even while carrying\n    if (crane_idx == 0) return true;\n    return true;\n}\n\n// BFS to find next move direction from (sr,sc) to (tr,tc)\npair<int,int> find_next_move(int sr, int sc, int tr, int tc, int crane_idx, bool carrying) {\n    if (sr == tr && sc == tc) return {0, 0};\n    \n    // BFS\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    visited[sr][sc] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) break;\n        \n        int dr[] = {-1, 1, 0, 0};\n        int dc[] = {0, 0, -1, 1};\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (can_move_to(nr, nc, crane_idx, carrying) && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                prev[nr][nc] = {r, c};\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path and return first step\n    if (!visited[tr][tc]) return {0, 0}; // no path, stay\n    \n    // Trace back\n    int r = tr, c = tc;\n    while (prev[r][c] != make_pair(sr, sc)) {\n        auto [pr, pc] = prev[r][c];\n        r = pr; c = pc;\n    }\n    // Now (r,c) is one step from (sr,sc)\n    return {r - sr, c - sc};\n}\n\n// Find free parking spot in row (columns 1-3)\nint find_free_parking(int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (!has_container(row, c) && !has_other_crane(row, c, -1)) {\n            return c;\n        }\n    }\n    return -1;\n}\n\n// Check if a container is parked in a given row\nbool is_parked_in_row(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return true;\n    }\n    return false;\n}\n\n// Find the cell where a container is parked in a row\npair<int,int> find_parked_cell(int container_id, int row) {\n    for (int c = 1; c <= 3; ++c) {\n        if (grid[row][c] == container_id) return {row, c};\n    }\n    return {-1, -1};\n}\n\nvoid simulate(vector<string>& actions) {\n    // Initialize\n    memset(grid, -1, sizeof(grid));\n    fill(gate_next_idx, gate_next_idx + N, 0);\n    fill(dispatch_next_needed, dispatch_next_needed + N, 0);\n    for (int i = 0; i < N; ++i) dispatched[i].clear();\n    fill(container_dispatched, container_dispatched + N*N, false);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].holding = -1;\n        cranes[i].state = Crane::IDLE;\n        cranes[i].path.clear();\n    }\n    \n    actions.resize(N);\n    for (int t = 0; t < MAX_TURNS; ++t) {\n        // Step 1: Place containers at gates\n        for (int i = 0; i < N; ++i) {\n            if (gate_next_idx[i] >= N) continue;\n            bool can_place = true;\n            if (has_container(i, 0)) can_place = false;\n            for (int k = 0; k < N; ++k) {\n                if (cranes[k].r == i && cranes[k].c == 0 && cranes[k].holding != -1) {\n                    can_place = false;\n                    break;\n                }\n            }\n            if (can_place) {\n                int container_id = gate_queues[i][gate_next_idx[i]];\n                grid[i][0] = container_id;\n                gate_next_idx[i]++;\n            }\n        }\n        \n        // Step 2: Crane actions\n        vector<char> turn_actions(N, '.');\n        \n        // Process large crane (index 0) first\n        auto& lc = cranes[0];\n        switch (lc.state) {\n            case Crane::IDLE: {\n                // Look for a container at a left gate that needs to be moved to parking\n                for (int i = 0; i < N; ++i) {\n                    if (!has_container(i, 0)) continue;\n                    int container_id = grid[i][0];\n                    int dest = container_id / N;\n                    int free_c = find_free_parking(dest);\n                    if (free_c != -1) {\n                        // Set target to pick up this container\n                        lc.target_r = i;\n                        lc.target_c = 0;\n                        lc.dest_row = dest;\n                        lc.state = Crane::MOVING_TO_PICKUP;\n                        break;\n                    }\n                }\n                break;\n            }\n            case Crane::MOVING_TO_PICKUP: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, lc.holding != -1);\n                if (dr == 0 && dc == 0) {\n                    // Reached, pick up\n                    turn_actions[0] = 'P';\n                    lc.holding = grid[lc.r][lc.c];\n                    grid[lc.r][lc.c] = -1;\n                    lc.state = Crane::PICKING_UP;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::PICKING_UP: {\n                // Set target for dropoff\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c == -1) {\n                    // No free spot, wait\n                    lc.state = Crane::WAITING;\n                } else {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n            case Crane::MOVING_TO_DROPOFF: {\n                auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0, true);\n                if (dr == 0 && dc == 0) {\n                    // Reached, drop\n                    turn_actions[0] = 'Q';\n                    grid[lc.r][lc.c] = lc.holding;\n                    lc.holding = -1;\n                    lc.state = Crane::DROPPING_OFF;\n                } else {\n                    // Move\n                    lc.r += dr;\n                    lc.c += dc;\n                    turn_actions[0] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                }\n                break;\n            }\n            case Crane::DROPPING_OFF: {\n                lc.state = Crane::IDLE;\n                break;\n            }\n            case Crane::WAITING: {\n                // Check if a free spot became available\n                int free_c = find_free_parking(lc.dest_row);\n                if (free_c != -1) {\n                    lc.target_r = lc.dest_row;\n                    lc.target_c = free_c;\n                    lc.state = Crane::MOVING_TO_DROPOFF;\n                }\n                break;\n            }\n        }\n        \n        // Process small cranes (indices 1-4)\n        for (int i = 1; i < N; ++i) {\n            auto& sc = cranes[i];\n            switch (sc.state) {\n                case Crane::IDLE: {\n                    int need = dispatch_next_needed[i];\n                    if (need < i*N || need >= (i+1)*N) break; // invalid\n                    if (container_dispatched[need]) break;\n                    auto [pr, pc] = find_parked_cell(need, i);\n                    if (pr != -1) {\n                        sc.target_r = pr;\n                        sc.target_c = pc;\n                        sc.state = Crane::MOVING_TO_PICKUP;\n                    }\n                    break;\n                }\n                case Crane::MOVING_TO_PICKUP: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, sc.holding != -1);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'P';\n                        sc.holding = grid[sc.r][sc.c];\n                        grid[sc.r][sc.c] = -1;\n                        sc.state = Crane::PICKING_UP;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::PICKING_UP: {\n                    sc.target_r = i;\n                    sc.target_c = N-1;\n                    sc.state = Crane::MOVING_TO_DROPOFF;\n                    break;\n                }\n                case Crane::MOVING_TO_DROPOFF: {\n                    auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i, true);\n                    if (dr == 0 && dc == 0) {\n                        turn_actions[i] = 'Q';\n                        grid[sc.r][sc.c] = sc.holding;\n                        sc.holding = -1;\n                        sc.state = Crane::DROPPING_OFF;\n                    } else {\n                        sc.r += dr;\n                        sc.c += dc;\n                        turn_actions[i] = (dr == -1 ? 'U' : dr == 1 ? 'D' : dc == -1 ? 'L' : 'R');\n                    }\n                    break;\n                }\n                case Crane::DROPPING_OFF: {\n                    sc.state = Crane::IDLE;\n                    break;\n                }\n                case Crane::WAITING: {\n                    break;\n                }\n            }\n        }\n        \n        // Step 3: Dispatch containers from right gates\n        for (int i = 0; i < N; ++i) {\n            if (has_container(i, N-1)) {\n                int container_id = grid[i][N-1];\n                dispatched[i].push_back(container_id);\n                container_dispatched[container_id] = true;\n                grid[i][N-1] = -1;\n                // Update next needed for this row\n                while (dispatch_next_needed[i] < (i+1)*N && container_dispatched[dispatch_next_needed[i]]) {\n                    dispatch_next_needed[i]++;\n                }\n            }\n        }\n        \n        // Record actions\n        for (int i = 0; i < N; ++i) {\n            actions[i] += turn_actions[i];\n        }\n        \n        // Check if all containers dispatched\n        bool all_done = true;\n        for (int id = 0; id < N*N; ++id) {\n            if (!container_dispatched[id]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; ++i) {\n        gate_queues[i].resize(N);\n        for (int j = 0; j < N; ++j) {\n            cin >> gate_queues[i][j];\n        }\n    }\n    \n    vector<string> actions;\n    simulate(actions);\n    \n    // Pad shorter strings with '.'\n    size_t max_len = 0;\n    for (const string& s : actions) {\n        max_len = max(max_len, s.size());\n    }\n    for (string& s : actions) {\n        if (s.size() < max_len) {\n            s.append(max_len - s.size(), '.');\n        }\n    }\n    \n    for (const string& s : actions) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 20;\n\n// Generate snake path by rows: (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> ... -> (N-1,0)\nvector<pair<int, int>> generate_path_rows() {\n    vector<pair<int, int>> path;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) path.emplace_back(i, j);\n        } else {\n            for (int j = N - 1; j >= 0; --j) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate snake path by columns: (0,0) -> (1,0) -> ... -> (N-1,0) -> (N-1,1) -> ... -> (0,N-1)\nvector<pair<int, int>> generate_path_cols() {\n    vector<pair<int, int>> path;\n    for (int j = 0; j < N; ++j) {\n        if (j % 2 == 0) {\n            for (int i = 0; i < N; ++i) path.emplace_back(i, j);\n        } else {\n            for (int i = N - 1; i >= 0; --i) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate clockwise spiral path starting at (0,0)\nvector<pair<int, int>> generate_spiral_cw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) path.emplace_back(top, j);\n        top++;\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, right);\n        right--;\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(bottom, j);\n            bottom--;\n        }\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, left);\n            left++;\n        }\n    }\n    return path;\n}\n\n// Generate counterclockwise spiral path starting at (0,0)\nvector<pair<int, int>> generate_spiral_ccw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, left);\n        left++;\n        for (int j = left; j <= right; ++j) path.emplace_back(bottom, j);\n        bottom--;\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, right);\n            right--;\n        }\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(top, j);\n            top++;\n        }\n    }\n    return path;\n}\n\n// Compute the total load-distance for a loading tour along the given path\nint compute_load_distance(const vector<pair<int, int>>& path, const vector<vector<int>>& h) {\n    int load = 0;\n    int total = 0;\n    for (int idx = 0; idx < (int)path.size(); ++idx) {\n        int i = path[idx].first, j = path[idx].second;\n        if (h[i][j] > 0) load += h[i][j];\n        if (idx < (int)path.size() - 1) total += load;\n    }\n    return total;\n}\n\n// Determine move direction from (i,j) to (ni,nj) assuming they are adjacent\nstring get_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return \"U\";\n    if (ni == i + 1) return \"D\";\n    if (nj == j - 1) return \"L\";\n    if (nj == j + 1) return \"R\";\n    assert(false);\n    return \"\";\n}\n\nint main() {\n    // Read input\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    // Generate candidate paths\n    vector<vector<pair<int, int>>> candidates;\n    candidates.push_back(generate_path_rows());\n    candidates.push_back(generate_path_cols());\n    candidates.push_back(generate_spiral_cw());\n    candidates.push_back(generate_spiral_ccw());\n\n    // Choose the path with smallest load-distance for loading tour\n    int best_dist = 1e9;\n    vector<pair<int, int>> best_path;\n    for (const auto& path : candidates) {\n        int dist = compute_load_distance(path, h);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_path = path;\n        }\n    }\n\n    // Make a copy of heights for simulation\n    vector<vector<int>> cur_h = h;\n    vector<string> ops;\n    int load = 0;\n\n    // Loading tour along best_path\n    int cur_i = best_path[0].first, cur_j = best_path[0].second;\n    for (int idx = 0; idx < (int)best_path.size(); ++idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Load if positive\n        if (cur_h[i][j] > 0) {\n            int d = cur_h[i][j];\n            ops.push_back(\"+\" + to_string(d));\n            load += d;\n            cur_h[i][j] = 0;\n        }\n        // Move to next cell if not last\n        if (idx < (int)best_path.size() - 1) {\n            int ni = best_path[idx+1].first, nj = best_path[idx+1].second;\n            ops.push_back(get_move(cur_i, cur_j, ni, nj));\n            cur_i = ni;\n            cur_j = nj;\n        }\n    }\n\n    // Unloading tour along the reverse of best_path\n    for (int idx = (int)best_path.size() - 1; idx >= 0; --idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Unload if negative\n        if (cur_h[i][j] < 0) {\n            int amount = min(load, -cur_h[i][j]);\n            if (amount > 0) {\n                ops.push_back(\"-\" + to_string(amount));\n                load -= amount;\n                cur_h[i][j] += amount;\n            }\n        }\n        // Move to previous cell if not first\n        if (idx > 0) {\n            int pi = best_path[idx-1].first, pj = best_path[idx-1].second;\n            ops.push_back(get_move(cur_i, cur_j, pi, pj));\n            cur_i = pi;\n            cur_j = pj;\n        }\n    }\n\n    // Output the operation sequence\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <utility>\n#include <set>\n#include <cstdlib>\n#include <ctime>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int T = 10;\nconst int K = 2 * N * (N - 1); // 60\nconst int MAX_ITER = 2000;     // iterations for local optimization\n\n// Global seeds for current turn\nvector<vector<int>> seeds(K, vector<int>(M));\n\n// Compute potential max sum for a pair of seeds (indices)\nint potential_max(int a, int b) {\n    int sum = 0;\n    for (int l = 0; l < M; ++l) {\n        sum += max(seeds[a][l], seeds[b][l]);\n    }\n    return sum;\n}\n\n// Compute total edge score for the grid\nint compute_total_score(const vector<vector<int>>& grid) {\n    int total = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i + 1 < N) total += potential_max(grid[i][j], grid[i + 1][j]);\n            if (j + 1 < N) total += potential_max(grid[i][j], grid[i][j + 1]);\n        }\n    }\n    return total;\n}\n\nint main() {\n    srand(time(0));\n\n    // Read initial seeds\n    for (int i = 0; i < K; ++i) {\n        for (int l = 0; l < M; ++l) {\n            cin >> seeds[i][l];\n        }\n    }\n\n    // Center of the grid (0-indexed)\n    const int center_i = 3, center_j = 3;\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Compute total sums\n        vector<int> sums(K, 0);\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                sums[i] += seeds[i][l];\n            }\n        }\n\n        // Select top 30 seeds by sum\n        vector<int> indices(K);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(),\n             [&](int i, int j) { return sums[i] > sums[j]; });\n        vector<int> plant_indices(indices.begin(), indices.begin() + 30);\n        int champion_idx = plant_indices[0];\n\n        // Add 6 complementary seeds (highest potential max with champion)\n        vector<pair<int, int>> extra; // (potential, index)\n        for (int i = 30; i < K; ++i) {\n            int idx = indices[i];\n            int P_val = 0;\n            for (int l = 0; l < M; ++l) {\n                P_val += max(seeds[champion_idx][l], seeds[idx][l]);\n            }\n            extra.emplace_back(P_val, idx);\n        }\n        sort(extra.begin(), extra.end(), greater<>());\n        for (int i = 0; i < 6; ++i) {\n            plant_indices.push_back(extra[i].second);\n        }\n\n        // Recompute champion (should be the same, but for safety)\n        for (int idx : plant_indices) {\n            if (sums[idx] > sums[champion_idx]) {\n                champion_idx = idx;\n            }\n        }\n\n        // Compute complementarity for mates (only from plant_indices, excluding champion)\n        vector<pair<int, int>> candidate_P; // (P, index)\n        for (int idx : plant_indices) {\n            if (idx == champion_idx) continue;\n            int P_val = 0;\n            for (int l = 0; l < M; ++l) {\n                P_val += max(seeds[champion_idx][l], seeds[idx][l]);\n            }\n            candidate_P.emplace_back(P_val, idx);\n        }\n        sort(candidate_P.begin(), candidate_P.end(), greater<>());\n\n        // Choose up to 4 mates\n        vector<int> mate_indices;\n        for (int i = 0; i < min(4, (int)candidate_P.size()); ++i) {\n            mate_indices.push_back(candidate_P[i].second);\n        }\n\n        // Initial grid assignment\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> seed_used(K, false);\n\n        // Place champion at center\n        grid[center_i][center_j] = champion_idx;\n        seed_used[champion_idx] = true;\n\n        // Place mates in the four orthogonal neighbours\n        vector<pair<int, int>> offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        for (int i = 0; i < (int)mate_indices.size(); ++i) {\n            int ni = center_i + offsets[i].first;\n            int nj = center_j + offsets[i].second;\n            grid[ni][nj] = mate_indices[i];\n            seed_used[mate_indices[i]] = true;\n        }\n\n        // Collect remaining seeds from plant_indices\n        vector<int> remaining_seeds;\n        for (int idx : plant_indices) {\n            if (!seed_used[idx]) {\n                remaining_seeds.push_back(idx);\n            }\n        }\n\n        // Collect empty cells\n        vector<pair<int, int>> empty_cells;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == -1) {\n                    empty_cells.emplace_back(i, j);\n                }\n            }\n        }\n\n        // Fill the remaining cells\n        for (size_t i = 0; i < remaining_seeds.size(); ++i) {\n            auto [r, c] = empty_cells[i];\n            grid[r][c] = remaining_seeds[i];\n        }\n\n        // Local optimization: improve the assignment by swapping seeds\n        int total_score = compute_total_score(grid);\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            // Randomly select two distinct cells\n            int i1 = rand() % N, j1 = rand() % N;\n            int i2 = rand() % N, j2 = rand() % N;\n            while (i1 == i2 && j1 == j2) {\n                i2 = rand() % N; j2 = rand() % N;\n            }\n\n            // Collect affected edges (unique)\n            auto edge_key = [](int i1, int j1, int i2, int j2) {\n                if (i1 > i2 || (i1 == i2 && j1 > j2)) {\n                    swap(i1, i2);\n                    swap(j1, j2);\n                }\n                return make_pair(i1 * N + j1, i2 * N + j2);\n            };\n            set<pair<int, int>> edge_set;\n\n            // Edges incident to (i1,j1)\n            if (i1 + 1 < N) edge_set.insert(edge_key(i1, j1, i1 + 1, j1));\n            if (i1 - 1 >= 0) edge_set.insert(edge_key(i1 - 1, j1, i1, j1));\n            if (j1 + 1 < N) edge_set.insert(edge_key(i1, j1, i1, j1 + 1));\n            if (j1 - 1 >= 0) edge_set.insert(edge_key(i1, j1 - 1, i1, j1));\n            // Edges incident to (i2,j2)\n            if (i2 + 1 < N) edge_set.insert(edge_key(i2, j2, i2 + 1, j2));\n            if (i2 - 1 >= 0) edge_set.insert(edge_key(i2 - 1, j2, i2, j2));\n            if (j2 + 1 < N) edge_set.insert(edge_key(i2, j2, i2, j2 + 1));\n            if (j2 - 1 >= 0) edge_set.insert(edge_key(i2, j2 - 1, i2, j2));\n\n            // Compute old contribution\n            int old_contrib = 0;\n            for (auto& e : edge_set) {\n                int a = e.first, b = e.second;\n                int i_a = a / N, j_a = a % N;\n                int i_b = b / N, j_b = b % N;\n                old_contrib += potential_max(grid[i_a][j_a], grid[i_b][j_b]);\n            }\n\n            // Swap the two seeds\n            swap(grid[i1][j1], grid[i2][j2]);\n\n            // Compute new contribution\n            int new_contrib = 0;\n            for (auto& e : edge_set) {\n                int a = e.first, b = e.second;\n                int i_a = a / N, j_a = a % N;\n                int i_b = b / N, j_b = b % N;\n                new_contrib += potential_max(grid[i_a][j_a], grid[i_b][j_b]);\n            }\n\n            int delta = new_contrib - old_contrib;\n            if (delta > 0) {\n                total_score += delta;\n                // Accept swap\n            } else {\n                // Revert swap\n                swap(grid[i1][j1], grid[i2][j2]);\n            }\n        }\n\n        // Output comments for debugging (ignored by judge)\n        cout << \"# Turn \" << turn << endl;\n        cout << \"# Champion: index=\" << champion_idx << \" sum=\" << sums[champion_idx] << endl;\n        cout << \"# Mates: \";\n        for (size_t i = 0; i < mate_indices.size(); ++i) {\n            int idx = mate_indices[i];\n            cout << idx << \" (sum=\" << sums[idx] << \", P=\" << candidate_P[i].first << \") \";\n        }\n        cout << endl;\n        cout << \"# Final edge score: \" << total_score << endl;\n\n        // Output the grid\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j > 0) cout << \" \";\n                cout << grid[i][j];\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read the next set of seeds (for the next turn)\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                cin >> seeds[i][l];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <climits>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Point& other) const { return !(*this == other); }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// direction encoding: 0: right (0,+1), 1: down (+1,0), 2: left (0,-1), 3: up (-1,0)\nint get_dir(const Point& from, const Point& to) {\n    int dx = to.x - from.x;\n    int dy = to.y - from.y;\n    if (dx == 1 && dy == 0) return 1; // down\n    if (dx == -1 && dy == 0) return 3; // up\n    if (dx == 0 && dy == 1) return 0; // right\n    if (dx == 0 && dy == -1) return 2; // left\n    // not adjacent\n    return -1;\n}\n\n// minimal rotation steps from cur_dir to target_dir (0..3)\nint rot_steps(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 0) return 0;\n    if (diff == 2) return 2;\n    return 1; // diff == 1 or 3\n}\n\n// choose rotation character to go from cur_dir to target_dir in one step (if possible)\nchar rot_char(int cur_dir, int target_dir) {\n    int diff = (target_dir - cur_dir + 4) % 4;\n    if (diff == 1) return 'R';\n    if (diff == 3) return 'L';\n    return '.'; // no rotation or need two steps (handled separately)\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\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 sources and targets\n    vector<Point> 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.emplace_back(i, j);\n            if (t_grid[i][j] == '1') targets.emplace_back(i, j);\n        }\n    }\n\n    // pair sources and targets greedily\n    vector<bool> used_target(M, false);\n    vector<pair<Point, Point>> pairs;\n    for (const Point& src : sources) {\n        int best_idx = -1;\n        int best_dist = INT_MAX;\n        for (int i = 0; i < M; ++i) {\n            if (used_target[i]) continue;\n            int d = manhattan(src, targets[i]);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        pairs.emplace_back(src, targets[best_idx]);\n        used_target[best_idx] = true;\n    }\n\n    // design tree: star with root 0 and leaves 1..V-1, all length 1\n    cout << V << '\\n';\n    for (int i = 1; i < V; ++i) {\n        cout << 0 << ' ' << 1 << '\\n';\n    }\n\n    // initial root position (choose center for convenience)\n    int init_x = N / 2, init_y = N / 2;\n    cout << init_x << ' ' << init_y << '\\n';\n\n    // simulation state\n    int rx = init_x, ry = init_y;\n    int leaf_dir = 0; // initially right\n    bool leaf_holding = false;\n\n    // track current takoyaki positions (initially all sources)\n    vector<vector<bool>> has_takoyaki(N, vector<bool>(N, false));\n    for (const Point& p : sources) has_takoyaki[p.x][p.y] = true;\n    // track filled targets\n    vector<vector<bool>> target_filled(N, vector<bool>(N, false));\n\n    vector<string> ops;\n\n    // helper to add a turn\n    auto add_turn = [&](char move, int rot_vertex, char rot, int grab_vertex, char grab) {\n        string s(2 * V, '.');\n        s[0] = move;\n        if (rot_vertex != -1) {\n            s[1 + rot_vertex] = rot; // rotation slots start at index 1\n        }\n        if (grab_vertex != -1) {\n            s[V + grab_vertex] = grab; // grab slots start at index V\n        }\n        ops.push_back(s);\n    };\n\n    // process each pair\n    for (const auto& p : pairs) {\n        const Point& src = p.first;\n        const Point& dst = p.second;\n\n        // --- pickup ---\n        // find best neighbor for pickup\n        int best_pick_dist = INT_MAX;\n        int best_pick_rot_diff = INT_MAX;\n        Point best_pick_root;\n        int best_pick_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = src.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = src.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_pick_root = Point(nx, ny);\n                best_pick_dir = dir_from_root;\n            }\n        }\n        // move to best_pick_root\n        int px = best_pick_root.x, py = best_pick_root.y;\n        // generate moves\n        vector<char> moves;\n        while (rx != px) {\n            if (rx > px) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != py) {\n            if (ry > py) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        // execute moves, with rotations as needed\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: also rotate and grab\n                int steps = rot_steps(leaf_dir, best_pick_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_pick_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                } else { // steps == 2\n                    // first rotation in this move (no grab)\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4); // arbitrary direction\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and grab in next turn\n                    char rot2 = rot_char(leaf_dir, best_pick_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_pick_dir;\n                    leaf_holding = true;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // remove takoyaki from source\n        has_takoyaki[src.x][src.y] = false;\n\n        // --- drop ---\n        // find best neighbor for drop (must be empty target)\n        best_pick_dist = INT_MAX;\n        best_pick_rot_diff = INT_MAX;\n        Point best_drop_root;\n        int best_drop_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = dst.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = dst.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (target_filled[nx][ny]) continue; // cannot land on filled target\n            int dist = manhattan(Point(rx, ry), Point(nx, ny));\n            int dir_from_root = (d + 2) % 4; // opposite direction\n            int rot_diff = rot_steps(leaf_dir, dir_from_root);\n            if (dist < best_pick_dist || (dist == best_pick_dist && rot_diff < best_pick_rot_diff)) {\n                best_pick_dist = dist;\n                best_pick_rot_diff = rot_diff;\n                best_drop_root = Point(nx, ny);\n                best_drop_dir = dir_from_root;\n            }\n        }\n        // move to best_drop_root\n        int dx = best_drop_root.x, dy = best_drop_root.y;\n        moves.clear();\n        while (rx != dx) {\n            if (rx > dx) {\n                moves.push_back('U');\n                --rx;\n            } else {\n                moves.push_back('D');\n                ++rx;\n            }\n        }\n        while (ry != dy) {\n            if (ry > dy) {\n                moves.push_back('L');\n                --ry;\n            } else {\n                moves.push_back('R');\n                ++ry;\n            }\n        }\n        for (size_t i = 0; i < moves.size(); ++i) {\n            char move = moves[i];\n            if (i == moves.size() - 1) {\n                // last move: rotate and release\n                int steps = rot_steps(leaf_dir, best_drop_dir);\n                if (steps == 0) {\n                    add_turn(move, 1, '.', 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else if (steps == 1) {\n                    char rot = rot_char(leaf_dir, best_drop_dir);\n                    add_turn(move, 1, rot, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                } else { // steps == 2\n                    // first rotation\n                    char rot1 = rot_char(leaf_dir, (leaf_dir + 1) % 4);\n                    add_turn(move, 1, rot1, -1, '.');\n                    leaf_dir = (leaf_dir + 1) % 4;\n                    // second rotation and release\n                    char rot2 = rot_char(leaf_dir, best_drop_dir);\n                    add_turn('.', 1, rot2, 1, 'P');\n                    leaf_dir = best_drop_dir;\n                    leaf_holding = false;\n                }\n            } else {\n                add_turn(move, 1, '.', -1, '.');\n            }\n        }\n        // mark target filled\n        target_filled[dst.x][dst.y] = true;\n    }\n\n    // output operations\n    for (const string& s : ops) {\n        cout << s << '\\n';\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_PERIMETER = 400000;\nconst vector<int> GRID_SIZES = {500, 250, 125};  // add finer grid\n\nstruct Rectangle {\n    int left, right, top, bottom;\n    int net;\n    int x_min, x_max, y_min, y_max;\n\n    Rectangle() : net(0) {}\n    Rectangle(int l, int r, int t, int b, int net_val,\n              const vector<int>& x_start, const vector<int>& x_end,\n              const vector<int>& y_start, const vector<int>& y_end)\n        : left(l), right(r), top(t), bottom(b), net(net_val) {\n        x_min = x_start[left];\n        x_max = x_end[right];\n        y_min = y_start[top];\n        y_max = y_end[bottom];\n    }\n\n    int perimeter() const {\n        int width = x_max - x_min + 1;\n        int height = y_max - y_min + 1;\n        return 2 * (width + height);\n    }\n};\n\nRectangle find_best_rectangle(const vector<vector<int>>& net, int G) {\n    int rows = net.size();\n    int cols = net[0].size();\n\n    vector<int> x_start(cols), x_end(cols);\n    for (int j = 0; j < cols; ++j) {\n        x_start[j] = j * G;\n        x_end[j] = (j == cols - 1) ? MAX_COORD : (j + 1) * G - 1;\n    }\n    vector<int> y_start(rows), y_end(rows);\n    for (int i = 0; i < rows; ++i) {\n        y_start[i] = i * G;\n        y_end[i] = (i == rows - 1) ? MAX_COORD : (i + 1) * G - 1;\n    }\n\n    Rectangle best;\n    best.net = 0;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (net[i][j] == 0) {\n                best = Rectangle(j, j, i, i, 0, x_start, x_end, y_start, y_end);\n                break;\n            }\n        }\n        if (best.net == 0) break;\n    }\n\n    for (int top = 0; top < rows; ++top) {\n        vector<int> col_sum(cols, 0);\n        for (int bottom = top; bottom < rows; ++bottom) {\n            for (int c = 0; c < cols; ++c) {\n                col_sum[c] += net[bottom][c];\n            }\n            int cur = 0, best_cur = 0;\n            int start = 0, best_start = 0, best_end = -1;\n            for (int c = 0; c < cols; ++c) {\n                if (cur <= 0) {\n                    cur = col_sum[c];\n                    start = c;\n                } else {\n                    cur += col_sum[c];\n                }\n                if (cur > best_cur) {\n                    best_cur = cur;\n                    best_start = start;\n                    best_end = c;\n                }\n            }\n            if (best_end == -1) continue;\n\n            Rectangle candidate(best_start, best_end, top, bottom, best_cur,\n                                x_start, x_end, y_start, y_end);\n            if (candidate.perimeter() <= MAX_PERIMETER && candidate.net > best.net) {\n                best = candidate;\n            }\n        }\n    }\n    return best;\n}\n\nstruct RegionGrower {\n    int G, rows, cols;\n    const vector<vector<int>>& net;\n    vector<vector<bool>> in_region;\n    int perimeter, total_net;\n    vector<pair<int, int>> region_cells;\n\n    static const int dx[4];\n    static const int dy[4];\n\n    RegionGrower(int G, const vector<vector<int>>& net)\n        : G(G), net(net), rows(net.size()), cols(net[0].size()) {\n        in_region.assign(rows, vector<bool>(cols, false));\n        perimeter = 0;\n        total_net = 0;\n    }\n\n    void add_cell(int i, int j) {\n        in_region[i][j] = true;\n        region_cells.emplace_back(i, j);\n        total_net += net[i][j];\n        int neighbors = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                ++neighbors;\n        }\n        perimeter += 4 - 2 * neighbors;\n    }\n\n    void grow() {\n        // Find seed with maximum net\n        int best_i = -1, best_j = -1, best_val = -1e9;\n        for (int i = 0; i < rows; ++i) {\n            for (int j = 0; j < cols; ++j) {\n                if (net[i][j] > best_val) {\n                    best_val = net[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        if (best_val <= 0) return;\n        add_cell(best_i, best_j);\n\n        set<pair<int, int>> candidates;\n        for (int d = 0; d < 4; ++d) {\n            int ni = best_i + dx[d], nj = best_j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                candidates.insert({ni, nj});\n        }\n\n        while (!candidates.empty() && perimeter <= MAX_PERIMETER) {\n            double best_priority = -1e18;\n            pair<int, int> best_cand;\n            for (const auto& cand : candidates) {\n                int i = cand.first, j = cand.second;\n                // Only consider cells with non-negative net\n                if (net[i][j] < 0) continue;\n                int delta_net = net[i][j];\n                int neighbors = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                        ++neighbors;\n                }\n                int delta_perim = 4 - 2 * neighbors;\n                double priority;\n                if (delta_perim > 0)\n                    priority = delta_net / (double)delta_perim;\n                else\n                    priority = delta_net * 1000.0;  // strongly favor perimeter reduction\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_cand = cand;\n                }\n            }\n            if (best_priority <= 0) break;\n\n            int i = best_cand.first, j = best_cand.second;\n            candidates.erase(best_cand);\n\n            int neighbors = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                    ++neighbors;\n            }\n            int delta_perim = 4 - 2 * neighbors;\n            if (perimeter + delta_perim > MAX_PERIMETER)\n                continue;\n\n            add_cell(i, j);\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                    candidates.insert({ni, nj});\n            }\n        }\n    }\n};\n\nconst int RegionGrower::dx[4] = {1, -1, 0, 0};\nconst int RegionGrower::dy[4] = {0, 0, 1, -1};\n\nvector<pair<int, int>> trace_boundary(const vector<vector<bool>>& in_region, int G, int rows, int cols) {\n    map<pair<int, int>, vector<pair<int, int>>> graph;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (!in_region[i][j]) continue;\n            if (j == 0 || !in_region[i][j - 1]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, j * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (j == cols - 1 || !in_region[i][j + 1]) {\n                pair<int, int> p1 = {i * G, (j + 1) * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == 0 || !in_region[i - 1][j]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {i * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == rows - 1 || !in_region[i + 1][j]) {\n                pair<int, int> p1 = {(i + 1) * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n        }\n    }\n    if (graph.empty()) return {};\n\n    auto start = graph.begin()->first;\n    vector<pair<int, int>> cycle;\n    pair<int, int> cur = start;\n    pair<int, int> prev = {-1, -1};\n    do {\n        cycle.push_back(cur);\n        const auto& neighbors = graph[cur];\n        pair<int, int> next;\n        for (const auto& nb : neighbors) {\n            if (nb != prev) {\n                next = nb;\n                break;\n            }\n        }\n        prev = cur;\n        cur = next;\n    } while (cur != start);\n\n    // Simplify collinear points\n    vector<pair<int, int>> simplified;\n    int n = cycle.size();\n    for (int i = 0; i < n; ++i) {\n        auto prev = cycle[(i - 1 + n) % n];\n        auto cur = cycle[i];\n        auto next = cycle[(i + 1) % n];\n        if (prev.first == cur.first && cur.first == next.first) continue;\n        if (prev.second == cur.second && cur.second == next.second) continue;\n        simplified.push_back(cur);\n    }\n    return simplified;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) cin >> mackerels[i].first >> mackerels[i].second;\n    for (int i = 0; i < N; ++i) cin >> sardines[i].first >> sardines[i].second;\n\n    int best_net = 0;\n    vector<pair<int, int>> best_polygon;\n    bool found_nonempty = false;\n\n    for (int G : GRID_SIZES) {\n        int rows = (MAX_COORD + G) / G;\n        int cols = rows;\n\n        vector<vector<int>> count_m(rows, vector<int>(cols, 0));\n        vector<vector<int>> count_s(rows, vector<int>(cols, 0));\n\n        for (auto& p : mackerels) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_m[i][j];\n        }\n        for (auto& p : sardines) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_s[i][j];\n        }\n\n        vector<vector<int>> net(rows, vector<int>(cols));\n        for (int i = 0; i < rows; ++i)\n            for (int j = 0; j < cols; ++j)\n                net[i][j] = count_m[i][j] - count_s[i][j];\n\n        // Rectangle search\n        Rectangle rect = find_best_rectangle(net, G);\n        if (rect.net > best_net) {\n            best_net = rect.net;\n            best_polygon = {\n                {rect.x_min, rect.y_min},\n                {rect.x_max, rect.y_min},\n                {rect.x_max, rect.y_max},\n                {rect.x_min, rect.y_max}\n            };\n            found_nonempty = (best_net > 0);\n        }\n\n        // Region growing\n        RegionGrower grower(G, net);\n        grower.grow();\n        if (grower.total_net > best_net) {\n            best_net = grower.total_net;\n            best_polygon = trace_boundary(grower.in_region, G, rows, cols);\n            found_nonempty = (best_net > 0);\n        }\n    }\n\n    if (!found_nonempty) {\n        best_polygon = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};\n    }\n\n    cout << best_polygon.size() << \"\\n\";\n    for (auto& p : best_polygon) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <map>\n#include <set>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\n// Normal distribution with given mean and stddev, rounded to integer, clamped to [1,1e9]\nint normal_int(double mean, double stddev, mt19937& rng) {\n    normal_distribution<double> dist(mean, stddev);\n    double val = dist(rng);\n    int res = (int)round(val);\n    if (res < 1) res = 1;\n    if (res > 1000000000) res = 1000000000;\n    return res;\n}\n\n// Structure for a placement instruction\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference index or -1\n};\n\n// Simulation state: bounding boxes of placed rectangles\nstruct Rect {\n    double x1, y1, x2, y2;\n};\n\n// Check if two rectangles overlap (allowing touching)\nbool overlap(const Rect& a, const Rect& b) {\n    return (a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1);\n}\n\n// Simulate the placement sequence using estimated dimensions.\n// Returns true if valid (no overlap, all coordinates non-negative).\n// Also returns the bounding box (W, H).\nbool simulate(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est,\n              double& W, double& H, map<int, Rect>& boxes) {\n    boxes.clear();\n    W = 0.0;\n    H = 0.0;\n    set<int> placed;\n    for (const Placement& pl : seq) {\n        int id = pl.p;\n        double w, h;\n        if (pl.r == 0) {\n            w = w_est[id];\n            h = h_est[id];\n        } else {\n            w = h_est[id];\n            h = w_est[id];\n        }\n        Rect r;\n        if (pl.d == 'U') {\n            if (pl.b == -1) {\n                r.x1 = 0.0;\n                r.y1 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x1 = ref.x2;\n                r.y1 = ref.y2;\n            }\n            r.x2 = r.x1 + w;\n            r.y2 = r.y1 + h;\n        } else if (pl.d == 'L') {\n            if (pl.b == -1) {\n                r.x2 = 0.0;\n                r.y2 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x2 = ref.x1;\n                r.y2 = ref.y1;\n            }\n            r.x1 = r.x2 - w;\n            r.y1 = r.y2 - h;\n        } else {\n            return false; // invalid direction\n        }\n        // Check bounds\n        if (r.x1 < 0.0 || r.y1 < 0.0) return false;\n        // Check overlap with existing rectangles\n        for (const auto& kv : boxes) {\n            if (overlap(r, kv.second)) return false;\n        }\n        boxes[id] = r;\n        placed.insert(id);\n        W = max(W, r.x2);\n        H = max(H, r.y2);\n    }\n    return true;\n}\n\n// Compute estimated score for a sequence\ndouble estimated_score(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est) {\n    map<int, Rect> boxes;\n    double W, H;\n    if (!simulate(seq, w_est, h_est, W, H, boxes)) {\n        return 1e30; // invalid\n    }\n    set<int> placed;\n    for (const Placement& pl : seq) placed.insert(pl.p);\n    double penalty = 0.0;\n    for (size_t i = 0; i < w_est.size(); ++i) {\n        if (placed.count(i) == 0) {\n            penalty += w_est[i] + h_est[i];\n        }\n    }\n    return W + H + penalty;\n}\n\n// Greedy packing based on estimated dimensions.\n// Returns a placement sequence.\nvector<Placement> greedy_packing(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, bool randomize = true) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Try all options for rectangle i\n        struct Option {\n            double delta; // increase in W+H\n            Placement pl;\n        };\n        vector<Option> options;\n\n        for (int rot = 0; rot < 2; ++rot) {\n            for (char dir : {'U', 'L'}) {\n                // Try all possible references: -1 and all placed indices\n                vector<int> refs = {-1};\n                for (int idx : placed) refs.push_back(idx);\n                for (int b : refs) {\n                    // Skip invalid combinations: L with b=-1 leads to negative coordinates\n                    if (dir == 'L' && b == -1) {\n                        continue;\n                    }\n                    Placement pl{ i, rot, dir, b };\n                    // Simulate with this new rectangle appended\n                    vector<Placement> test_seq = seq;\n                    test_seq.push_back(pl);\n                    map<int, Rect> test_boxes;\n                    double newW, newH;\n                    if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                        double delta = (newW + newH) - (curW + curH);\n                        options.push_back({ delta, pl });\n                    }\n                }\n            }\n        }\n        // Consider skipping\n        double skip_penalty = w_est[i] + h_est[i]; // estimated penalty if skipped\n\n        if (options.empty()) {\n            // must skip\n            continue;\n        }\n        // Find option with minimum delta\n        double best_delta = 1e30;\n        for (const auto& opt : options) {\n            if (opt.delta < best_delta) best_delta = opt.delta;\n        }\n        // Collect all options with delta close to best (within 1e-6) to randomize\n        vector<Option> best_options;\n        for (const auto& opt : options) {\n            if (abs(opt.delta - best_delta) < 1e-6) best_options.push_back(opt);\n        }\n        // Choose one randomly if randomize, otherwise the first\n        Option chosen = best_options[0];\n        if (randomize && best_options.size() > 1) {\n            uniform_int_distribution<int> dist(0, best_options.size() - 1);\n            chosen = best_options[dist(rng)];\n        }\n        // Decide to place or skip based on greedy criterion\n        if (best_delta < skip_penalty) {\n            // Place it\n            seq.push_back(chosen.pl);\n            // Update current state by re-simulating from scratch (could be optimized but N is small)\n            simulate(seq, w_est, h_est, curW, curH, current_boxes);\n            placed.insert(i);\n        }\n        // else skip\n    }\n    return seq;\n}\n\n// Generate a random valid sequence\nvector<Placement> random_valid_sequence(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Decide whether to place this rectangle (probability 0.8)\n        if (uniform_real_distribution<double>(0,1)(rng) > 0.8) continue;\n        // Try to place with random parameters\n        bool placed_ok = false;\n        for (int attempt = 0; attempt < 10; ++attempt) {\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_real_distribution<double>(0,1)(rng) < 0.5) ? 'U' : 'L';\n            vector<int> refs = {-1};\n            for (int idx : placed) refs.push_back(idx);\n            int b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n            if (dir == 'L' && b == -1) continue; // invalid\n            Placement pl{i, rot, dir, b};\n            vector<Placement> test_seq = seq;\n            test_seq.push_back(pl);\n            map<int, Rect> test_boxes;\n            double newW, newH;\n            if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                // Valid\n                seq.push_back(pl);\n                current_boxes = test_boxes;\n                curW = newW;\n                curH = newH;\n                placed.insert(i);\n                placed_ok = true;\n                break;\n            }\n        }\n        // if not placed after attempts, skip\n    }\n    return seq;\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    vector<int> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Initialize measurement accumulators with the initial observations as one measurement each\n    vector<double> w_meas_sum(N), h_meas_sum(N);\n    vector<int> cnt_w(N, 1), cnt_h(N, 1);\n    for (int i = 0; i < N; ++i) {\n        w_meas_sum[i] = w_obs[i];\n        h_meas_sum[i] = h_obs[i];\n    }\n    // Current estimates\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = w_meas_sum[i] / cnt_w[i];\n        h_est[i] = h_meas_sum[i] / cnt_h[i];\n    }\n\n    // Determine number of measurement attempts\n    int M;\n    if (T >= 2 * N) {\n        M = 2 * N; // we will do 2N measurements (each rectangle measured twice)\n    } else if (T >= N) {\n        M = N; // each rectangle measured once\n    } else {\n        M = T / 2; // half for measurement, half for packing\n    }\n    int measurement_done = 0;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Placement> best_est_seq; // best sequence by estimated score\n    double best_est_score = 1e30;\n    vector<Placement> best_actual_seq; // best sequence by actual score\n    double best_actual_score = 1e30;\n\n    for (int t = 0; t < T; ++t) {\n        // Decide whether to do a measurement attempt\n        if (measurement_done < M) {\n            // Choose a random rectangle to measure\n            int i = uniform_int_distribution<int>(0, N-1)(rng);\n            int r = uniform_int_distribution<int>(0,1)(rng);\n            // Output single rectangle placement\n            cout << 1 << '\\n';\n            cout << i << ' ' << r << ' ' << 'U' << ' ' << -1 << '\\n';\n            cout.flush();\n\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n\n            // Update measurements\n            if (r == 0) {\n                w_meas_sum[i] += W_meas;\n                h_meas_sum[i] += H_meas;\n            } else {\n                w_meas_sum[i] += H_meas;\n                h_meas_sum[i] += W_meas;\n            }\n            cnt_w[i]++;\n            cnt_h[i]++;\n            w_est[i] = w_meas_sum[i] / cnt_w[i];\n            h_est[i] = h_meas_sum[i] / cnt_h[i];\n\n            measurement_done++;\n            // No need to compute score for measurement attempts (they are poor)\n            continue;\n        }\n\n        // Packing attempt\n        vector<Placement> cur_seq;\n        // With probability 0.3, generate a new random sequence; else use best_est_seq or generate greedy\n        if (uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n            // Generate a random sequence\n            cur_seq = random_valid_sequence(w_est, h_est, rng);\n        } else if (!best_est_seq.empty() && uniform_real_distribution<double>(0,1)(rng) < 0.7) {\n            // Use the current best estimated sequence (maybe with small mutation? we skip mutation for simplicity)\n            cur_seq = best_est_seq;\n        } else {\n            // Generate a greedy packing with perturbed estimates\n            vector<double> pert_w = w_est, pert_h = h_est;\n            normal_distribution<double> noise(0.0, sigma * 0.5);\n            for (int i = 0; i < N; ++i) {\n                pert_w[i] += noise(rng);\n                pert_h[i] += noise(rng);\n                if (pert_w[i] < 1.0) pert_w[i] = 1.0;\n                if (pert_h[i] < 1.0) pert_h[i] = 1.0;\n            }\n            cur_seq = greedy_packing(pert_w, pert_h, rng, true);\n        }\n\n        // Ensure sequence is valid under current estimates; if not, fallback to greedy\n        {\n            map<int, Rect> dummy_boxes;\n            double dummyW, dummyH;\n            if (!simulate(cur_seq, w_est, h_est, dummyW, dummyH, dummy_boxes)) {\n                cur_seq = greedy_packing(w_est, h_est, rng, true);\n            }\n        }\n\n        // Compute estimated score for this sequence\n        double est_score = estimated_score(cur_seq, w_est, h_est);\n        if (est_score < best_est_score) {\n            best_est_score = est_score;\n            best_est_seq = cur_seq;\n        }\n\n        // Decide which sequence to output\n        vector<Placement> output_seq;\n        if (t % 5 == 0 && !best_actual_seq.empty()) {\n            // Occasionally output the best actual sequence found so far\n            output_seq = best_actual_seq;\n        } else {\n            // Otherwise output the current sequence (or best estimated? we output cur_seq for exploration)\n            output_seq = cur_seq;\n        }\n\n        // Output the sequence\n        cout << output_seq.size() << '\\n';\n        for (const Placement& pl : output_seq) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout.flush();\n\n        // Read measurement\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n\n        // Compute actual score\n        set<int> placed_ids;\n        for (const Placement& pl : output_seq) placed_ids.insert(pl.p);\n        double penalty = 0.0;\n        for (int i = 0; i < N; ++i) {\n            if (placed_ids.count(i) == 0) {\n                penalty += w_est[i] + h_est[i];\n            }\n        }\n        double score = W_meas + H_meas + penalty;\n\n        // Update best actual\n        if (score < best_actual_score) {\n            best_actual_score = score;\n            best_actual_seq = output_seq;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // All-pairs shortest distances (BFS from each vertex)\n    vector<vector<short>> dist(N, vector<short>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        queue<int> q;\n        dist[s][s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // cover[v] = bitset of vertices within distance H from v\n    vector<bitset<MAXN>> cover(N);\n    for (int v = 0; v < N; ++v) {\n        for (int u = 0; u < N; ++u) {\n            if (dist[v][u] != -1 && dist[v][u] <= H) {\n                cover[v].set(u);\n            }\n        }\n    }\n\n    // Greedy weighted set cover to select roots (minimize sum of A of roots)\n    bitset<MAXN> uncovered;\n    uncovered.set();\n    vector<int> roots;\n    while (uncovered.any()) {\n        int best = -1;\n        double best_ratio = 1e18;\n        for (int v = 0; v < N; ++v) {\n            bitset<MAXN> cur = cover[v] & uncovered;\n            if (cur.none()) continue;\n            int gain = cur.count();\n            double ratio = (double)A[v] / gain;\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best = v;\n            }\n        }\n        if (best == -1) break;   // should never happen\n        roots.push_back(best);\n        uncovered &= ~cover[best];\n    }\n\n    // Assign each vertex to the nearest root (break ties arbitrarily)\n    vector<int> root_of(N, -1);\n    vector<int> dist_to_root(N, 1000);\n    for (int v = 0; v < N; ++v) {\n        int best_r = -1, best_d = 1000;\n        for (int r : roots) {\n            int d = dist[v][r];\n            if (d < best_d) {\n                best_d = d;\n                best_r = r;\n            }\n        }\n        root_of[v] = best_r;\n        dist_to_root[v] = best_d;\n    }\n\n    // Build the parent array (forest)\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (root_of[v] == v) {\n            parent[v] = -1;\n            continue;\n        }\n        int r = root_of[v];\n        int d = dist_to_root[v];\n        bool found = false;\n        for (int u : adj[v]) {\n            if (root_of[u] == r && dist[u][r] == d - 1) {\n                parent[v] = u;\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            // Fallback: any neighbor with same root and smaller distance\n            for (int u : adj[v]) {\n                if (root_of[u] == r && dist[u][r] < d) {\n                    parent[v] = u;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i];\n        if (i < N - 1) cout << ' ';\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<pair<char, int>> moves;\n\n    // Helper functions to perform a single shift and record the move\n    auto shiftRowLeft = [&](int i) {\n        char removed = board[i][0]; // not used\n        for (int j = 0; j < N - 1; ++j) {\n            board[i][j] = board[i][j + 1];\n        }\n        board[i][N - 1] = '.';\n        moves.push_back({'L', i});\n    };\n\n    auto shiftRowRight = [&](int i) {\n        char removed = board[i][N - 1];\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n        moves.push_back({'R', i});\n    };\n\n    auto shiftColUp = [&](int j) {\n        char removed = board[0][j];\n        for (int i = 0; i < N - 1; ++i) {\n            board[i][j] = board[i + 1][j];\n        }\n        board[N - 1][j] = '.';\n        moves.push_back({'U', j});\n    };\n\n    auto shiftColDown = [&](int j) {\n        char removed = board[N - 1][j];\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n        moves.push_back({'D', j});\n    };\n\n    while (true) {\n        // Collect all current Oni positions\n        vector<pair<int, int>> oniList;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    oniList.emplace_back(i, j);\n                }\n            }\n        }\n        if (oniList.empty()) {\n            break;\n        }\n\n        // Find the best Oni and direction to remove with best ratio of removed Oni per shift\n        int bestIdx = -1;\n        char bestDir = ' ';\n        double bestScore = -1.0;\n\n        for (size_t idx = 0; idx < oniList.size(); ++idx) {\n            auto [i, j] = oniList[idx];\n\n            // Check safety in each direction\n            bool safeUp = true;\n            for (int r = 0; r < i; ++r) {\n                if (board[r][j] == 'o') safeUp = false;\n            }\n            bool safeDown = true;\n            for (int r = i + 1; r < N; ++r) {\n                if (board[r][j] == 'o') safeDown = false;\n            }\n            bool safeLeft = true;\n            for (int c = 0; c < j; ++c) {\n                if (board[i][c] == 'o') safeLeft = false;\n            }\n            bool safeRight = true;\n            for (int c = j + 1; c < N; ++c) {\n                if (board[i][c] == 'o') safeRight = false;\n            }\n\n            // Evaluate each safe direction\n            if (safeUp) {\n                int shifts = i + 1;\n                int removed = 0;\n                for (int r = 0; r <= i; ++r) {\n                    if (board[r][j] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'U';\n                }\n            }\n            if (safeDown) {\n                int shifts = N - i;\n                int removed = 0;\n                for (int r = i; r < N; ++r) {\n                    if (board[r][j] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'D';\n                }\n            }\n            if (safeLeft) {\n                int shifts = j + 1;\n                int removed = 0;\n                for (int c = 0; c <= j; ++c) {\n                    if (board[i][c] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'L';\n                }\n            }\n            if (safeRight) {\n                int shifts = N - j;\n                int removed = 0;\n                for (int c = j; c < N; ++c) {\n                    if (board[i][c] == 'x') removed++;\n                }\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'R';\n                }\n            }\n        }\n\n        // According to the problem guarantee, there should always be a safe direction.\n        if (bestIdx == -1) {\n            break;\n        }\n\n        auto [i, j] = oniList[bestIdx];\n\n        // Perform the shifts in the chosen direction\n        if (bestDir == 'U') {\n            for (int k = 0; k < i + 1; ++k) {\n                shiftColUp(j);\n            }\n        } else if (bestDir == 'D') {\n            for (int k = 0; k < N - i; ++k) {\n                shiftColDown(j);\n            }\n        } else if (bestDir == 'L') {\n            for (int k = 0; k < j + 1; ++k) {\n                shiftRowLeft(i);\n            }\n        } else if (bestDir == 'R') {\n            for (int k = 0; k < N - j; ++k) {\n                shiftRowRight(i);\n            }\n        }\n    }\n\n    // Output the moves\n    for (auto [d, p] : moves) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Dinic's max flow\nstruct Edge {\n    int to, rev;\n    long long cap;\n};\n\nclass Dinic {\npublic:\n    vector<vector<Edge>> graph;\n    vector<int> level, iter;\n    Dinic(int n) : graph(n), level(n), iter(n) {}\n    void add_edge(int from, int to, long long cap) {\n        graph[from].push_back({to, (int)graph[to].size(), cap});\n        graph[to].push_back({from, (int)graph[from].size() - 1, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto& e : graph[v]) {\n                if (e.cap > 0 && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    long long dfs(int v, int t, long long f) {\n        if (v == t) return f;\n        for (int& i = iter[v]; i < (int)graph[v].size(); ++i) {\n            Edge& e = graph[v][i];\n            if (e.cap > 0 && level[v] < level[e.to]) {\n                long long d = dfs(e.to, t, min(f, e.cap));\n                if (d > 0) {\n                    e.cap -= d;\n                    graph[e.to][e.rev].cap += d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    long long max_flow(int s, int t) {\n        long long flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            long long f;\n            while ((f = dfs(s, t, 1e18)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\n// Simulation function that returns counts and error\npair<vector<int>, long long> simulate(const vector<int>& a, const vector<int>& b, const vector<long long>& T, int N, long long L) {\n    vector<int> cnt(N, 0);\n    int current = 0;\n    cnt[current] = 1;\n    for (long long week = 2; week <= L; ++week) {\n        if (cnt[current] % 2 == 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        cnt[current]++;\n    }\n    long long error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(cnt[i] - T[i]);\n    }\n    return {cnt, error};\n}\n\nint main() {\n    const int N = 100;\n    const long long L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Build flow network\n    int source = 0;\n    int left_start = 1;                     // 1 .. 200\n    int right_start = left_start + 2 * N;   // 201 .. 300\n    int sink = right_start + N;             // 301\n    Dinic dinic(sink + 1);\n\n    // Source to left nodes (two per employee)\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n        dinic.add_edge(source, node1, T[i]);\n        dinic.add_edge(source, node2, T[i]);\n    }\n\n    // Right nodes to sink\n    for (int j = 0; j < N; ++j) {\n        int node = right_start + j;\n        dinic.add_edge(node, sink, 2 * T[j]);\n    }\n\n    // Left nodes to right nodes (infinite capacity)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node1 = left_start + 2 * i;\n            int node2 = left_start + 2 * i + 1;\n            int right_node = right_start + j;\n            dinic.add_edge(node1, right_node, L);\n            dinic.add_edge(node2, right_node, L);\n        }\n    }\n\n    // Compute max flow\n    long long flow = dinic.max_flow(source, sink);\n\n    // Extract a[i] and b[i] by rounding to the dominant assignment\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n\n        // Find best j for node1\n        long long max_fl1 = -1;\n        int best_j1 = 0;\n        for (auto& e : dinic.graph[node1]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl1) {\n                    max_fl1 = fl;\n                    best_j1 = e.to - right_start;\n                }\n            }\n        }\n        a[i] = best_j1;\n\n        // Find best j for node2\n        long long max_fl2 = -1;\n        int best_j2 = 0;\n        for (auto& e : dinic.graph[node2]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl2) {\n                    max_fl2 = fl;\n                    best_j2 = e.to - right_start;\n                }\n            }\n        }\n        b[i] = best_j2;\n    }\n\n    // Compute initial counts and error\n    auto [cnt, best_error] = simulate(a, b, T, N, L);\n    vector<int> best_a = a, best_b = b;\n    vector<long long> err(N);\n    for (int i = 0; i < N; ++i) {\n        err[i] = cnt[i] - T[i];\n    }\n\n    // Local search with biased perturbations\n    const int max_iter = 2000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < max_iter; ++iter) {\n        // Randomly choose an employee i\n        int i = rng() % N;\n        // Randomly choose whether to change a[i] or b[i]\n        bool change_a = (rng() % 2 == 0);\n        // Generate new value with bias if err[i] > 0\n        int new_val;\n        if (err[i] > 0) {\n            // Collect under-visited employees\n            vector<int> candidates;\n            for (int j = 0; j < N; ++j) {\n                if (err[j] < 0) candidates.push_back(j);\n            }\n            if (!candidates.empty()) {\n                new_val = candidates[rng() % candidates.size()];\n            } else {\n                new_val = rng() % N;\n            }\n        } else {\n            new_val = rng() % N;\n        }\n        // Store old value\n        int old_val = change_a ? best_a[i] : best_b[i];\n        // Temporarily change\n        if (change_a) {\n            a[i] = new_val;\n        } else {\n            b[i] = new_val;\n        }\n        // Simulate\n        auto [new_cnt, new_error] = simulate(a, b, T, N, L);\n        // If improved, update best and error vector; otherwise revert\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a[i] = change_a ? new_val : best_a[i];\n            best_b[i] = change_a ? best_b[i] : new_val;\n            // Update error vector\n            for (int j = 0; j < N; ++j) {\n                err[j] = new_cnt[j] - T[j];\n            }\n        } else {\n            // revert\n            if (change_a) {\n                a[i] = old_val;\n            } else {\n                b[i] = old_val;\n            }\n        }\n    }\n\n    // Output the best solution\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\nusing pii = pair<int, int>;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\n\nvector<vector<int>> groups;\nvector<vector<pii>> group_edges;\n\n// Fortune\u2011telling query\nvector<pii> query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    vector<pii> edges;\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\n// Hilbert curve index for integer coordinates (14\u2011bit precision)\nuint64_t hilbertOrder(int x, int y) {\n    int pow = 14;\n    uint64_t d = 0;\n    int s = 1 << (pow - 1);\n    for (int i = pow - 1; i >= 0; --i) {\n        int rx = (x & s) ? 1 : 0;\n        int ry = (y & s) ? 1 : 0;\n        d = (d << 2) | ((rx * 3) ^ ry);\n        if (!ry) {\n            if (rx) {\n                x = (1 << pow) - 1 - x;\n                y = (1 << pow) - 1 - y;\n            }\n            swap(x, y);\n        }\n        s >>= 1;\n    }\n    return d;\n}\n\n// Approximate MST order for a group using Euclidean distances between centers\nvector<int> approximateMSTorder(const vector<int>& group) {\n    int n = group.size();\n    vector<double> dist(n, 1e18);\n    vector<bool> visited(n, false);\n    vector<int> parent(n, -1);\n    dist[0] = 0;\n    for (int i = 0; i < n; ++i) {\n        int u = -1;\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v] && (u == -1 || dist[v] < dist[u]))\n                u = v;\n        }\n        visited[u] = true;\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v]) {\n                double dx = cx[group[u]] - cx[group[v]];\n                double dy = cy[group[u]] - cy[group[v]];\n                double d = sqrt(dx*dx + dy*dy);\n                if (d < dist[v]) {\n                    dist[v] = d;\n                    parent[v] = u;\n                }\n            }\n        }\n    }\n    // Build adjacency list of the MST\n    vector<vector<int>> adj(n);\n    for (int i = 1; i < n; ++i) {\n        int u = i, v = parent[i];\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // DFS traversal to obtain a linear order\n    vector<int> order;\n    function<void(int,int)> dfs = [&](int u, int p) {\n        order.push_back(group[u]);\n        for (int v : adj[u]) {\n            if (v != p)\n                dfs(v, u);\n        }\n    };\n    dfs(0, -1);\n    return order;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Global ordering by Hilbert curve index\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n    });\n\n    // Partition into groups according to G\n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n\n    int total_queries = 0;\n    for (int i = 0; i < M; ++i) {\n        int s = groups[i].size();\n        if (s == 1) continue;\n        if (s <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n            ++total_queries;\n        } else {\n            // Reorder cities within the group using approximate MST order\n            vector<int> reordered = approximateMSTorder(groups[i]);\n            int start = 0;\n            while (start < s) {\n                int end = min(start + L, s);\n                int window_size = end - start;\n                if (window_size >= 2) {\n                    vector<int> window(reordered.begin() + start, reordered.begin() + end);\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                    ++total_queries;\n                }\n                start += L - 1;  // overlap by exactly one city\n            }\n        }\n        if (total_queries > Q) break;  // safety, should not happen\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // City list of the group (using the original grouping order for output)\n        for (size_t j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> points(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n\n    pair<int, int> cur = points[0];\n    vector<pair<int, int>> targets(points.begin() + 1, points.end());\n    vector<string> actions;\n\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n    const string dir_name[4] = {\"D\", \"U\", \"R\", \"L\"};\n\n    for (size_t k = 0; k < targets.size(); ++k) {\n        auto [ti, tj] = targets[k];\n\n        // Build blocked cells: future targets (index > k)\n        vector<vector<bool>> blocked_future(N, vector<bool>(N, false));\n        for (size_t i = k + 1; i < targets.size(); ++i) {\n            int x = targets[i].first, y = targets[i].second;\n            blocked_future[x][y] = true;\n        }\n\n        // Case 1: already aligned and target on boundary -> direct slide\n        if (cur.first == ti) {\n            if (tj == 0) {\n                actions.push_back(\"S L\");\n                cur.second = tj;\n                continue;\n            } else if (tj == N - 1) {\n                actions.push_back(\"S R\");\n                cur.second = tj;\n                continue;\n            }\n        } else if (cur.second == tj) {\n            if (ti == 0) {\n                actions.push_back(\"S U\");\n                cur.first = ti;\n                continue;\n            } else if (ti == N - 1) {\n                actions.push_back(\"S D\");\n                cur.first = ti;\n                continue;\n            }\n        }\n\n        // Case 2: target on a boundary, try align-then-slide if straight path clear\n        bool used_align_slide = false;\n        if (ti == 0 || ti == N-1 || tj == 0 || tj == N-1) {\n            // Target on top/bottom boundary: move horizontally to column tj, then slide vertically\n            if (ti == 0 || ti == N-1) {\n                // Check horizontal segment from (cur.first, cur.second) to (cur.first, tj)\n                bool clear = true;\n                if (cur.second != tj) {\n                    int step = (cur.second < tj) ? 1 : -1;\n                    for (int j = cur.second; j != tj; j += step) {\n                        if (blocked_future[cur.first][j]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                // Also ensure the destination cell (cur.first, tj) is not a future target\n                if (clear && blocked_future[cur.first][tj]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform horizontal moves\n                    if (cur.second < tj) {\n                        for (int j = cur.second; j < tj; ++j) actions.push_back(\"M R\");\n                    } else if (cur.second > tj) {\n                        for (int j = cur.second; j > tj; --j) actions.push_back(\"M L\");\n                    }\n                    cur.second = tj;\n                    // Perform slide\n                    if (ti == 0) {\n                        actions.push_back(\"S U\");\n                        cur.first = ti;\n                    } else {\n                        actions.push_back(\"S D\");\n                        cur.first = ti;\n                    }\n                    used_align_slide = true;\n                }\n            }\n            // If not used, try the other orientation if target on left/right boundary\n            if (!used_align_slide && (tj == 0 || tj == N-1)) {\n                // Move vertically to row ti, then slide horizontally\n                bool clear = true;\n                if (cur.first != ti) {\n                    int step = (cur.first < ti) ? 1 : -1;\n                    for (int i = cur.first; i != ti; i += step) {\n                        if (blocked_future[i][cur.second]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                if (clear && blocked_future[ti][cur.second]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform vertical moves\n                    if (cur.first < ti) {\n                        for (int i = cur.first; i < ti; ++i) actions.push_back(\"M D\");\n                    } else if (cur.first > ti) {\n                        for (int i = cur.first; i > ti; --i) actions.push_back(\"M U\");\n                    }\n                    cur.first = ti;\n                    // Perform slide\n                    if (tj == 0) {\n                        actions.push_back(\"S L\");\n                        cur.second = tj;\n                    } else {\n                        actions.push_back(\"S R\");\n                        cur.second = tj;\n                    }\n                    used_align_slide = true;\n                }\n            }\n        }\n        if (used_align_slide) {\n            continue;\n        }\n\n        // Case 3: fallback to BFS with moves and slides\n        vector<vector<int>> prev_x(N, vector<int>(N, -1));\n        vector<vector<int>> prev_y(N, vector<int>(N, -1));\n        vector<vector<int>> prev_dir(N, vector<int>(N, -1)); // 0-3: move, 4-7: slide\n        queue<pair<int, int>> q;\n        q.push(cur);\n        prev_x[cur.first][cur.second] = cur.first;\n        prev_y[cur.first][cur.second] = cur.second;\n\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            if (x == ti && y == tj) break;\n\n            // Move actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                if (blocked_future[nx][ny]) continue;\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = d; // 0-3 for moves\n                q.push({nx, ny});\n            }\n\n            // Slide actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x, ny = y;\n                // Simulate slide\n                while (true) {\n                    int next_x = nx + dx[d];\n                    int next_y = ny + dy[d];\n                    if (next_x < 0 || next_x >= N || next_y < 0 || next_y >= N) break;\n                    // If next cell is a future target, we can still move into it (since it's not a block),\n                    // but we must not end on it. We'll continue moving.\n                    // However, we cannot move into a cell that is a block. Since we have no blocks,\n                    // we just move.\n                    nx = next_x;\n                    ny = next_y;\n                }\n                // Now (nx, ny) is the final cell after sliding.\n                if (nx == x && ny == y) continue; // no movement\n                if (blocked_future[nx][ny]) continue; // cannot end on future target\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = 4 + d; // 4-7 for slides\n                q.push({nx, ny});\n            }\n        }\n\n        // Reconstruct path\n        vector<string> path_actions;\n        int x = ti, y = tj;\n        while (x != cur.first || y != cur.second) {\n            int dir = prev_dir[x][y];\n            int px = prev_x[x][y];\n            int py = prev_y[x][y];\n            if (dir < 4) {\n                // move action\n                path_actions.push_back(\"M \" + dir_name[dir]);\n            } else {\n                // slide action\n                path_actions.push_back(\"S \" + dir_name[dir - 4]);\n            }\n            x = px;\n            y = py;\n        }\n        reverse(path_actions.begin(), path_actions.end());\n\n        for (const string& a : path_actions) {\n            actions.push_back(a);\n        }\n\n        cur = {ti, tj};\n    }\n\n    // Output actions\n    for (const string& a : actions) {\n        cout << a << \"\\n\";\n    }\n\n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <climits>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r, idx;\n};\n\nvector<Company> companies;\nvector<int> a, b, c, d;\n\n// assign a rectangle to a single company within given rect\nvoid assign_single(int i, int rect_l, int rect_b, int rect_r, int rect_t) {\n    long long r = companies[i].r;\n    int x = companies[i].x;\n    int y = companies[i].y;\n    int w_max = rect_r - rect_l;\n    int h_max = rect_t - rect_b;\n    double best_sat = -1.0;\n    int best_a = 0, best_b = 0, best_c = 0, best_d = 0;\n\n    // try all possible widths\n    for (int w = 1; w <= w_max; ++w) {\n        int h = (r + w / 2) / w; // round(r/w)\n        if (h > h_max) h = h_max;\n        if (h < 1) h = 1;\n        long long s = w * (long long)h;\n        double ratio = min(r, s) / (double)max(r, s);\n        double sat = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n\n        // check if placement is possible\n        int a_min = max(rect_l, x - w + 1);\n        int a_max = min(x, rect_r - w);\n        if (a_min > a_max) continue;\n        int b_min = max(rect_b, y - h + 1);\n        int b_max = min(y, rect_t - h);\n        if (b_min > b_max) continue;\n\n        int a = a_min;\n        int b = b_min;\n        if (sat > best_sat) {\n            best_sat = sat;\n            best_a = a;\n            best_b = b;\n            best_c = a + w;\n            best_d = b + h;\n        }\n    }\n\n    // assign the best found rectangle\n    a[companies[i].idx] = best_a;\n    b[companies[i].idx] = best_b;\n    c[companies[i].idx] = best_c;\n    d[companies[i].idx] = best_d;\n}\n\n// fallback: column packing within given rect\nvoid fallback_column_packing(int rect_l, int rect_b, int rect_r, int rect_t,\n                             vector<int> indices) {\n    if (indices.empty()) return;\n\n    // sort indices by x coordinate\n    sort(indices.begin(), indices.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    int n = indices.size();\n    vector<int> w(n);\n    long long cur_start = rect_l;\n\n    // initial widths\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        long long w_min_cov = max(1LL, (long long)companies[i].x - cur_start + 1);\n        long long w_min_area = (companies[i].r + 9999) / 10000;\n        w[k] = max(w_min_cov, w_min_area);\n        cur_start += w[k];\n    }\n\n    long long total_width = cur_start - rect_l;\n    long long avail_width = rect_r - rect_l;\n    long long excess = total_width - avail_width;\n\n    // precompute satisfaction for each possible width (1..10000) for each company\n    vector<vector<double>> sat(n, vector<double>(10001, 0.0));\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        long long ri = companies[i].r;\n        for (int width = 1; width <= 10000; ++width) {\n            int h = (ri + width / 2) / width;\n            if (h > 10000) h = 10000;\n            if (h < 1) h = 1;\n            long long s = width * (long long)h;\n            double ratio = min(ri, s) / (double)max(ri, s);\n            sat[k][width] = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        }\n    }\n\n    // reduce widths if total exceeds available width\n    while (excess > 0) {\n        // recompute current starts\n        vector<long long> start_pos(n);\n        cur_start = rect_l;\n        for (int k = 0; k < n; ++k) {\n            start_pos[k] = cur_start;\n            cur_start += w[k];\n        }\n\n        int best_k = -1;\n        double best_loss = 1e18;\n        for (int k = 0; k < n; ++k) {\n            int i = indices[k];\n            long long w_min_cov = max(1LL, (long long)companies[i].x - start_pos[k] + 1);\n            if (w[k] <= w_min_cov) continue;\n            double p_curr = sat[k][w[k]];\n            double p_red = sat[k][w[k] - 1];\n            double loss = p_curr - p_red;\n            if (loss < best_loss) {\n                best_loss = loss;\n                best_k = k;\n            }\n        }\n        if (best_k == -1) break;\n        w[best_k]--;\n        excess--;\n    }\n\n    // assign rectangles\n    cur_start = rect_l;\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        int wi = w[k];\n        long long ri = companies[i].r;\n        int h = (ri + wi / 2) / wi;\n        if (h > 10000) h = 10000;\n        if (h < 1) h = 1;\n\n        int ai = cur_start;\n        int ci = ai + wi;\n        int bi = max(rect_b, companies[i].y - h + 1);\n        int di = bi + h;\n        // ensure within rect vertically\n        if (bi < rect_b) bi = rect_b;\n        if (di > rect_t) {\n            di = rect_t;\n            bi = di - h;\n        }\n\n        a[companies[i].idx] = ai;\n        b[companies[i].idx] = bi;\n        c[companies[i].idx] = ci;\n        d[companies[i].idx] = di;\n\n        cur_start += wi;\n    }\n}\n\n// recursive splitting\nvoid solve(int rect_l, int rect_b, int rect_r, int rect_t, vector<int> indices) {\n    if (indices.empty()) return;\n    if (indices.size() == 1) {\n        assign_single(indices[0], rect_l, rect_b, rect_r, rect_t);\n        return;\n    }\n\n    // try vertical split\n    bool vertical_ok = false;\n    int best_s = -1;\n    double best_error = 1e18;\n    vector<int> best_left, best_right;\n\n    // sort indices by x\n    vector<int> sorted_idx = indices;\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> left(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> right(sorted_idx.begin() + k, sorted_idx.end());\n        int max_x_left = companies[left.back()].x;\n        int min_x_right = companies[right.front()].x;\n        if (max_x_left + 1 > min_x_right) continue;\n\n        long long sum_left = 0, sum_right = 0;\n        for (int i : left) sum_left += companies[i].r;\n        for (int i : right) sum_right += companies[i].r;\n        long long height = rect_t - rect_b;\n        double s_ideal = (double)sum_left / height;\n        int s_low = max_x_left + 1;\n        int s_high = min_x_right;\n        int s = max(s_low, min(s_high, (int)round(s_ideal)));\n        double error = abs(sum_left - s * height) + abs(sum_right - (rect_r - s) * height);\n        if (error < best_error) {\n            best_error = error;\n            best_s = s;\n            best_left = left;\n            best_right = right;\n            vertical_ok = true;\n        }\n    }\n\n    if (vertical_ok) {\n        solve(rect_l, rect_b, best_s, rect_t, best_left);\n        solve(best_s, rect_b, rect_r, rect_t, best_right);\n        return;\n    }\n\n    // try horizontal split\n    bool horizontal_ok = false;\n    int best_t = -1;\n    double best_error_h = 1e18;\n    vector<int> best_bottom, best_top;\n\n    // sort indices by y\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].y < companies[j].y; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> bottom(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> top(sorted_idx.begin() + k, sorted_idx.end());\n        int max_y_bottom = companies[bottom.back()].y;\n        int min_y_top = companies[top.front()].y;\n        if (max_y_bottom + 1 > min_y_top) continue;\n\n        long long sum_bottom = 0, sum_top = 0;\n        for (int i : bottom) sum_bottom += companies[i].r;\n        for (int i : top) sum_top += companies[i].r;\n        long long width = rect_r - rect_l;\n        double t_ideal = (double)sum_bottom / width;\n        int t_low = max_y_bottom + 1;\n        int t_high = min_y_top;\n        int t = max(t_low, min(t_high, (int)round(t_ideal)));\n        double error = abs(sum_bottom - t * width) + abs(sum_top - (rect_t - t) * width);\n        if (error < best_error_h) {\n            best_error_h = error;\n            best_t = t;\n            best_bottom = bottom;\n            best_top = top;\n            horizontal_ok = true;\n        }\n    }\n\n    if (horizontal_ok) {\n        solve(rect_l, rect_b, rect_r, best_t, best_bottom);\n        solve(rect_l, best_t, rect_r, rect_t, best_top);\n        return;\n    }\n\n    // no feasible split found, fallback to column packing for the whole region\n    fallback_column_packing(rect_l, rect_b, rect_r, rect_t, indices);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].idx = i;\n    }\n\n    a.resize(n);\n    b.resize(n);\n    c.resize(n);\n    d.resize(n);\n\n    vector<int> all_idx(n);\n    iota(all_idx.begin(), all_idx.end(), 0);\n\n    solve(0, 0, 10000, 10000, all_idx);\n\n    for (int i = 0; i < n; ++i) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <random>\n#include <tuple>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> tile(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tile[i][j];\n        }\n    }\n\n    vector<vector<int>> value(50, vector<int>(50));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> value[i][j];\n        }\n    }\n\n    // Find total number of tiles (M)\n    int M = 0;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            M = max(M, tile[i][j] + 1);\n        }\n    }\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n    // Timestamp technique to avoid resetting visited array each trial\n    vector<int> visited_tiles(M, 0);\n    int cur_timestamp = 0;\n\n    random_device rd;\n    mt19937 gen(rd());\n\n    string best_path = \"\";\n    int best_score = -1;\n\n    const int num_trials = 20000; // will be plus one greedy trial\n    for (int trial = 0; trial <= num_trials; ++trial) {\n        ++cur_timestamp;\n        int policy; // 0: uniform random, 1: weighted random, 2: greedy\n        if (trial == num_trials) {\n            policy = 2; // greedy at the end\n        } else {\n            policy = (gen() % 2); // 50% uniform, 50% weighted\n        }\n\n        int cur_r = si, cur_c = sj;\n        visited_tiles[tile[cur_r][cur_c]] = cur_timestamp;\n        int score = value[cur_r][cur_c];\n        string path = \"\";\n\n        while (true) {\n            // Collect unvisited neighbors\n            // Fixed: Changed to tuple with 5 elements to match emplace_back\n            vector<tuple<int, int, int, int, char>> candidates; // value, nr, nc, tid, dir\n            for (int d = 0; d < 4; ++d) {\n                int nr = cur_r + dr[d];\n                int nc = cur_c + dc[d];\n                if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n                int tid = tile[nr][nc];\n                if (visited_tiles[tid] == cur_timestamp) continue;\n                candidates.emplace_back(value[nr][nc], nr, nc, tid, dir_char[d]);\n            }\n            if (candidates.empty()) break;\n\n            int chosen_idx = 0;\n            if (policy == 2) {\n                // Greedy: choose the candidate with maximum value\n                for (int i = 1; i < (int)candidates.size(); ++i) {\n                    if (get<0>(candidates[i]) > get<0>(candidates[chosen_idx])) {\n                        chosen_idx = i;\n                    }\n                }\n            } else {\n                if (policy == 0) {\n                    // Uniform random\n                    chosen_idx = gen() % candidates.size();\n                } else {\n                    // Weighted random (weights = value)\n                    int total = 0;\n                    for (const auto& cand : candidates) {\n                        total += get<0>(cand);\n                    }\n                    if (total == 0) {\n                        chosen_idx = gen() % candidates.size();\n                    } else {\n                        int r = gen() % total;\n                        int cum = 0;\n                        for (int i = 0; i < (int)candidates.size(); ++i) {\n                            cum += get<0>(candidates[i]);\n                            if (cum > r) {\n                                chosen_idx = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Execute the chosen move\n            // Fixed: Updated structured binding to match 5-element tuple\n            auto [val, nr, nc, tid, dir] = candidates[chosen_idx];\n            path += dir;\n            cur_r = nr;\n            cur_c = nc;\n            visited_tiles[tid] = cur_timestamp;\n            score += val;\n        }\n\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n        }\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    const int N = 30;\n    // Base estimates for rows and columns\n    vector<double> row_base(N, 5000.0);\n    vector<double> col_base(N, 5000.0);\n    \n    // Helper to compute edge estimate from base values\n    auto get_edge_weight = [&](bool is_horizontal, int i, int j) {\n        return is_horizontal ? row_base[i] : col_base[j];\n    };\n\n    double lr = 0.2;  // initial learning rate\n    int total_updates = 0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        int start = si * N + sj;\n        int target = ti * N + tj;\n\n        const double INF = 1e18;\n        vector<double> dist(N*N, INF);\n        vector<int> prev(N*N, -1);\n        vector<char> prev_move(N*N);\n        dist[start] = 0.0;\n        priority_queue<pair<double, int>,\n                       vector<pair<double, int>>,\n                       greater<pair<double, int>>> pq;\n        pq.emplace(0.0, start);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            int ui = u / N, uj = u % N;\n\n            // Up\n            if (ui > 0) {\n                int v = (ui-1)*N + uj;\n                double w = get_edge_weight(false, ui-1, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'U';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Down\n            if (ui < N-1) {\n                int v = (ui+1)*N + uj;\n                double w = get_edge_weight(false, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'D';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Left\n            if (uj > 0) {\n                int v = ui*N + (uj-1);\n                double w = get_edge_weight(true, ui, uj-1);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'L';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Right\n            if (uj < N-1) {\n                int v = ui*N + (uj+1);\n                double w = get_edge_weight(true, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'R';\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        // Reconstruct path and collect row/column usage\n        vector<char> moves;\n        vector<pair<bool, int>> path_edges; // (is_horizontal, index)\n        map<int, int> row_count, col_count;\n\n        int cur = target;\n        while (cur != start) {\n            int p = prev[cur];\n            char dir = prev_move[cur];\n            moves.push_back(dir);\n\n            int pi = p / N, pj = p % N;\n            int ci = cur / N, cj = cur % N;\n\n            if (pi == ci) { // horizontal move\n                int j = min(pj, cj);\n                path_edges.push_back({true, pi});\n                row_count[pi]++;\n            } else { // vertical move\n                int i = min(pi, ci);\n                path_edges.push_back({false, pj});\n                col_count[pj]++;\n            }\n            cur = p;\n        }\n        reverse(moves.begin(), moves.end());\n\n        // Output\n        for (char c : moves) cout << c;\n        cout << endl;\n\n        // Read result\n        int res;\n        cin >> res;\n\n        // Compute predicted length using current base estimates\n        double L_est = 0.0;\n        for (auto& [is_h, idx] : path_edges) {\n            L_est += is_h ? row_base[idx] : col_base[idx];\n        }\n        int len = path_edges.size();\n        double measured = res;\n\n        // Multiplicative update factor\n        double factor = pow(measured / L_est, lr / len);\n\n        // Update row and column base values\n        for (auto& [is_h, idx] : path_edges) {\n            if (is_h) {\n                row_base[idx] *= factor;\n                row_base[idx] = max(1000.0, min(9000.0, row_base[idx]));\n            } else {\n                col_base[idx] *= factor;\n                col_base[idx] = max(1000.0, min(9000.0, col_base[idx]));\n            }\n        }\n\n        total_updates += len;\n        // Decay learning rate more slowly\n        lr = 0.2 / (1 + total_updates * 0.0001);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_K = 12;\nconst uint64_t BASE = 131;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int M;\n    cin >> M;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n    \n    // Hash each string\n    vector<uint64_t> str_hash(M);\n    unordered_map<uint64_t, int> hash_to_str;\n    for (int i = 0; i < M; ++i) {\n        uint64_t h = 0;\n        for (char ch : strs[i]) {\n            h = h * BASE + (ch - 'A' + 1);\n        }\n        str_hash[i] = h;\n        hash_to_str[h] = i;\n    }\n    \n    // Initialize random grid\n    vector<vector<char>> grid(N, vector<char>(N));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_letter(0, 7);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + dist_letter(rng);\n        }\n    }\n    \n    // Precompute row and column updates for each cell\n    vector<vector<pair<int, int>>> row_updates(N * N);\n    vector<vector<pair<int, int>>> col_updates(N * N);\n    \n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cell = r * N + c;\n            // Row updates: all substrings containing (r,c)\n            for (int k = 2; k <= MAX_K; ++k) {\n                for (int s = 0; s < N; ++s) {\n                    if ((c - s + N) % N < k) {\n                        row_updates[cell].push_back({s, k});\n                    }\n                }\n            }\n            // Column updates: all substrings containing (r,c)\n            for (int k = 2; k <= MAX_K; ++k) {\n                for (int s = 0; s < N; ++s) {\n                    if ((r - s + N) % N < k) {\n                        col_updates[cell].push_back({s, k});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Initialize row and column hash sets\n    vector<unordered_set<uint64_t>> row_hashes(N);\n    vector<unordered_set<uint64_t>> col_hashes(N);\n    \n    auto compute_hash_row = [&](int r, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int col = (start + i) % N;\n            h = h * BASE + (grid[r][col] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    auto compute_hash_col = [&](int c, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int row = (start + i) % N;\n            h = h * BASE + (grid[row][c] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    for (int r = 0; r < N; ++r) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= MAX_K; ++k) {\n                row_hashes[r].insert(compute_hash_row(r, s, k));\n            }\n        }\n    }\n    for (int c = 0; c < N; ++c) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= MAX_K; ++k) {\n                col_hashes[c].insert(compute_hash_col(c, s, k));\n            }\n        }\n    }\n    \n    // Count satisfied strings\n    vector<int> str_count(M, 0);\n    int total_sat = 0;\n    for (int i = 0; i < M; ++i) {\n        bool found = false;\n        for (int r = 0; r < N && !found; ++r) {\n            if (row_hashes[r].count(str_hash[i])) {\n                found = true;\n                str_count[i]++;\n            }\n        }\n        for (int c = 0; c < N && !found; ++c) {\n            if (col_hashes[c].count(str_hash[i])) {\n                found = true;\n                str_count[i]++;\n            }\n        }\n        if (str_count[i] > 0) total_sat++;\n    }\n    \n    // Simulated annealing\n    const int iterations = 50000;\n    double temp = 10.0;\n    const double cooling = 0.9999;\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    uniform_int_distribution<int> dist_cell(0, N - 1);\n    uniform_int_distribution<int> dist_newchar(0, 7);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int r = dist_cell(rng);\n        int c = dist_cell(rng);\n        char old_char = grid[r][c];\n        char new_char = 'A' + dist_newchar(rng);\n        \n        if (new_char == old_char) continue;\n        \n        int cell = r * N + c;\n        int old_total = total_sat;\n        \n        // Remove old hashes from row r\n        vector<uint64_t> old_row_hashes;\n        for (auto &[s, k] : row_updates[cell]) {\n            uint64_t old_hash = compute_hash_row(r, s, k);\n            old_row_hashes.push_back(old_hash);\n            row_hashes[r].erase(old_hash);\n            \n            if (hash_to_str.count(old_hash)) {\n                int i = hash_to_str[old_hash];\n                str_count[i]--;\n                if (str_count[i] == 0) total_sat--;\n            }\n        }\n        \n        // Remove old hashes from column c\n        vector<uint64_t> old_col_hashes;\n        for (auto &[s, k] : col_updates[cell]) {\n            uint64_t old_hash = compute_hash_col(c, s, k);\n            old_col_hashes.push_back(old_hash);\n            col_hashes[c].erase(old_hash);\n            \n            if (hash_to_str.count(old_hash)) {\n                int i = hash_to_str[old_hash];\n                str_count[i]--;\n                if (str_count[i] == 0) total_sat--;\n            }\n        }\n        \n        // Apply change\n        grid[r][c] = new_char;\n        \n        // Add new hashes to row r\n        vector<uint64_t> new_row_hashes;\n        for (auto &[s, k] : row_updates[cell]) {\n            uint64_t new_hash = compute_hash_row(r, s, k);\n            new_row_hashes.push_back(new_hash);\n            row_hashes[r].insert(new_hash);\n            \n            if (hash_to_str.count(new_hash)) {\n                int i = hash_to_str[new_hash];\n                str_count[i]++;\n                if (str_count[i] == 1) total_sat++;\n            }\n        }\n        \n        // Add new hashes to column c\n        vector<uint64_t> new_col_hashes;\n        for (auto &[s, k] : col_updates[cell]) {\n            uint64_t new_hash = compute_hash_col(c, s, k);\n            new_col_hashes.push_back(new_hash);\n            col_hashes[c].insert(new_hash);\n            \n            if (hash_to_str.count(new_hash)) {\n                int i = hash_to_str[new_hash];\n                str_count[i]++;\n                if (str_count[i] == 1) total_sat++;\n            }\n        }\n        \n        int new_total = total_sat;\n        double delta = new_total - old_total;\n        \n        // Accept or reject\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else if (temp > 1e-6 && exp(delta / temp) > dist_real(rng)) {\n            accept = true;\n        }\n        \n        if (!accept) {\n            // Revert changes\n            grid[r][c] = old_char;\n            \n            // Remove new hashes from row r\n            for (uint64_t h : new_row_hashes) {\n                row_hashes[r].erase(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]--;\n                    if (str_count[i] == 0) total_sat--;\n                }\n            }\n            \n            // Remove new hashes from column c\n            for (uint64_t h : new_col_hashes) {\n                col_hashes[c].erase(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]--;\n                    if (str_count[i] == 0) total_sat--;\n                }\n            }\n            \n            // Add back old hashes to row r\n            for (uint64_t h : old_row_hashes) {\n                row_hashes[r].insert(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]++;\n                    if (str_count[i] == 1) total_sat++;\n                }\n            }\n            \n            // Add back old hashes to column c\n            for (uint64_t h : old_col_hashes) {\n                col_hashes[c].insert(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]++;\n                    if (str_count[i] == 1) total_sat++;\n                }\n            }\n            \n            total_sat = old_total;\n        }\n        \n        temp *= cooling;\n        if (total_sat == M) break;\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n};\n\n// Hopcroft\u2013Karp for bipartite matching\nint hopcroft_karp(const vector<vector<int>>& adj, int L, int R,\n                  vector<int>& matchL, vector<int>& matchR) {\n    vector<int> dist(L, -1);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            dist[u] = 0;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (matchR[v] != -1 && dist[matchR[v]] == -1) {\n                dist[matchR[v]] = dist[u] + 1;\n                q.push(matchR[v]);\n            }\n        }\n    }\n    function<bool(int)> dfs = [&](int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 ||\n                (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n    int matching = 0;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1 && dfs(u)) ++matching;\n    }\n    return matching;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; ++i) cin >> grid_str[i];\n\n    // Convert grid: -1 for obstacle, otherwise cost (5-9)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Point> roads;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid_str[i][j];\n            if (c != '#') {\n                grid[i][j] = c - '0';\n                roads.push_back({i, j});\n            }\n        }\n    }\n\n    // ---------- row segments ----------\n    vector<vector<int>> row_seg(N, vector<int>(N, -1));\n    int L = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != -1) {\n                int start = j;\n                while (j < N && grid[i][j] != -1) ++j;\n                int end = j - 1;\n                for (int k = start; k <= end; ++k) row_seg[i][k] = L;\n                ++L;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ---------- column segments ----------\n    vector<vector<int>> col_seg(N, vector<int>(N, -1));\n    int R = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != -1) {\n                int start = i;\n                while (i < N && grid[i][j] != -1) ++i;\n                int end = i - 1;\n                for (int k = start; k <= end; ++k) col_seg[k][j] = R;\n                ++R;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ---------- bipartite graph (row segments vs column segments) ----------\n    vector<vector<int>> adj(L);\n    vector<vector<pair<int, Point>>> edge_coord(L); // for each row segment: (col_segment, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        adj[u].push_back(v);\n        edge_coord[u].push_back({v, {p.i, p.j}});\n    }\n\n    // ---------- minimum vertex cover (via maximum matching) ----------\n    vector<int> matchL(L, -1), matchR(R, -1);\n    hopcroft_karp(adj, L, R, matchL, matchR);\n\n    vector<bool> visL(L, false), visR(R, false);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            visL[u] = true;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (!visR[v]) {\n                visR[v] = true;\n                if (matchR[v] != -1 && !visL[matchR[v]]) {\n                    visL[matchR[v]] = true;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n    }\n    vector<bool> selected_row(L, false), selected_col(R, false);\n    for (int u = 0; u < L; ++u) selected_row[u] = !visL[u];\n    for (int v = 0; v < R; ++v) selected_col[v] = visR[v];\n\n    // ---------- selected segments ----------\n    vector<int> sel_row_list, sel_col_list;\n    for (int u = 0; u < L; ++u) if (selected_row[u]) sel_row_list.push_back(u);\n    for (int v = 0; v < R; ++v) if (selected_col[v]) sel_col_list.push_back(v);\n    int L2 = sel_row_list.size(), R2 = sel_col_list.size();\n    map<int, int> row_idx, col_idx;\n    for (int i = 0; i < L2; ++i) row_idx[sel_row_list[i]] = i;\n    for (int i = 0; i < R2; ++i) col_idx[sel_col_list[i]] = i;\n\n    // ---------- induced graph on selected segments ----------\n    vector<vector<int>> adj2(L2);\n    vector<vector<int>> radj2(R2);\n    vector<vector<pair<int, Point>>> edge_coord2(L2); // (col_idx, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        if (selected_row[u] && selected_col[v]) {\n            int u2 = row_idx[u];\n            int v2 = col_idx[v];\n            adj2[u2].push_back(v2);\n            radj2[v2].push_back(u2);\n            edge_coord2[u2].push_back({v2, {p.i, p.j}});\n        }\n    }\n\n    // ---------- minimum edge cover on induced graph ----------\n    vector<int> matchL2(L2, -1), matchR2(R2, -1);\n    hopcroft_karp(adj2, L2, R2, matchL2, matchR2);\n\n    vector<Point> S; // squares to visit\n    vector<bool> row_covered(L2, false), col_covered(R2, false);\n\n    // 1. take all matching edges\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (matchL2[u2] != -1) {\n            int v2 = matchL2[u2];\n            for (auto& e : edge_coord2[u2]) {\n                if (e.first == v2) {\n                    S.push_back(e.second);\n                    break;\n                }\n            }\n            row_covered[u2] = true;\n            col_covered[v2] = true;\n        }\n    }\n\n    // 2. cover unmatched rows\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (!row_covered[u2]) {\n            if (!adj2[u2].empty()) {\n                int v2 = adj2[u2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n                col_covered[v2] = true;\n            } else { // isolated row segment\n                int u_orig = sel_row_list[u2];\n                for (auto& p : roads) {\n                    if (row_seg[p.i][p.j] == u_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n            }\n        }\n    }\n\n    // 3. cover unmatched columns\n    for (int v2 = 0; v2 < R2; ++v2) {\n        if (!col_covered[v2]) {\n            if (!radj2[v2].empty()) {\n                int u2 = radj2[v2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            } else { // isolated column segment\n                int v_orig = sel_col_list[v2];\n                for (auto& p : roads) {\n                    if (col_seg[p.i][p.j] == v_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            }\n        }\n    }\n\n    // ---------- nodes for TSP (start + S without duplicates) ----------\n    vector<Point> nodes;\n    nodes.push_back({si, sj});\n    set<pair<int, int>> visited_set;\n    for (auto& p : S) {\n        if (p.i == si && p.j == sj) continue;\n        if (visited_set.insert({p.i, p.j}).second) {\n            nodes.push_back(p);\n        }\n    }\n    int n = nodes.size();\n\n    // ---------- Dijkstra from each node, build distance matrix and predecessors ----------\n    const int INF = 1e9;\n    vector<vector<int>> dist_mat(n, vector<int>(n, INF));\n    vector<vector<vector<char>>> pred(n, vector<vector<char>>(N, vector<char>(N, 0)));\n\n    auto dijkstra = [&](int src_idx) {\n        int si = nodes[src_idx].i, sj = nodes[src_idx].j;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        dist[si][sj] = 0;\n        pred[src_idx][si][sj] = 0; // 0 marks the source\n        priority_queue<pair<int, pair<int, int>>,\n                       vector<pair<int, pair<int, int>>>,\n                       greater<>> pq;\n        pq.push({0, {si, sj}});\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dir[4] = {'U', 'D', 'L', 'R'};\n        while (!pq.empty()) {\n            auto top = pq.top(); pq.pop();\n            int d = top.first;\n            int i = top.second.first, j = top.second.second;\n            if (d != dist[i][j]) continue;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid[ni][nj] == -1) continue;\n                int nd = d + grid[ni][nj];\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    pred[src_idx][ni][nj] = dir[k];\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n        for (int t = 0; t < n; ++t) {\n            int ti = nodes[t].i, tj = nodes[t].j;\n            dist_mat[src_idx][t] = dist[ti][tj];\n        }\n    };\n    for (int s = 0; s < n; ++s) dijkstra(s);\n\n    // ---------- TSP heuristic (nearest neighbour + 2\u2011opt + swap + or\u2011opt) ----------\n    vector<int> tour;\n    vector<bool> vis(n, false);\n    tour.push_back(0); // start at index 0\n    vis[0] = true;\n    int cur = 0;\n    for (int iter = 0; iter < n - 1; ++iter) {\n        int nxt = -1, best = INF;\n        for (int v = 0; v < n; ++v) {\n            if (!vis[v] && dist_mat[cur][v] < best) {\n                best = dist_mat[cur][v];\n                nxt = v;\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = true;\n        cur = nxt;\n    }\n    tour.push_back(0); // return to start\n\n    auto tour_cost = [&](const vector<int>& t) {\n        int cost = 0;\n        for (size_t i = 0; i < t.size() - 1; ++i) cost += dist_mat[t[i]][t[i+1]];\n        return cost;\n    };\n\n    int best_cost = tour_cost(tour);\n    vector<int> best_tour = tour;\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n\n        // 2-opt\n        bool found = false;\n        for (size_t i = 0; i < best_tour.size() - 2 && !found; ++i) {\n            for (size_t j = i + 2; j < best_tour.size() - 1; ++j) {\n                int a = best_tour[i], b = best_tour[i+1], c = best_tour[j], d = best_tour[j+1];\n                int cur_cost = dist_mat[a][b] + dist_mat[c][d];\n                int seg_orig = 0;\n                for (size_t k = i+1; k < j; ++k) seg_orig += dist_mat[best_tour[k]][best_tour[k+1]];\n                int new_cost = dist_mat[a][c] + dist_mat[b][d];\n                int seg_rev = 0;\n                for (size_t k = j; k > i+1; --k) seg_rev += dist_mat[best_tour[k]][best_tour[k-1]];\n                if (cur_cost + seg_orig > new_cost + seg_rev) {\n                    reverse(best_tour.begin() + i + 1, best_tour.begin() + j + 1);\n                    best_cost += (new_cost + seg_rev) - (cur_cost + seg_orig);\n                    improved = true;\n                    found = true;\n                    break;\n                }\n            }\n        }\n        if (improved) continue;\n\n        // swap (non-adjacent nodes)\n        found = false;\n        for (size_t i = 1; i < best_tour.size() - 1 && !found; ++i) {\n            for (size_t j = i + 2; j < best_tour.size() - 1; ++j) { // skip adjacent\n                int u = best_tour[i], v = best_tour[j];\n                int a = best_tour[i-1], b = best_tour[i+1];\n                int c = best_tour[j-1], d = best_tour[j+1];\n                int delta = (dist_mat[a][v] + dist_mat[v][b] + dist_mat[c][u] + dist_mat[u][d])\n                          - (dist_mat[a][u] + dist_mat[u][b] + dist_mat[c][v] + dist_mat[v][d]);\n                if (delta < 0) {\n                    swap(best_tour[i], best_tour[j]);\n                    best_cost += delta;\n                    improved = true;\n                    found = true;\n                    break;\n                }\n            }\n        }\n        if (improved) continue;\n\n        // or-opt: relocate single nodes\n        found = false;\n        for (size_t i = 1; i < best_tour.size() - 1 && !found; ++i) {\n            int u = best_tour[i];\n            int a = best_tour[i-1], c = best_tour[i+1];\n            for (size_t j = 1; j < best_tour.size() - 1; ++j) {\n                if (j == i-1 || j == i || j == i+1) continue;\n                int d = best_tour[j-1], e = best_tour[j];\n                int delta = -dist_mat[a][u] - dist_mat[u][c] + dist_mat[a][c]\n                            - dist_mat[d][e] + dist_mat[d][u] + dist_mat[u][e];\n                if (delta < 0) {\n                    best_tour.erase(best_tour.begin() + i);\n                    if (j > i) j--;\n                    best_tour.insert(best_tour.begin() + j, u);\n                    best_cost += delta;\n                    improved = true;\n                    found = true;\n                    break;\n                }\n            }\n        }\n        // if no improvement, loop ends\n    }\n    tour = best_tour;\n\n    // ---------- build move string ----------\n    string moves;\n    for (size_t idx = 0; idx < tour.size() - 1; ++idx) {\n        int src_idx = tour[idx];\n        int tgt_idx = tour[idx+1];\n        int ci = nodes[tgt_idx].i, cj = nodes[tgt_idx].j;\n        vector<char> path;\n        while (!(ci == nodes[src_idx].i && cj == nodes[src_idx].j)) {\n            char d = pred[src_idx][ci][cj];\n            path.push_back(d);\n            // move to parent\n            if (d == 'U') ci++;\n            else if (d == 'D') ci--;\n            else if (d == 'L') cj++;\n            else if (d == 'R') cj--;\n        }\n        reverse(path.begin(), path.end());\n        for (char c : path) moves.push_back(c);\n    }\n\n    cout << moves << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Function to compute expected completion time given estimated deficit w\ndouble expected_time(double w) {\n    if (w <= 0.0) return 1.0;\n    if (w >= 4.0) return w;\n    // Precomputed expected times for integer w (0 to 4)\n    const double E0 = 1.0;\n    const double E1 = 13.0 / 7.0;\n    const double E2 = 17.0 / 7.0;\n    const double E3 = 22.0 / 7.0;\n    const double E4 = 4.0;\n    int floor_w = (int)w;\n    double frac = w - floor_w;\n    if (floor_w == 0) return E0 + frac * (E1 - E0);\n    if (floor_w == 1) return E1 + frac * (E2 - E1);\n    if (floor_w == 2) return E2 + frac * (E3 - E2);\n    if (floor_w == 3) return E3 + frac * (E4 - E3);\n    return w; // fallback\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            cin >> d[i][k];\n        }\n    }\n\n    vector<vector<int>> children(N);\n    vector<int> prereq_count(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        prereq_count[v]++;\n    }\n\n    // Critical path length L[i]\n    vector<int> L(N, 1);\n    for (int i = N - 1; i >= 0; --i) {\n        for (int v : children[i]) {\n            L[i] = max(L[i], 1 + L[v]);\n        }\n    }\n\n    // Available tasks (prerequisites satisfied)\n    vector<int> avail;\n    for (int i = 0; i < N; ++i) {\n        if (prereq_count[i] == 0) {\n            avail.push_back(i);\n        }\n    }\n\n    // Task status: 0=not started, 1=started, 2=completed\n    vector<int> task_status(N, 0);\n\n    // Team member state\n    vector<int> current_task(M, -1);      // -1 if idle\n    vector<int> start_day(M, -1);\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));  // estimated skill levels\n\n    int cur_day = 1;\n\n    while (true) {\n        // Collect idle members\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // Collect currently available tasks (status 0)\n        vector<int> today_avail;\n        for (int i : avail) {\n            if (task_status[i] == 0) {\n                today_avail.push_back(i);\n            }\n        }\n\n        // Sort by critical path length descending\n        sort(today_avail.begin(), today_avail.end(),\n             [&](int a, int b) { return L[a] > L[b]; });\n\n        vector<pair<int, int>> assignments; // (member, task)\n        vector<bool> member_used(M, false);\n\n        for (int i : today_avail) {\n            if (idle_members.empty()) break;\n\n            int best_j = -1;\n            double best_expected = 1e9;\n            for (int j : idle_members) {\n                if (member_used[j]) continue;\n                double w_est = 0.0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        w_est += d[i][k] - s_est[j][k];\n                    }\n                }\n                double exp_t = expected_time(w_est);\n                if (exp_t < best_expected) {\n                    best_expected = exp_t;\n                    best_j = j;\n                }\n            }\n            if (best_j != -1) {\n                assignments.emplace_back(best_j, i);\n                member_used[best_j] = true;\n                // Update current task and start day immediately\n                current_task[best_j] = i;\n                start_day[best_j] = cur_day;\n                task_status[i] = 1; // mark as started\n            }\n        }\n\n        // Output assignments\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        // Read response line\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        istringstream iss(line);\n        int n;\n        iss >> n;\n        vector<int> completing;\n        for (int i = 0; i < n; ++i) {\n            int f;\n            iss >> f;\n            completing.push_back(f - 1); // to 0-index\n        }\n\n        // Process completions\n        for (int j : completing) {\n            int i = current_task[j];\n            if (i == -1) continue; // should not happen\n\n            int t = cur_day - start_day[j] + 1; // actual duration\n\n            // Update skill estimates for member j\n            double w_est = 0.0;\n            int num_deficient = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    w_est += d[i][k] - s_est[j][k];\n                    num_deficient++;\n                }\n            }\n            if (num_deficient > 0) {\n                double delta = (w_est - t) / num_deficient;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        s_est[j][k] += delta;\n                        if (s_est[j][k] < 0.0) s_est[j][k] = 0.0;\n                    }\n                }\n            }\n\n            // Mark task as completed\n            task_status[i] = 2;\n            current_task[j] = -1;\n\n            // Update dependent tasks\n            for (int v : children[i]) {\n                prereq_count[v]--;\n                if (prereq_count[v] == 0) {\n                    avail.push_back(v);\n                }\n            }\n        }\n\n        ++cur_day;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <ctime>\n#include <cassert>\n\nusing namespace std;\n\nstruct Order {\n    int id;          // original index (0-based)\n    int a, b, c, d;  // restaurant and destination\n};\n\nvector<Order> orders; // all 1000 orders\n\n// Manhattan distance\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Point in the route: (order_index, type) type: 0=restaurant, 1=destination\nusing Point = pair<int, int>;\n\n// Compute total distance for a sequence of points\nint total_distance(const vector<Point>& seq, const vector<Order>& sel) {\n    int cur_x = 400, cur_y = 400;\n    int total = 0;\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) { // restaurant\n            total += dist(cur_x, cur_y, sel[idx].a, sel[idx].b);\n            cur_x = sel[idx].a;\n            cur_y = sel[idx].b;\n        } else { // destination\n            total += dist(cur_x, cur_y, sel[idx].c, sel[idx].d);\n            cur_x = sel[idx].c;\n            cur_y = sel[idx].d;\n        }\n    }\n    total += dist(cur_x, cur_y, 400, 400);\n    return total;\n}\n\n// Check precedence constraints: for each order, restaurant before destination\nbool is_valid(const vector<Point>& seq, int m) {\n    vector<int> rest_pos(m, -1), dest_pos(m, -1);\n    for (size_t i = 0; i < seq.size(); ++i) {\n        int idx = seq[i].first;\n        if (seq[i].second == 0) {\n            rest_pos[idx] = i;\n        } else {\n            dest_pos[idx] = i;\n        }\n    }\n    for (int i = 0; i < m; ++i) {\n        if (rest_pos[i] == -1 || dest_pos[i] == -1) return false;\n        if (rest_pos[i] >= dest_pos[i]) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read all orders\n    orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n\n    // Selection: pick 50 orders with smallest round-trip cost\n    vector<int> indices(1000);\n    for (int i = 0; i < 1000; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int cost_i = dist(400, 400, orders[i].a, orders[i].b) +\n                     dist(orders[i].a, orders[i].b, orders[i].c, orders[i].d) +\n                     dist(orders[i].c, orders[i].d, 400, 400);\n        int cost_j = dist(400, 400, orders[j].a, orders[j].b) +\n                     dist(orders[j].a, orders[j].b, orders[j].c, orders[j].d) +\n                     dist(orders[j].c, orders[j].d, 400, 400);\n        return cost_i < cost_j;\n    });\n    vector<Order> selected;\n    for (int i = 0; i < 50; ++i) {\n        selected.push_back(orders[indices[i]]);\n    }\n    int m = 50;\n\n    // Generate initial sequence using nearest neighbor with precedence\n    vector<Point> seq;\n    vector<bool> rest_done(m, false), dest_done(m, false);\n    vector<int> available; // orders whose restaurant done but destination not\n    int cur_x = 400, cur_y = 400;\n\n    for (int step = 0; step < 2 * m; ++step) {\n        int best_idx = -1;\n        int best_type = -1;\n        int best_cost = 1e9;\n\n        // Consider restaurants of unvisited orders\n        for (int i = 0; i < m; ++i) {\n            if (rest_done[i]) continue;\n            int cost = dist(cur_x, cur_y, selected[i].a, selected[i].b);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 0;\n            }\n        }\n        // Consider destinations of available orders\n        for (int i : available) {\n            int cost = dist(cur_x, cur_y, selected[i].c, selected[i].d);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_idx = i;\n                best_type = 1;\n            }\n        }\n        assert(best_idx != -1);\n        seq.emplace_back(best_idx, best_type);\n        if (best_type == 0) {\n            rest_done[best_idx] = true;\n            available.push_back(best_idx);\n        } else {\n            dest_done[best_idx] = true;\n            // Remove from available\n            auto it = find(available.begin(), available.end(), best_idx);\n            if (it != available.end()) available.erase(it);\n        }\n        // Update current position\n        if (best_type == 0) {\n            cur_x = selected[best_idx].a;\n            cur_y = selected[best_idx].b;\n        } else {\n            cur_x = selected[best_idx].c;\n            cur_y = selected[best_idx].d;\n        }\n    }\n    assert(is_valid(seq, m));\n    int total = total_distance(seq, selected);\n\n    // Local search: 2-opt and point swaps until no improvement or time limit\n    clock_t start = clock();\n    const double time_limit = 1.8 * CLOCKS_PER_SEC; // slightly less than 2 sec\n    bool improved = true;\n    while (improved && (clock() - start) < time_limit) {\n        improved = false;\n        // Try all segment reversals\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                vector<Point> new_seq = seq;\n                reverse(new_seq.begin() + i, new_seq.begin() + j + 1);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n        // Try all point swaps\n        for (size_t i = 0; i < seq.size(); ++i) {\n            for (size_t j = i + 1; j < seq.size(); ++j) {\n                vector<Point> new_seq = seq;\n                swap(new_seq[i], new_seq[j]);\n                if (!is_valid(new_seq, m)) continue;\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < total) {\n                    seq = new_seq;\n                    total = new_total;\n                    improved = true;\n                }\n            }\n            if ((clock() - start) >= time_limit) break;\n        }\n    }\n\n    // Output selected orders (1-based indices)\n    cout << m;\n    for (const auto& order : selected) {\n        cout << ' ' << order.id + 1;\n    }\n    cout << '\\n';\n\n    // Output route: office, then points in seq, then office\n    cout << 1 + 2 * m + 1; // start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) {\n            cout << ' ' << selected[idx].a << ' ' << selected[idx].b;\n        } else {\n            cout << ' ' << selected[idx].c << ' ' << selected[idx].d;\n        }\n    }\n    cout << \" 400 400\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct DSU {\n    vector<int> parent, rank;\n    int components;\n    DSU(int n) : parent(n), rank(n, 0), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        components--;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (accepted == 399) {\n            cout << 0 << endl;\n            continue;\n        }\n        if (dsu.find(u[i]) == dsu.find(v[i])) {\n            cout << 0 << endl;\n            continue;\n        }\n        cout << 1 << endl;\n        dsu.unite(u[i], v[i]);\n        accepted++;\n        cout.flush();\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 30;\nconst double WALL_BONUS = 0.5;  // Bonus for placing any wall\nconst double PET_PENALTY = 2.0; // Penalty per pet in component\n\nint N, M;\nint px[20], py[20], pt[20];\nint hx[10], hy[10];\nbool passable[31][31];\n\nbool pet_at[31][31];\nbool human_at[31][31];\nbool adj_to_pet[31][31];\n\nbool blocked_this_turn[31][31];\n\nrandom_device rd;\nmt19937 rng(rd());\n\n// BFS that counts pets and returns size\nint bfs(int sx, int sy, int& pet_count, bool temp_blocked = false, int tbx = -1, int tby = -1) {\n    static bool visited[31][31];\n    memset(visited, 0, sizeof(visited));\n    queue<pair<int,int>> q;\n    if (passable[sx][sy] && !blocked_this_turn[sx][sy] && \n        !(temp_blocked && sx==tbx && sy==tby)) {\n        q.push({sx, sy});\n        visited[sx][sy] = true;\n    }\n    int size = 0;\n    pet_count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        size++;\n        if (pet_at[x][y]) pet_count++;\n        for (int dx = -1; dx <= 1; dx++) {\n            for (int dy = -1; dy <= 1; dy++) {\n                if (abs(dx) + abs(dy) != 1) continue;\n                int nx = x + dx, ny = y + dy;\n                if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) continue;\n                if (!passable[nx][ny]) continue;\n                if (blocked_this_turn[nx][ny]) continue;\n                if (temp_blocked && nx==tbx && ny==tby) continue;\n                if (visited[nx][ny]) continue;\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return size;\n}\n\n// Simulate pet movement for one step to estimate future pet positions\nvoid simulate_pet_step(int& x, int& y, int type) {\n    // Simplified: for now, just move randomly (can be improved per type)\n    vector<pair<int,int>> moves = {{-1,0},{1,0},{0,-1},{0,1}};\n    vector<pair<int,int>> valid;\n    for (auto [dx, dy] : moves) {\n        int nx = x + dx, ny = y + dy;\n        if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN && passable[nx][ny]) {\n            valid.push_back({nx, ny});\n        }\n    }\n    if (!valid.empty()) {\n        auto [nx, ny] = valid[rng() % valid.size()];\n        x = nx; y = ny;\n    }\n}\n\nint main() {\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> px[i] >> py[i] >> pt[i];\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> hx[i] >> hy[i];\n    }\n\n    // Initialize passable grid\n    for (int i = 1; i <= MAXN; i++) {\n        for (int j = 1; j <= MAXN; j++) {\n            passable[i][j] = true;\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        // Precompute grids\n        memset(pet_at, 0, sizeof(pet_at));\n        for (int i = 0; i < N; i++) pet_at[px[i]][py[i]] = true;\n        memset(human_at, 0, sizeof(human_at));\n        for (int i = 0; i < M; i++) human_at[hx[i]][hy[i]] = true;\n        memset(adj_to_pet, 0, sizeof(adj_to_pet));\n        for (int i = 0; i < N; i++) {\n            int x = px[i], y = py[i];\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    if (abs(dx) + abs(dy) != 1) continue;\n                    int nx = x + dx, ny = y + dy;\n                    if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN) {\n                        adj_to_pet[nx][ny] = true;\n                    }\n                }\n            }\n        }\n\n        memset(blocked_this_turn, 0, sizeof(blocked_this_turn));\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        string actions(M, '.');\n\n        for (int idx : order) {\n            int x = hx[idx], y = hy[idx];\n            double best_value = -1e9;\n            char best_action = '.';\n\n            // Compute current pet count for reference\n            int P0;\n            bfs(x, y, P0);\n\n            auto evaluate = [&](char action) -> double {\n                int nx = x, ny = y;\n                bool is_block = false;\n                bool is_move = false;\n                int tbx = -1, tby = -1;\n\n                if (action == '.') {\n                    // Stay\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    // Block\n                    is_block = true;\n                    if (action == 'u') { nx = x-1; ny = y; }\n                    else if (action == 'd') { nx = x+1; ny = y; }\n                    else if (action == 'l') { nx = x; ny = y-1; }\n                    else if (action == 'r') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (pet_at[nx][ny]) return -1e9;\n                    if (human_at[nx][ny]) return -1e9;\n                    if (adj_to_pet[nx][ny]) return -1e9;\n                    tbx = nx; tby = ny;\n                } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // Move\n                    is_move = true;\n                    if (action == 'U') { nx = x-1; ny = y; }\n                    else if (action == 'D') { nx = x+1; ny = y; }\n                    else if (action == 'L') { nx = x; ny = y-1; }\n                    else if (action == 'R') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (blocked_this_turn[nx][ny]) return -1e9;\n                } else {\n                    return -1e9;\n                }\n\n                // Compute component after action\n                int start_x = is_move ? nx : x;\n                int start_y = is_move ? ny : y;\n                int pet_count;\n                int comp_size = bfs(start_x, start_y, pet_count, is_block, tbx, tby);\n                \n                // Base value with heavy pet penalty\n                double value = (comp_size / 900.0) * pow(0.5, pet_count * PET_PENALTY);\n                \n                // Bonus for placing a wall\n                if (is_block) {\n                    value += WALL_BONUS;\n                    // Additional bonus for removing pets\n                    if (P0 > pet_count) {\n                        value += 2.0 * (P0 - pet_count);\n                    }\n                }\n                \n                // Small random noise to break ties\n                value += (rng() % 1000) / 1000000.0;\n                return value;\n            };\n\n            vector<char> actions_list = {'.', 'u', 'd', 'l', 'r', 'U', 'D', 'L', 'R'};\n            for (char a : actions_list) {\n                double val = evaluate(a);\n                if (val > best_value) {\n                    best_value = val;\n                    best_action = a;\n                }\n            }\n\n            actions[idx] = best_action;\n\n            if (best_action == 'u' || best_action == 'd' || best_action == 'l' || best_action == 'r') {\n                int bx = x, by = y;\n                if (best_action == 'u') bx = x-1;\n                else if (best_action == 'd') bx = x+1;\n                else if (best_action == 'l') by = y-1;\n                else if (best_action == 'r') by = y+1;\n                blocked_this_turn[bx][by] = true;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        // Read and apply 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') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n            }\n        }\n\n        // Update passable grid with walls\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'u' || a == 'd' || a == 'l' || a == 'r') {\n                int bx = hx[i], by = hy[i];\n                if (a == 'u') bx = hx[i]-1;\n                else if (a == 'd') bx = hx[i]+1;\n                else if (a == 'l') by = hy[i]-1;\n                else if (a == 'r') by = hy[i]+1;\n                passable[bx][by] = false;\n            }\n        }\n\n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') hx[i]--;\n            else if (a == 'D') hx[i]++;\n            else if (a == 'L') hy[i]--;\n            else if (a == 'R') hy[i]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0:U, 1:D, 2:L, 3:R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst double EPS = 1e-12;\nconst int BEAM_WIDTH = 200;   // increased width\n\n// Precompute next cell for each cell and direction\nint next_cell[4][20][20][2]; // [dir][i][j][0]=ni, [1]=nj\n\nvoid precompute_next(const vector<vector<int>>& h,\n                     const vector<vector<int>>& v) {\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            // U\n            if (i > 0 && v[i-1][j] == 0) {\n                next_cell[0][i][j][0] = i-1;\n                next_cell[0][i][j][1] = j;\n            } else {\n                next_cell[0][i][j][0] = i;\n                next_cell[0][i][j][1] = j;\n            }\n            // D\n            if (i < 19 && v[i][j] == 0) {\n                next_cell[1][i][j][0] = i+1;\n                next_cell[1][i][j][1] = j;\n            } else {\n                next_cell[1][i][j][0] = i;\n                next_cell[1][i][j][1] = j;\n            }\n            // L\n            if (j > 0 && h[i][j-1] == 0) {\n                next_cell[2][i][j][0] = i;\n                next_cell[2][i][j][1] = j-1;\n            } else {\n                next_cell[2][i][j][0] = i;\n                next_cell[2][i][j][1] = j;\n            }\n            // R\n            if (j < 19 && h[i][j] == 0) {\n                next_cell[3][i][j][0] = i;\n                next_cell[3][i][j][1] = j+1;\n            } else {\n                next_cell[3][i][j][0] = i;\n                next_cell[3][i][j][1] = j;\n            }\n        }\n    }\n}\n\n// BFS to find a shortest path from start to target\nstring bfs_path(int si, int sj, int ti, int tj,\n                const vector<vector<int>>& h,\n                const vector<vector<int>>& v) {\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move(20, vector<char>(20, ' '));\n    queue<pair<int, int>> q;\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            if (d == 0 && (i == 0 || v[i-1][j] == 1)) continue;\n            if (d == 1 && (i == 19 || v[i][j] == 1)) continue;\n            if (d == 2 && (j == 0 || h[i][j-1] == 1)) continue;\n            if (d == 3 && (j == 19 || h[i][j] == 1)) continue;\n            if (!visited[ni][nj]) {\n                visited[ni][nj] = true;\n                parent[ni][nj] = {i, j};\n                move[ni][nj] = dir_char[d];\n                q.emplace(ni, nj);\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        char m = move[i][j];\n        path += m;\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Simulate the stochastic process and compute expected score\ndouble simulate(const string& s, int si, int sj, int ti, int tj, double p) {\n    double dist[20][20] = {};\n    dist[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int t = 1; t <= L; ++t) {\n        char c = s[t-1];\n        int d = -1;\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        double new_dist[20][20] = {};\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob = dist[i][j];\n                if (prob == 0.0) continue;\n                new_dist[i][j] += prob * p;\n                int ni = next_cell[d][i][j][0];\n                int nj = next_cell[d][i][j][1];\n                if (ni == ti && nj == tj) {\n                    score += prob * (1-p) * (401 - t);\n                } else {\n                    new_dist[ni][nj] += prob * (1-p);\n                }\n            }\n        }\n        memcpy(dist, new_dist, sizeof(dist));\n    }\n    return score;\n}\n\n// Generate greedy nominal string\nstring greedy_nominal(int si, int sj, int ti, int tj,\n                      const vector<vector<int>>& h,\n                      const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char best = 'R';\n        bool moved = false;\n        if (cur_c < tj && h[cur_r][cur_c] == 0) {\n            best = 'R';\n            moved = true;\n        }\n        if (!moved && cur_r < ti && v[cur_r][cur_c] == 0) {\n            best = 'D';\n            moved = true;\n        }\n        if (!moved && cur_c > tj && (cur_c > 0 && h[cur_r][cur_c-1] == 0)) {\n            best = 'L';\n            moved = true;\n        }\n        if (!moved && cur_r > ti && (cur_r > 0 && v[cur_r-1][cur_c] == 0)) {\n            best = 'U';\n            moved = true;\n        }\n        if (!moved) {\n            if (cur_c < 19 && h[cur_r][cur_c] == 0) best = 'R';\n            else if (cur_r < 19 && v[cur_r][cur_c] == 0) best = 'D';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) best = 'L';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) best = 'U';\n            else best = 'R';\n        }\n        cand += best;\n        if (best == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (best == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (best == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n        else if (best == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n    }\n    return cand;\n}\n\n// Generate alternating direction string\nstring alternating_string(int si, int sj, int ti, int tj,\n                          const vector<vector<int>>& h,\n                          const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char dir = 'D';\n        if (cur_r > ti) dir = 'U';\n        else if (cur_c < tj) dir = 'R';\n        else if (cur_c > tj) dir = 'L';\n        bool possible = false;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) possible = true;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) possible = true;\n        if (!possible) {\n            if (cur_r < 19 && v[cur_r][cur_c] == 0) dir = 'D';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) dir = 'U';\n            else if (cur_c < 19 && h[cur_r][cur_c] == 0) dir = 'R';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) dir = 'L';\n            else dir = 'R';\n        }\n        cand += dir;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n    }\n    return cand;\n}\n\n// DP for optimal adaptive value function V[t][i][j] (t steps remaining)\ndouble V[201][20][20];\n\nvoid compute_V(int ti, int tj, double p) {\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            V[0][i][j] = 0.0;\n    for (int t = 1; t <= 200; ++t) {\n        int step_num = 201 - t;\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    V[t][i][j] = 0.0;\n                    continue;\n                }\n                double best = -1e9;\n                for (int a = 0; a < 4; ++a) {\n                    double val = 0.0;\n                    val += p * V[t-1][i][j];\n                    int ni = next_cell[a][i][j][0];\n                    int nj = next_cell[a][i][j][1];\n                    if (ni == ti && nj == tj) {\n                        val += (1-p) * (401 - step_num);\n                    } else {\n                        val += (1-p) * V[t-1][ni][nj];\n                    }\n                    if (val > best) best = val;\n                }\n                V[t][i][j] = best;\n            }\n        }\n    }\n}\n\n// Helper: apply action to distribution and compute immediate reward\nvoid apply_action(const double dist[20][20], int a, int step,\n                  int ti, int tj, double p,\n                  double new_dist[20][20], double& reward) {\n    memset(new_dist, 0, sizeof(double)*20*20);\n    reward = 0.0;\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            double prob = dist[i][j];\n            if (prob < EPS) continue;\n            new_dist[i][j] += prob * p;\n            int ni = next_cell[a][i][j][0];\n            int nj = next_cell[a][i][j][1];\n            if (ni == ti && nj == tj) {\n                reward += prob * (1-p) * (401 - step);\n            } else {\n                new_dist[ni][nj] += prob * (1-p);\n            }\n        }\n    }\n}\n\n// Helper: compute heuristic value for a distribution with r steps remaining\ndouble heuristic(const double dist[20][20], int r) {\n    double val = 0.0;\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            val += dist[i][j] * V[r][i][j];\n    return val;\n}\n\n// Beam search to find a good sequence\nstring beam_search_sequence(int si, int sj, int ti, int tj, double p) {\n    struct State {\n        double dist[20][20];\n        string seq;\n        double score;   // expected reward so far\n        double total;   // score + heuristic (for sorting)\n    };\n    vector<State> beam;\n    // initial state\n    State init;\n    memset(init.dist, 0, sizeof(init.dist));\n    init.dist[si][sj] = 1.0;\n    init.seq = \"\";\n    init.score = 0.0;\n    init.total = heuristic(init.dist, 200);\n    beam.push_back(init);\n\n    for (int step = 1; step <= 200; ++step) {\n        vector<State> candidates;\n        for (const State& st : beam) {\n            // compute total probability\n            double total_prob = 0.0;\n            for (int i = 0; i < 20; ++i)\n                for (int j = 0; j < 20; ++j)\n                    total_prob += st.dist[i][j];\n            if (total_prob < EPS) continue;\n\n            for (int a = 0; a < 4; ++a) {\n                double new_dist[20][20];\n                double reward;\n                apply_action(st.dist, a, step, ti, tj, p, new_dist, reward);\n                double new_score = st.score + reward;\n                double h = heuristic(new_dist, 200 - step);\n                State new_state;\n                memcpy(new_state.dist, new_dist, sizeof(new_dist));\n                new_state.seq = st.seq + dir_char[a];\n                new_state.score = new_score;\n                new_state.total = new_score + h;\n                candidates.push_back(new_state);\n            }\n        }\n        // keep top BEAM_WIDTH candidates\n        if (candidates.size() > BEAM_WIDTH) {\n            nth_element(candidates.begin(), candidates.begin() + BEAM_WIDTH, candidates.end(),\n                        [](const State& a, const State& b) { return a.total > b.total; });\n            candidates.resize(BEAM_WIDTH);\n        }\n        beam = move(candidates);\n    }\n    // select best final state\n    State best = *max_element(beam.begin(), beam.end(),\n                              [](const State& a, const State& b) { return a.total > b.total; });\n    return best.seq;\n}\n\n// Lookahead greedy with dynamic depth and pruning (kept for diversity)\nstring lookahead_greedy_sequence(int si, int sj, int ti, int tj, double p) {\n    double prob[20][20] = {};\n    prob[si][sj] = 1.0;\n    string s = \"\";\n    const int MAX_DEPTH = 4;   // reduced depth for speed\n    for (int t = 1; t <= 200; ++t) {\n        int remaining_after = 200 - t;\n        int lookahead = min(MAX_DEPTH - 1, remaining_after);\n        int terminal_rem = remaining_after - lookahead;\n        double best_score = -1e9;\n        int best_action = 0;\n\n        for (int first_a = 0; first_a < 4; ++first_a) {\n            double dist1[20][20];\n            double immediate;\n            apply_action(prob, first_a, t, ti, tj, p, dist1, immediate);\n            double best_continuation = -1e9;\n\n            function<void(int, double[20][20], double)> dfs = [&](int depth, double cur_dist[20][20], double cur_reward) {\n                if (depth == lookahead) {\n                    double term = (terminal_rem > 0) ? heuristic(cur_dist, terminal_rem) : 0.0;\n                    double total = cur_reward + term;\n                    if (total > best_continuation) best_continuation = total;\n                    return;\n                }\n                // compute total probability\n                double total_prob = 0.0;\n                for (int i = 0; i < 20; ++i)\n                    for (int j = 0; j < 20; ++j)\n                        total_prob += cur_dist[i][j];\n                if (total_prob < EPS) return;\n\n                int next_step = t + 1 + depth;\n                for (int a = 0; a < 4; ++a) {\n                    double new_dist[20][20];\n                    double add_reward;\n                    apply_action(cur_dist, a, next_step, ti, tj, p, new_dist, add_reward);\n                    dfs(depth + 1, new_dist, cur_reward + add_reward);\n                }\n            };\n\n            dfs(0, dist1, 0.0);\n            double total = immediate + best_continuation;\n            if (total > best_score) {\n                best_score = total;\n                best_action = first_a;\n            }\n        }\n        s += dir_char[best_action];\n        double new_prob[20][20];\n        double dummy;\n        apply_action(prob, best_action, t, ti, tj, p, new_prob, dummy);\n        memcpy(prob, new_prob, sizeof(prob));\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    vector<vector<int>> h(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 19; ++j) {\n            h[i][j] = line[j] - '0';\n        }\n    }\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 20; ++j) {\n            v[i][j] = line[j] - '0';\n        }\n    }\n\n    precompute_next(h, v);\n    compute_V(ti, tj, p);\n\n    string shortest_path = bfs_path(si, sj, ti, tj, h, v);\n    int k = shortest_path.size();\n\n    vector<string> candidates;\n\n    if (k > 0) {\n        candidates.push_back(shortest_path);\n        int t = 200 / k;\n        int rem = 200 % k;\n        string cand = \"\";\n        for (int i = 0; i < t; ++i) cand += shortest_path;\n        cand += shortest_path.substr(0, rem);\n        candidates.push_back(cand);\n        int m = 200 / k;\n        cand = \"\";\n        for (char c : shortest_path) {\n            for (int i = 0; i < m; ++i) cand += c;\n        }\n        candidates.push_back(cand);\n    }\n\n    candidates.push_back(greedy_nominal(si, sj, ti, tj, h, v));\n    candidates.push_back(alternating_string(si, sj, ti, tj, h, v));\n    candidates.push_back(lookahead_greedy_sequence(si, sj, ti, tj, p));\n    candidates.push_back(beam_search_sequence(si, sj, ti, tj, p));\n\n    double best_score = -1.0;\n    string best_str = \"\";\n    for (const string& cand : candidates) {\n        double score = simulate(cand, si, sj, ti, tj, p);\n        if (score > best_score) {\n            best_score = score;\n            best_str = cand;\n        }\n    }\n\n    cout << best_str << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\nconst int GREEDY_PASSES = 6;\nconst int SA_STEPS = 20000;\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};\n\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nint rotate(int t, int r) {\n    for (int i = 0; i < r; i++) {\n        if (t == 0) t = 1;\n        else if (t == 1) t = 2;\n        else if (t == 2) t = 3;\n        else if (t == 3) t = 0;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else if (t == 7) t = 6;\n    }\n    return t;\n}\n\npair<int, int> compute_two_longest(const vector<vector<int>>& tiles) {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\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                if (visited[i][j][d]) continue;\n                \n                int si = i, sj = j, sd = d;\n                int ci = i, cj = j, cd = d;\n                int length = 0;\n                \n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t = tiles[ci][cj];\n                    int d2 = to[t][cd];\n                    if (d2 == -1) break;\n                    \n                    ci += di[d2];\n                    cj += dj[d2];\n                    if (ci < 0 || ci >= N || cj < 0 || cj >= N) break;\n                    \n                    cd = (d2 + 2) % 4;\n                    length++;\n                    \n                    if (ci == si && cj == sj && cd == sd) {\n                        if (length > max1) {\n                            max2 = max1;\n                            max1 = length;\n                        } else if (length > max2) {\n                            max2 = length;\n                        }\n                        break;\n                    }\n                    \n                    if (length > 4 * N * N) break;\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> tiles(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    // Initialize rotations to 0\n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Greedy hill climbing phase\n    vector<pair<int, int>> all_tiles;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            all_tiles.emplace_back(i, j);\n        }\n    }\n    \n    auto [init_max1, init_max2] = compute_two_longest(tiles);\n    long long current_score = (long long)init_max1 * init_max2;\n    \n    for (int pass = 0; pass < GREEDY_PASSES; pass++) {\n        shuffle(all_tiles.begin(), all_tiles.end(), rng);\n        bool improved = false;\n        \n        for (auto [i, j] : all_tiles) {\n            int current_rot = rotations[i][j];\n            int original_type = tiles[i][j];\n            long long best_score_here = current_score;\n            int best_rot_here = current_rot;\n            \n            for (int rot = 0; rot < 4; rot++) {\n                if (rot == current_rot) continue;\n                \n                int diff = (rot - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                \n                auto [max1, max2] = compute_two_longest(tiles);\n                long long new_score = (long long)max1 * max2;\n                \n                if (new_score > best_score_here) {\n                    best_score_here = new_score;\n                    best_rot_here = rot;\n                }\n            }\n            \n            if (best_rot_here != current_rot) {\n                int diff = (best_rot_here - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                rotations[i][j] = best_rot_here;\n                current_score = best_score_here;\n                improved = true;\n            } else {\n                tiles[i][j] = original_type;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Simulated annealing phase\n    vector<vector<int>> best_rotations = rotations;\n    vector<vector<int>> best_tiles = tiles;\n    long long best_score = current_score;\n    \n    double temperature = 1000.0;\n    double cooling_rate = 0.9998;\n    \n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n    \n    for (int step = 0; step < SA_STEPS; step++) {\n        int i = pos_dist(rng);\n        int j = pos_dist(rng);\n        int old_rot = rotations[i][j];\n        int new_rot = rot_dist(rng);\n        \n        if (new_rot == old_rot) continue;\n        \n        int diff = (new_rot - old_rot + 4) % 4;\n        int old_type = tiles[i][j];\n        int new_type = rotate(old_type, diff);\n        \n        tiles[i][j] = new_type;\n        rotations[i][j] = new_rot;\n        \n        auto [new_max1, new_max2] = compute_two_longest(tiles);\n        long long new_score = (long long)new_max1 * new_max2;\n        \n        if (new_score > current_score || \n            rng() % 10000 < 10000 * exp((new_score - current_score) / temperature)) {\n            current_score = new_score;\n            \n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rotations = rotations;\n                best_tiles = tiles;\n            }\n        } else {\n            tiles[i][j] = old_type;\n            rotations[i][j] = old_rot;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    // Output the best rotations found\n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += '0' + best_rotations[i][j];\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <utility>\n#include <chrono>\n#include <limits>\n\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opposite[4] = {1, 0, 3, 2};\n\nstruct State {\n    int S;                 // size of the largest tree component\n    int edges_in_largest;  // edges in that component\n};\n\nState compute_state() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_vertices = 0;\n    int max_edges = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            if (visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int vertices = 0;\n            int edges = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                vertices++;\n                int mask = board[x][y];\n                for (int d = 0; d < 4; ++d) {\n                    if (!(mask & (1 << d))) continue;\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    int opp_mask = board[nx][ny];\n                    int opp_bit = 1 << opposite[d];\n                    if (opp_mask & opp_bit) {\n                        if (d == 1 || d == 3) {\n                            edges++;\n                        }\n                        if (!visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            if (edges == vertices - 1) { // tree\n                if (vertices > max_vertices) {\n                    max_vertices = vertices;\n                    max_edges = edges;\n                } else if (vertices == max_vertices && edges > max_edges) {\n                    max_edges = edges;\n                }\n            }\n        }\n    }\n    return {max_vertices, max_edges};\n}\n\nvector<char> get_valid_moves() {\n    vector<char> moves;\n    for (int d = 0; d < 4; ++d) {\n        int ni = empty_i + di[d];\n        int nj = empty_j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            moves.push_back(dir_char[d]);\n        }\n    }\n    return moves;\n}\n\nvoid apply_move(int d) {\n    int ni = empty_i + di[d];\n    int nj = empty_j + dj[d];\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nvoid undo_move(int d) {\n    apply_move(opposite[d]);\n}\n\npair<bool, string> simulated_annealing_run(mt19937& gen, uniform_real_distribution<>& dis, int max_iter) {\n    State current_state = compute_state();\n    int current_score = current_state.S * 1000000 + current_state.edges_in_largest;\n    string current_seq = \"\";\n    bool found_full_tree = false;\n    string full_tree_seq = \"\";\n    int best_S = current_state.S;\n    int best_edges = current_state.edges_in_largest;\n    string best_seq = current_seq;\n\n    double temp = 5.0;\n    double cooling = 0.999;\n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        vector<char> moves = get_valid_moves();\n        if (moves.empty()) break;\n        char move = moves[gen() % moves.size()];\n        int d;\n        for (int i = 0; i < 4; ++i) {\n            if (dir_char[i] == move) {\n                d = i;\n                break;\n            }\n        }\n        apply_move(d);\n        State new_state = compute_state();\n        int new_score = new_state.S * 1000000 + new_state.edges_in_largest;\n        double delta = new_score - current_score;\n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            current_state = new_state;\n            current_score = new_score;\n            current_seq += move;\n            if (new_state.S > best_S || (new_state.S == best_S && new_state.edges_in_largest > best_edges)) {\n                best_S = new_state.S;\n                best_edges = new_state.edges_in_largest;\n                best_seq = current_seq;\n            }\n            if (new_state.S == N * N - 1) {\n                if (!found_full_tree || current_seq.length() < full_tree_seq.length()) {\n                    found_full_tree = true;\n                    full_tree_seq = current_seq;\n                }\n                break;\n            }\n        } else {\n            undo_move(d);\n        }\n        temp *= cooling;\n    }\n\n    if (found_full_tree) {\n        return {true, full_tree_seq};\n    } else {\n        return {false, best_seq};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 2.8;\n    const int MAX_ITER_PER_RUN = 500; // keep runs short to allow many runs\n\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int init_empty_i, init_empty_j;\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            initial_board[i][j] = val;\n            if (val == 0) {\n                init_empty_i = i;\n                init_empty_j = j;\n            }\n        }\n    }\n\n    bool overall_full_tree = false;\n    string overall_best_seq = \"\";\n    int overall_best_S = 0;\n    int overall_best_edges = 0;\n    int overall_full_tree_len = numeric_limits<int>::max();\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed >= time_limit) break;\n\n        board = initial_board;\n        empty_i = init_empty_i;\n        empty_j = init_empty_j;\n\n        // limit iterations per run to min(T, MAX_ITER_PER_RUN)\n        int max_iter = min(T, MAX_ITER_PER_RUN);\n        auto [is_full, seq] = simulated_annealing_run(gen, dis, max_iter);\n\n        if (is_full) {\n            if (seq.length() < overall_full_tree_len) {\n                overall_full_tree = true;\n                overall_full_tree_len = seq.length();\n                overall_best_seq = seq;\n            }\n        } else {\n            // evaluate the sequence's final state\n            vector<vector<int>> temp_board = initial_board;\n            int temp_empty_i = init_empty_i, temp_empty_j = init_empty_j;\n            for (char c : seq) {\n                int d;\n                for (int i = 0; i < 4; ++i) {\n                    if (dir_char[i] == c) {\n                        d = i;\n                        break;\n                    }\n                }\n                int ni = temp_empty_i + di[d];\n                int nj = temp_empty_j + dj[d];\n                swap(temp_board[temp_empty_i][temp_empty_j], temp_board[ni][nj]);\n                temp_empty_i = ni;\n                temp_empty_j = nj;\n            }\n            vector<vector<int>> saved_board = board;\n            int saved_empty_i = empty_i, saved_empty_j = empty_j;\n            board = temp_board;\n            empty_i = temp_empty_i;\n            empty_j = temp_empty_j;\n            State final_state = compute_state();\n            board = saved_board;\n            empty_i = saved_empty_i;\n            empty_j = saved_empty_j;\n\n            if (final_state.S > overall_best_S ||\n                (final_state.S == overall_best_S && final_state.edges_in_largest > overall_best_edges)) {\n                overall_best_S = final_state.S;\n                overall_best_edges = final_state.edges_in_largest;\n                overall_best_seq = seq;\n            }\n        }\n    }\n\n    // ensure the output sequence length does not exceed T\n    if (overall_best_seq.length() > T) {\n        overall_best_seq = overall_best_seq.substr(0, T);\n    }\n    cout << overall_best_seq << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n#include <set>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\n// Global arrays\nint a[11]; // a[1]..a[10]\n\n// Compute the score for given vertical lines V and horizontal lines H\nint compute_score(const vector<int>& V, const vector<int>& H, const vector<pair<int,int>>& points) {\n    int p = V.size();\n    int q = H.size();\n    int total_cells = (p+1)*(q+1);\n    vector<int> cell_counts(total_cells, 0);\n    \n    // Create boundary arrays including cake boundaries (-10000 and 10000)\n    vector<int> V_all(p+2), H_all(q+2);\n    V_all[0] = -10000;\n    for (int i=0; i<p; ++i) V_all[i+1] = V[i];\n    V_all[p+1] = 10000;\n    H_all[0] = -10000;\n    for (int i=0; i<q; ++i) H_all[i+1] = H[i];\n    H_all[q+1] = 10000;\n    \n    // For each point, determine its cell\n    for (const auto& pt : points) {\n        int x = pt.first, y = pt.second;\n        // Find vertical interval index i such that V_all[i] < x < V_all[i+1]\n        auto it_x = upper_bound(V_all.begin(), V_all.end(), x);\n        // Since x is strictly between -10000 and 10000, it_x cannot be begin or end\n        int i = (it_x - V_all.begin()) - 1;\n        // Find horizontal interval index j\n        auto it_y = upper_bound(H_all.begin(), H_all.end(), y);\n        int j = (it_y - H_all.begin()) - 1;\n        int cell_idx = i * (q+1) + j;\n        cell_counts[cell_idx]++;\n    }\n    \n    // Compute b_d for d=1..10\n    vector<int> b(11, 0); // index 1..10\n    for (int cnt : cell_counts) {\n        if (1 <= cnt && cnt <= 10) {\n            b[cnt]++;\n        }\n    }\n    int score = 0;\n    for (int d=1; d<=10; ++d) {\n        score += min(a[d], b[d]);\n    }\n    return score;\n}\n\n// Check if a vertical line at position x is valid (does not pass through any point)\nbool is_valid_vertical(int x, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.first == x) return false;\n    }\n    return true;\n}\n\n// Check if a horizontal line at position y is valid\nbool is_valid_horizontal(int y, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.second == y) return false;\n    }\n    return true;\n}\n\n// Find a free integer coordinate for a line, starting from a candidate and exploring nearby integers\nint find_free(int cand, const vector<int>& lines, const vector<pair<int,int>>& points, bool is_vertical) {\n    for (int d=0; ; ++d) {\n        for (int sign : {0, 1, -1}) {\n            int pos = cand + sign * d;\n            if (pos < -10000 || pos > 10000) continue;\n            // Check not already used by another line\n            if (find(lines.begin(), lines.end(), pos) != lines.end()) continue;\n            // Check not on any point\n            if (is_vertical) {\n                if (!is_valid_vertical(pos, points)) continue;\n            } else {\n                if (!is_valid_horizontal(pos, points)) continue;\n            }\n            return pos;\n        }\n    }\n}\n\n// Flexible simulated annealing that allows changing orientation and adding/removing lines\npair<vector<int>, vector<int>> sa_optimize_flexible(int initial_p, int initial_q, const vector<pair<int,int>>& points, int max_lines, int iterations=1500) {\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    uniform_int_distribution<int> dist_move(0, 3); // 0: move line, 1: change orientation, 2: add line, 3: remove line\n    uniform_int_distribution<int> dist_offset(-100, 100);\n    \n    int N = points.size();\n    \n    // Initialize vertical lines\n    vector<int> V;\n    for (int i=1; i<=initial_p; ++i) {\n        // Simple initialization: evenly spaced from -10000 to 10000, avoiding points\n        int cand = -10000 + i * 20000 / (initial_p+1);\n        int pos = find_free(cand, V, points, true);\n        V.push_back(pos);\n    }\n    sort(V.begin(), V.end());\n    \n    // Initialize horizontal lines\n    vector<int> H;\n    for (int i=1; i<=initial_q; ++i) {\n        int cand = -10000 + i * 20000 / (initial_q+1);\n        int pos = find_free(cand, H, points, false);\n        H.push_back(pos);\n    }\n    sort(H.begin(), H.end());\n    \n    int cur_score = compute_score(V, H, points);\n    vector<int> bestV = V, bestH = H;\n    int best_score = cur_score;\n    \n    double temp = 1000.0;\n    double cooling = 0.999;\n    \n    for (int iter=0; iter<iterations; ++iter) {\n        int total_lines = V.size() + H.size();\n        int move_type = dist_move(rng);\n        bool vertical = (rng()%2 == 0); // for orientation change, which orientation to target\n        \n        if (move_type == 0 && total_lines > 0) {\n            // Move a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            \n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            int new_pos = cur_pos + dist_offset(rng);\n            if (new_pos < -10000 || new_pos > 10000) continue;\n            if (new_pos == cur_pos) continue;\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                newV[idx] = new_pos;\n                if (!is_valid_vertical(new_pos, points)) continue;\n                sort(newV.begin(), newV.end());\n                if (adjacent_find(newV.begin(), newV.end()) != newV.end()) continue;\n            } else {\n                newH[idx] = new_pos;\n                if (!is_valid_horizontal(new_pos, points)) continue;\n                sort(newH.begin(), newH.end());\n                if (adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 1 && total_lines > 0) {\n            // Change orientation of a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                // Change from vertical to horizontal\n                newV.erase(newV.begin() + idx);\n                // Check if cur_pos is valid as horizontal\n                if (!is_valid_horizontal(cur_pos, points)) continue;\n                // Check not already in H\n                if (find(newH.begin(), newH.end(), cur_pos) != newH.end()) continue;\n                newH.push_back(cur_pos);\n                sort(newH.begin(), newH.end());\n            } else {\n                // Change from horizontal to vertical\n                newH.erase(newH.begin() + idx);\n                if (!is_valid_vertical(cur_pos, points)) continue;\n                if (find(newV.begin(), newV.end(), cur_pos) != newV.end()) continue;\n                newV.push_back(cur_pos);\n                sort(newV.begin(), newV.end());\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 2 && total_lines < max_lines) {\n            // Add a line (randomly vertical or horizontal)\n            bool add_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            // Generate a candidate position\n            int cand = -10000 + rng()%20001;\n            if (add_vertical) {\n                int pos = find_free(cand, newV, points, true);\n                newV.push_back(pos);\n                sort(newV.begin(), newV.end());\n            } else {\n                int pos = find_free(cand, newH, points, false);\n                newH.push_back(pos);\n                sort(newH.begin(), newH.end());\n            }\n            // Check for duplicates\n            if (adjacent_find(newV.begin(), newV.end()) != newV.end() ||\n                adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 3 && total_lines > 1) {\n            // Remove a line\n            bool remove_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (remove_vertical && !newV.empty()) {\n                int idx = rng() % newV.size();\n                newV.erase(newV.begin() + idx);\n            } else if (!newH.empty()) {\n                int idx = rng() % newH.size();\n                newH.erase(newH.begin() + idx);\n            } else {\n                continue; // cannot remove\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        }\n        temp *= cooling;\n    }\n    return {bestV, bestH};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, K;\n    cin >> N >> K;\n    for (int d=1; d<=10; ++d) cin >> a[d];\n    \n    vector<pair<int,int>> points(N);\n    for (int i=0; i<N; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Try a few initial splits and run flexible SA on each\n    vector<pair<int,int>> initial_splits = {{0,0}, {25,25}, {50,0}, {0,50}, {50,50}, {75,25}, {25,75}};\n    int best_total_score = -1;\n    vector<int> bestV, bestH;\n    \n    for (auto [p,q] : initial_splits) {\n        if (p+q > K) continue;\n        auto [V, H] = sa_optimize_flexible(p, q, points, K, 1500);\n        int score = compute_score(V, H, points);\n        if (score > best_total_score) {\n            best_total_score = score;\n            bestV = V;\n            bestH = H;\n        }\n    }\n    \n    // Output\n    cout << bestV.size() + bestH.size() << '\\n';\n    // Vertical lines\n    for (int x : bestV) {\n        cout << x << \" \" << -10000 << \" \" << x << \" \" << 10000 << '\\n';\n    }\n    // Horizontal lines\n    for (int y : bestH) {\n        cout << -10000 << \" \" << y << \" \" << 10000 << \" \" << y << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <ctime>\n#include <array>\n#include <cstring>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\n// Encode a unit segment into a 32-bit integer (canonical order)\nuint32_t encode_seg(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    return (x1 << 18) | (y1 << 12) | (x2 << 6) | y2;\n}\n\n// Check condition 2 for axis-aligned rectangle\nbool check_perimeter_axis(int x1, int y1, int x2, int y2, const vector<vector<bool>>& dot_grid) {\n    for (int y = y1 + 1; y < y2; ++y) {\n        if (dot_grid[x1][y] || dot_grid[x2][y])\n            return false;\n    }\n    for (int x = x1 + 1; x < x2; ++x) {\n        if (dot_grid[x][y1] || dot_grid[x][y2])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for axis-aligned rectangle\nbool check_used_segments_axis(int x1, int y1, int x2, int y2, const unordered_set<uint32_t>& used_segments) {\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x1, y, x1, y + 1)))\n            return false;\n        if (used_segments.count(encode_seg(x2, y, x2, y + 1)))\n            return false;\n    }\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y1, x + 1, y1)))\n            return false;\n        if (used_segments.count(encode_seg(x, y2, x + 1, y2)))\n            return false;\n    }\n    return true;\n}\n\n// Check condition 2 for 45-degree rectangle\nbool check_perimeter_45(int x, int y, int a, int b, const vector<vector<bool>>& dot_grid) {\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + i][y + i])\n            return false;\n    }\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + a + i][y + a - i])\n            return false;\n    }\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + a + b - i][y + a - b - i])\n            return false;\n    }\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + b - i][y - b + i])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for 45-degree rectangle\nbool check_used_segments_45(int x, int y, int a, int b, const unordered_set<uint32_t>& used_segments) {\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + i, y + i, x + i + 1, y + i + 1)))\n            return false;\n    }\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + a + i, y + a - i, x + a + i + 1, y + a - i - 1)))\n            return false;\n    }\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + a + b - i, y + a - b - i, x + a + b - i - 1, y + a - b - i - 1)))\n            return false;\n    }\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + b - i, y - b + i, x + b - i - 1, y - b + i + 1)))\n            return false;\n    }\n    return true;\n}\n\n// Add all unit segments of a rectangle to used_segments\nvoid add_rectangle_segments(const array<int, 8>& op, unordered_set<uint32_t>& used_segments) {\n    for (int k = 0; k < 4; ++k) {\n        int k2 = (k + 1) % 4;\n        int x1 = op[2*k], y1 = op[2*k+1];\n        int x2 = op[2*k2], y2 = op[2*k2+1];\n        \n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        int sx = (dx == 0) ? 0 : (dx > 0 ? 1 : -1);\n        int sy = (dy == 0) ? 0 : (dy > 0 ? 1 : -1);\n        int num_steps = max(abs(dx), abs(dy));\n        \n        for (int step = 0; step < num_steps; ++step) {\n            int cur_x = x1 + step * sx;\n            int cur_y = y1 + step * sy;\n            int next_x = cur_x + sx;\n            int next_y = cur_y + sy;\n            used_segments.insert(encode_seg(cur_x, cur_y, next_x, next_y));\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    vector<Point> initial(M);\n    vector<vector<bool>> dot_grid(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        cin >> initial[i].x >> initial[i].y;\n        dot_grid[initial[i].x][initial[i].y] = true;\n    }\n\n    vector<Point> dots = initial;\n    unordered_set<uint32_t> used_segments;\n    vector<array<int, 8>> operations;\n\n    int c = (N - 1) / 2;\n    int max_weight = 2 * c * c + 1;\n    clock_t start_time = clock();\n\n    while (true) {\n        if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.5)\n            break;\n\n        int best_weight = -1;\n        int best_size = 1000000;  // Initialize to a large number\n        array<int, 8> best_op;\n        bool found = false;\n        bool found_corner = false;\n\n        int Mcurr = dots.size();\n        for (int i = 0; i < Mcurr && !found_corner; ++i) {\n            for (int j = i + 1; j < Mcurr && !found_corner; ++j) {\n                Point A = dots[i], B = dots[j];\n\n                // ---------- Axis-aligned rectangle ----------\n                int x1 = min(A.x, B.x), x2 = max(A.x, B.x);\n                int y1 = min(A.y, B.y), y2 = max(A.y, B.y);\n                if (x1 < x2 && y1 < y2) {\n                    bool c1 = dot_grid[x1][y1];\n                    bool c2 = dot_grid[x1][y2];\n                    bool c3 = dot_grid[x2][y1];\n                    bool c4 = dot_grid[x2][y2];\n                    int cnt = c1 + c2 + c3 + c4;\n                    if (cnt == 3) {\n                        Point D;\n                        if (!c1) D = {x1, y1};\n                        else if (!c2) D = {x1, y2};\n                        else if (!c3) D = {x2, y1};\n                        else D = {x2, y2};\n\n                        if (check_perimeter_axis(x1, y1, x2, y2, dot_grid) &&\n                            check_used_segments_axis(x1, y1, x2, y2, used_segments)) {\n                            int w = (D.x - c) * (D.x - c) + (D.y - c) * (D.y - c) + 1;\n                            // Calculate rectangle size (number of unit segments)\n                            int dx = x2 - x1;\n                            int dy = y2 - y1;\n                            int size = 2 * (dx + dy);\n                            \n                            if (w == max_weight) {\n                                best_weight = w;\n                                best_size = size;\n                                array<Point, 4> corners;\n                                corners[0] = {x1, y1};\n                                corners[1] = {x1, y2};\n                                corners[2] = {x2, y2};\n                                corners[3] = {x2, y1};\n                                \n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                                found_corner = true;\n                                break;\n                            } else if (w > best_weight || (w == best_weight && size < best_size)) {\n                                best_weight = w;\n                                best_size = size;\n                                array<Point, 4> corners;\n                                corners[0] = {x1, y1};\n                                corners[1] = {x1, y2};\n                                corners[2] = {x2, y2};\n                                corners[3] = {x2, y1};\n                                \n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                            }\n                        }\n                    }\n                }\n\n                // ---------- 45-degree rectangle ----------\n                for (int order = 0; order < 2 && !found_corner; ++order) {\n                    Point start = (order == 0) ? A : B;\n                    Point opposite = (order == 0) ? B : A;\n                    int dx = opposite.x - start.x;\n                    int dy = opposite.y - start.y;\n                    int sum_diff = dx + dy;\n                    int sub_diff = dx - dy;\n                    if (sum_diff % 2 != 0 || sub_diff % 2 != 0) continue;\n                    int a = sum_diff / 2;\n                    int b = sub_diff / 2;\n                    if (a <= 0 || b <= 0) continue;\n\n                    Point C = {start.x + a, start.y + a};\n                    Point D = {start.x + b, start.y - b};\n                    if (C.x < 0 || C.x >= N || C.y < 0 || C.y >= N ||\n                        D.x < 0 || D.x >= N || D.y < 0 || D.y >= N) continue;\n\n                    bool cC = dot_grid[C.x][C.y];\n                    bool cD = dot_grid[D.x][D.y];\n                    if (cC + cD != 1) continue;\n\n                    Point missing = cC ? D : C;\n                    \n                    array<Point, 4> corners;\n                    corners[0] = start;\n                    corners[1] = C;\n                    corners[2] = opposite;\n                    corners[3] = D;\n\n                    if (check_perimeter_45(start.x, start.y, a, b, dot_grid) &&\n                        check_used_segments_45(start.x, start.y, a, b, used_segments)) {\n                        int w = (missing.x - c) * (missing.x - c) + (missing.y - c) * (missing.y - c) + 1;\n                        // Calculate rectangle size for 45-degree rectangle\n                        int size = 2 * (a + b);\n                        \n                        if (w == max_weight) {\n                            best_weight = w;\n                            best_size = size;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                            found_corner = true;\n                            break;\n                        } else if (w > best_weight || (w == best_weight && size < best_size)) {\n                            best_weight = w;\n                            best_size = size;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (!found) break;\n\n        operations.push_back(best_op);\n        Point new_dot = {best_op[0], best_op[1]};\n        dot_grid[new_dot.x][new_dot.y] = true;\n        dots.push_back(new_dot);\n        add_rectangle_segments(best_op, used_segments);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            cout << op[i];\n            if (i < 7) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int SIZE = 10;\nusing Grid = vector<vector<int>>; // 1\u2011indexed, 11x11\n\n// Apply a tilt in the given direction and return the new grid.\nGrid apply_tilt(const Grid& grid, char dir) {\n    Grid new_grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n    if (dir == 'L') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][i + 1] = flavors[i];\n        }\n    } else if (dir == 'R') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][SIZE - k + 1 + i] = flavors[i];\n        }\n    } else if (dir == 'F') { // forward = up\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[i + 1][c] = flavors[i];\n        }\n    } else { // 'B' \u2013 backward = down\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[SIZE - k + 1 + i][c] = flavors[i];\n        }\n    }\n    return new_grid;\n}\n\n// Evaluate a grid using a combined heuristic: connectivity + compactness.\ndouble evaluate_state(const Grid& grid) {\n    bool visited[SIZE + 1][SIZE + 1] = {false};\n    long long connectivity = 0;\n    const int dr[] = {1, -1, 0, 0};\n    const int dc[] = {0, 0, 1, -1};\n\n    // Compute connectivity (sum of squares of component sizes).\n    for (int r = 1; r <= SIZE; ++r) {\n        for (int c = 1; c <= SIZE; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                vector<pair<int, int>> queue = {{r, c}};\n                visited[r][c] = true;\n                int idx = 0;\n                while (idx < queue.size()) {\n                    auto [cr, cc] = queue[idx++];\n                    ++size;\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = cr + dr[d];\n                        int nc = cc + dc[d];\n                        if (nr >= 1 && nr <= SIZE && nc >= 1 && nc <= SIZE &&\n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            queue.push_back({nr, nc});\n                        }\n                    }\n                }\n                connectivity += (long long)size * size;\n            }\n        }\n    }\n\n    // Compute compactness (density of each flavor's bounding box).\n    double compactness = 0.0;\n    for (int flavor = 1; flavor <= 3; ++flavor) {\n        int min_r = SIZE + 1, max_r = 0, min_c = SIZE + 1, max_c = 0;\n        int count = 0;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == flavor) {\n                    ++count;\n                    min_r = min(min_r, r);\n                    max_r = max(max_r, r);\n                    min_c = min(min_c, c);\n                    max_c = max(max_c, c);\n                }\n            }\n        }\n        if (count > 0) {\n            int area = (max_r - min_r + 1) * (max_c - min_c + 1);\n            compactness += (double)count / area;\n        }\n    }\n\n    const double beta = 1000.0; // weight for compactness\n    return connectivity + beta * compactness;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) cin >> f[i];\n\n    Grid grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n\n    for (int t = 1; t <= 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Locate the p\u2011th empty cell (front\u2011to\u2011back, left\u2011to\u2011right).\n        int count = 0;\n        int placed_r = -1, placed_c = -1;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == 0) {\n                    ++count;\n                    if (count == p) {\n                        placed_r = r;\n                        placed_c = c;\n                        break;\n                    }\n                }\n            }\n            if (placed_r != -1) break;\n        }\n        grid[placed_r][placed_c] = f[t];\n\n        if (t == 100) break; // last candy \u2013 no tilt needed\n\n        // One\u2011step lookahead with combined heuristic.\n        char best_dir = 'F';\n        double best_expected = -1.0;\n\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid grid1 = apply_tilt(grid, dir);\n\n            // Collect empty cells in grid1.\n            vector<pair<int, int>> empties;\n            for (int r = 1; r <= SIZE; ++r)\n                for (int c = 1; c <= SIZE; ++c)\n                    if (grid1[r][c] == 0) empties.emplace_back(r, c);\n\n            double total = 0.0;\n            for (auto [r, c] : empties) {\n                Grid grid2 = grid1;\n                grid2[r][c] = f[t + 1];\n\n                double best_next = 0.0;\n                for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                    Grid grid3 = apply_tilt(grid2, next_dir);\n                    double sc = evaluate_state(grid3);\n                    if (sc > best_next) best_next = sc;\n                }\n                total += best_next;\n            }\n            double expected = total / empties.size();\n            if (expected > best_expected) {\n                best_expected = expected;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        grid = apply_tilt(grid, best_dir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Precompute expected sorted degree lists for each possible a (1..N)\n    vector<vector<double>> exp_sorted(N + 1);\n    for (int a = 1; a <= N; ++a) {\n        vector<double> degs;\n        if (a == N) {\n            double mu = (N - 1) * (1 - epsilon);\n            degs.assign(N, mu);\n        } else {\n            double muA = (a - 1) * (1 - epsilon) + (N - a) * epsilon;\n            double muB = (N - a - 1) * (1 - epsilon) + a * epsilon;\n            for (int i = 0; i < a; ++i) degs.push_back(muA);\n            for (int i = 0; i < N - a; ++i) degs.push_back(muB);\n            sort(degs.begin(), degs.end());\n        }\n        exp_sorted[a] = degs;\n    }\n\n    // Precompute squared distances between any two a\n    vector<vector<double>> dist(N + 1, vector<double>(N + 1, 0.0));\n    for (int a1 = 1; a1 <= N; ++a1) {\n        for (int a2 = a1 + 1; a2 <= N; ++a2) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = exp_sorted[a1][i] - exp_sorted[a2][i];\n                d += diff * diff;\n            }\n            dist[a1][a2] = d;\n            dist[a2][a1] = d;\n        }\n    }\n\n    // Greedy selection of M a values\n    vector<int> selected;\n    selected.push_back(50);  // start with middle\n    vector<bool> used(N + 1, false);\n    used[50] = true;\n    for (int step = 1; step < M; ++step) {\n        int best_a = -1;\n        double best_min_dist = -1.0;\n        for (int a = 1; a <= N; ++a) {\n            if (used[a]) continue;\n            double min_dist = 1e18;\n            for (int b : selected) {\n                min_dist = min(min_dist, dist[a][b]);\n            }\n            if (min_dist > best_min_dist) {\n                best_min_dist = min_dist;\n                best_a = a;\n            }\n        }\n        selected.push_back(best_a);\n        used[best_a] = true;\n    }\n\n    // Sort selected a in increasing order for output order\n    sort(selected.begin(), selected.end());\n\n    // Create mapping from a to index\n    vector<int> index_of_a(N + 1, -1);\n    for (int i = 0; i < M; ++i) {\n        index_of_a[selected[i]] = i;\n    }\n\n    // Output N\n    cout << N << endl;\n\n    // Output M graphs\n    for (int a : selected) {\n        string graph;\n        graph.resize(N * (N - 1) / 2, '0');\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool same_clique = false;\n                if (a == N) {\n                    same_clique = true; // complete graph\n                } else {\n                    if (i < a && j < a) same_clique = true;\n                    else if (i >= a && j >= a) same_clique = true;\n                }\n                if (same_clique) graph[pos] = '1';\n                pos++;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        // Compute degrees\n        vector<int> deg(N, 0);\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[pos] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                pos++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n\n        // Find the a with minimum squared distance\n        int best_idx = -1;\n        double best_dist = 1e18;\n        for (int a : selected) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = deg[i] - exp_sorted[a][i];\n                d += diff * diff;\n            }\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = index_of_a[a];\n            }\n        }\n\n        cout << best_idx << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll INF = 1e18;\nconst int MAXN = 1000;\n\nint N, M, D, K;\nvector<vector<pair<int, int>>> adj; // neighbor, edge index\nvector<int> u, v, w;\nvector<double> mid_x, mid_y;\nvector<ll> cnt;\nvector<vector<char>> removed; // removed[day][edge]\nvector<int> day_assign;\nvector<ll> day_sum; // sum of cnt per day\nvector<int> day_cnt;\nvector<double> sum_mid_x, sum_mid_y;\n\nint vis[MAXN];\nint cur_mark = 0;\n\nbool isConnected(int d) {\n    cur_mark++;\n    queue<int> q;\n    q.push(0);\n    vis[0] = cur_mark;\n    int count = 1;\n    while (!q.empty()) {\n        int node = q.front(); q.pop();\n        for (auto [nbr, eidx] : adj[node]) {\n            if (removed[d][eidx]) continue;\n            if (vis[nbr] != cur_mark) {\n                vis[nbr] = cur_mark;\n                q.push(nbr);\n                count++;\n            }\n        }\n    }\n    return count == N;\n}\n\n// Function to run Dijkstra with specific tie-breaking rule and update cnt\nvoid dijkstra(int s, vector<ll>& cnt_add, int tie_rule) {\n    vector<ll> dist(N, INF);\n    vector<int> parent(N, -1);\n    dist[s] = 0;\n    // Priority queue: (distance, node)\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        if (d != dist[node]) continue;\n        for (auto [nbr, weight] : adj[node]) {\n            ll nd = d + weight;\n            if (nd < dist[nbr]) {\n                dist[nbr] = nd;\n                parent[nbr] = node;\n                pq.emplace(nd, nbr);\n            } else if (nd == dist[nbr]) {\n                // Apply tie-breaking rule\n                if (tie_rule == 0) { // Prefer smaller neighbor ID\n                    if (node < parent[nbr]) parent[nbr] = node;\n                } else if (tie_rule == 1) { // Prefer larger neighbor ID\n                    if (node > parent[nbr]) parent[nbr] = node;\n                } else { // Prefer larger edge weight (if tie, smaller ID)\n                    if (parent[nbr] == -1 || \n                        weight > w[node] || \n                        (weight == w[node] && node < parent[nbr])) {\n                        parent[nbr] = node;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Build tree and compute sizes\n    vector<vector<int>> tree(N);\n    for (int v = 0; v < N; ++v) {\n        if (v == s) continue;\n        int p = parent[v];\n        if (p == -1) continue; // Should not happen in connected graph\n        tree[p].push_back(v);\n        tree[v].push_back(p);\n    }\n    \n    vector<int> order;\n    vector<bool> visited(N, false);\n    stack<int> stk;\n    stk.push(s);\n    visited[s] = true;\n    while (!stk.empty()) {\n        int node = stk.top(); stk.pop();\n        order.push_back(node);\n        for (int nbr : tree[node]) {\n            if (!visited[nbr]) {\n                visited[nbr] = true;\n                stk.push(nbr);\n            }\n        }\n    }\n    \n    vector<int> sz(N, 0);\n    for (int i = order.size()-1; i >= 0; --i) {\n        int node = order[i];\n        sz[node] = 1;\n        for (int nbr : tree[node]) {\n            if (nbr == s) continue;\n            if (parent[nbr] == node) {\n                sz[node] += sz[nbr];\n            }\n        }\n    }\n    \n    // Add contributions to cnt_add\n    for (int v = 0; v < N; ++v) {\n        if (v == s) continue;\n        int p = parent[v];\n        if (p == -1) continue;\n        // Find edge index between p and v\n        for (auto [nbr, eidx] : adj[p]) {\n            if (nbr == v) {\n                cnt_add[eidx] += sz[v];\n                break;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> D >> K;\n    u.resize(M); v.resize(M); w.resize(M);\n    adj.resize(N);\n    vector<vector<int>> edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        edge_idx[u[i]][v[i]] = i;\n        edge_idx[v[i]][u[i]] = i;\n        adj[u[i]].emplace_back(v[i], i);\n        adj[v[i]].emplace_back(u[i], i);\n    }\n\n    vector<int> coord_x(N), coord_y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coord_x[i] >> coord_y[i];\n    }\n\n    mid_x.resize(M); mid_y.resize(M);\n    for (int i = 0; i < M; ++i) {\n        mid_x[i] = (coord_x[u[i]] + coord_x[v[i]]) * 0.5;\n        mid_y[i] = (coord_y[u[i]] + coord_y[v[i]]) * 0.5;\n    }\n\n    // Criticality (cnt) for each edge using three tie-breaking rules\n    cnt.assign(M, 0);\n    for (int s = 0; s < N; ++s) {\n        vector<ll> cnt_temp(M, 0);\n        // Run Dijkstra with three different tie-breaking rules\n        dijkstra(s, cnt_temp, 0); // smaller neighbor ID\n        dijkstra(s, cnt_temp, 1); // larger neighbor ID\n        dijkstra(s, cnt_temp, 2); // larger edge weight\n        \n        // Average and add to total cnt\n        for (int i = 0; i < M; ++i) {\n            cnt[i] += cnt_temp[i] / 3;\n        }\n    }\n\n    // Initialize day structures\n    day_assign.assign(M, -1);\n    day_sum.assign(D, 0);\n    day_cnt.assign(D, 0);\n    sum_mid_x.assign(D, 0.0);\n    sum_mid_y.assign(D, 0.0);\n    removed.assign(D, vector<char>(M, 0));\n\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n    sort(order_edges.begin(), order_edges.end(),\n         [&](int a, int b) { return cnt[a] > cnt[b]; });\n\n    for (int e : order_edges) {\n        // Collect all days with free slots\n        vector<int> candidates;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K) {\n                candidates.push_back(d);\n            }\n        }\n\n        // Among candidates, find those that keep connectivity\n        vector<int> connected_days;\n        for (int d : candidates) {\n            removed[d][e] = 1;\n            if (isConnected(d)) {\n                connected_days.push_back(d);\n            }\n            removed[d][e] = 0;\n        }\n\n        int best_day = -1;\n        double best_dist2 = -1.0;\n\n        if (!connected_days.empty()) {\n            // Among connected days, choose the one with smallest day_sum, then largest distance\n            ll min_sum = INF;\n            for (int d : connected_days) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                }\n            }\n            vector<int> best_candidates;\n            for (int d : connected_days) {\n                if (day_sum[d] == min_sum) {\n                    best_candidates.push_back(d);\n                }\n            }\n            if (best_candidates.size() == 1) {\n                best_day = best_candidates[0];\n            } else {\n                // tie-break by distance\n                for (int d : best_candidates) {\n                    double dist2;\n                    if (day_cnt[d] == 0) {\n                        dist2 = 1e18;\n                    } else {\n                        double avg_x = sum_mid_x[d] / day_cnt[d];\n                        double avg_y = sum_mid_y[d] / day_cnt[d];\n                        double dx = mid_x[e] - avg_x;\n                        double dy = mid_y[e] - avg_y;\n                        dist2 = dx*dx + dy*dy;\n                    }\n                    if (best_day == -1 || dist2 > best_dist2) {\n                        best_dist2 = dist2;\n                        best_day = d;\n                    }\n                }\n            }\n        } else {\n            // No day keeps connectivity; fallback to day with smallest day_sum\n            ll min_sum = INF;\n            for (int d : candidates) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                    best_day = d;\n                }\n            }\n        }\n\n        // Assign edge to best_day\n        day_assign[e] = best_day;\n        day_sum[best_day] += cnt[e];\n        day_cnt[best_day]++;\n        sum_mid_x[best_day] += mid_x[e];\n        sum_mid_y[best_day] += mid_y[e];\n        removed[best_day][e] = 1;\n    }\n\n    // Output\n    for (int i = 0; i < M; ++i) {\n        cout << day_assign[i] + 1;\n        if (i < M - 1) cout << ' ';\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\n\n// generate minimal object from silhouette pair (simple edge cover)\nvector<array<int,3>> generate_object(const vector<string>& f, const vector<string>& r) {\n    vector<array<int,3>> cubes;\n    for (int z = 0; z < D; ++z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (f[z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (r[z][y] == '1') Y.push_back(y);\n        if (X.empty() || Y.empty()) continue;\n        if (X.size() <= Y.size()) {\n            for (size_t i = 0; i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            for (size_t i = X.size(); i < Y.size(); ++i) {\n                cubes.push_back({X[0], Y[i], z});\n            }\n        } else {\n            for (size_t i = 0; i < Y.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            for (size_t i = Y.size(); i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[0], z});\n            }\n        }\n    }\n    return cubes;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D;\n\n    // read silhouettes\n    vector<string> f0(D), r0(D), f1(D), r1(D);\n    for (int i = 0; i < D; ++i) cin >> f0[i];\n    for (int i = 0; i < D; ++i) cin >> r0[i];\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n\n    // minimal objects\n    auto cubes0 = generate_object(f0, r0);\n    auto cubes1 = generate_object(f1, r1);\n    int V0 = cubes0.size(), V1 = cubes1.size();\n\n    // map coordinates to indices for quick neighbor lookup\n    vector<vector<vector<int>>> idx0(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    vector<vector<vector<int>>> idx1(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    for (int i = 0; i < V0; ++i) {\n        auto& p = cubes0[i];\n        idx0[p[0]][p[1]][p[2]] = i;\n    }\n    for (int i = 0; i < V1; ++i) {\n        auto& p = cubes1[i];\n        idx1[p[0]][p[1]][p[2]] = i;\n    }\n\n    // find dominos (pairs of adjacent cubes) in each object\n    vector<bool> used0(V0, false), used1(V1, false);\n    vector<pair<int,int>> dom0, dom1;\n    // directions: +x, +y, +z\n    const int dx[3] = {1, 0, 0};\n    const int dy[3] = {0, 1, 0};\n    const int dz[3] = {0, 0, 1};\n\n    for (int i = 0; i < V0; ++i) {\n        if (used0[i]) continue;\n        auto& p = cubes0[i];\n        for (int d = 0; d < 3; ++d) {\n            int nx = p[0] + dx[d], ny = p[1] + dy[d], nz = p[2] + dz[d];\n            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n            int j = idx0[nx][ny][nz];\n            if (j == -1 || used0[j]) continue;\n            // take this domino\n            dom0.emplace_back(i, j);\n            used0[i] = used0[j] = true;\n            break;\n        }\n    }\n\n    for (int i = 0; i < V1; ++i) {\n        if (used1[i]) continue;\n        auto& p = cubes1[i];\n        for (int d = 0; d < 3; ++d) {\n            int nx = p[0] + dx[d], ny = p[1] + dy[d], nz = p[2] + dz[d];\n            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n            int j = idx1[nx][ny][nz];\n            if (j == -1 || used1[j]) continue;\n            dom1.emplace_back(i, j);\n            used1[i] = used1[j] = true;\n            break;\n        }\n    }\n\n    // block assignment arrays\n    vector<int> block0(V0, 0), block1(V1, 0);\n    int block_counter = 0;\n\n    // match shared dominos\n    int M = min(dom0.size(), dom1.size());\n    for (int i = 0; i < M; ++i) {\n        int id = ++block_counter;\n        auto& p0 = dom0[i];\n        block0[p0.first] = block0[p0.second] = id;\n        auto& p1 = dom1[i];\n        block1[p1.first] = block1[p1.second] = id;\n    }\n\n    // collect remaining unused cubes\n    vector<int> rem0, rem1;\n    for (int i = 0; i < V0; ++i) if (!block0[i]) rem0.push_back(i);\n    for (int i = 0; i < V1; ++i) if (!block1[i]) rem1.push_back(i);\n\n    // shared unit blocks\n    int U = min(rem0.size(), rem1.size());\n    for (int i = 0; i < U; ++i) {\n        int id = ++block_counter;\n        block0[rem0[i]] = block1[rem1[i]] = id;\n    }\n\n    // single-use unit blocks in object0\n    for (int i = U; i < rem0.size(); ++i) {\n        int id = ++block_counter;\n        block0[rem0[i]] = id;\n    }\n\n    // single-use unit blocks in object1\n    for (int i = U; i < rem1.size(); ++i) {\n        int id = ++block_counter;\n        block1[rem1[i]] = id;\n    }\n\n    int N = block_counter;\n\n    // build output arrays\n    vector<int> b0(D * D * D, 0), b1(D * D * D, 0);\n    for (int i = 0; i < V0; ++i) {\n        auto& p = cubes0[i];\n        b0[p[0] * D * D + p[1] * D + p[2]] = block0[i];\n    }\n    for (int i = 0; i < V1; ++i) {\n        auto& p = cubes1[i];\n        b1[p[0] * D * D + p[1] * D + p[2]] = block1[i];\n    }\n\n    // output\n    cout << N << '\\n';\n    for (size_t i = 0; i < b0.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b0[i];\n    }\n    cout << '\\n';\n    for (size_t i = 0; i < b1.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <map>\n#include <set>\n#include <random>\n#include <climits>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nconst double EPS = 1e-9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    for (int i = 0; i < N; ++i) distV[i][i] = 0;\n\n    vector<tuple<int, int, long long>> edges(M);\n    map<pair<int, int>, int> edgeIndex;\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[j] = {u, v, w};\n        if (u > v) swap(u, v);\n        edgeIndex[{u, v}] = j;\n        distV[u][v] = min(distV[u][v], w);\n        distV[v][u] = min(distV[v][u], w);\n    }\n\n    vector<vector<int>> next(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i != j && distV[i][j] < INF) {\n                next[i][j] = j;\n            }\n        }\n    }\n\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][k] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[k][j] == INF) continue;\n                if (distV[i][j] > distV[i][k] + distV[k][j]) {\n                    distV[i][j] = distV[i][k] + distV[k][j];\n                    next[i][j] = next[i][k];\n                }\n            }\n        }\n    }\n\n    vector<double> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    vector<vector<double>> distVtoR(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            distVtoR[i][k] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Precompute candidate vertices for each resident (30 nearest Euclidean + root)\n    vector<vector<int>> candidateVertices(K);\n    for (int k = 0; k < K; ++k) {\n        vector<pair<double, int>> distances;\n        for (int i = 0; i < N; ++i) {\n            distances.push_back({distVtoR[i][k], i});\n        }\n        sort(distances.begin(), distances.end());\n        for (int t = 0; t < min(30, N); ++t) {\n            candidateVertices[k].push_back(distances[t].second);\n        }\n        // Ensure root is included\n        if (find(candidateVertices[k].begin(), candidateVertices[k].end(), 0) == candidateVertices[k].end()) {\n            candidateVertices[k].push_back(0);\n        }\n        // Remove duplicates (though unlikely)\n        sort(candidateVertices[k].begin(), candidateVertices[k].end());\n        candidateVertices[k].erase(unique(candidateVertices[k].begin(), candidateVertices[k].end()), candidateVertices[k].end());\n    }\n\n    vector<multiset<double>> distSets(N);\n    vector<vector<int>> residentList(N);\n    vector<int> assign(K);\n    vector<int> P(N, 0);\n    long long sumSq = 0;\n\n    // Initial assignment to nearest vertex\n    for (int k = 0; k < K; ++k) {\n        int best = 0;\n        for (int i = 1; i < N; ++i) {\n            if (distVtoR[i][k] < distVtoR[best][k] - EPS) {\n                best = i;\n            }\n        }\n        assign[k] = best;\n        distSets[best].insert(distVtoR[best][k]);\n        residentList[best].push_back(k);\n    }\n\n    // Compute initial P[i]\n    for (int i = 0; i < N; ++i) {\n        if (!distSets[i].empty()) {\n            double maxDist = *distSets[i].rbegin();\n            P[i] = (int)ceil(maxDist);\n            if (P[i] > 5000) P[i] = 5000;\n        } else {\n            P[i] = 0;\n        }\n        sumSq += (long long)P[i] * P[i];\n    }\n\n    // Cache for actual connection cost\n    map<vector<int>, long long> costCache;\n\n    // Lambda to compute actual connection cost (sum of edge weights of Steiner tree)\n    auto computeActualConnectionCost = [&](const vector<int>& T) -> long long {\n        if (T.size() <= 1) return 0;\n        // Use sorted vector as cache key\n        vector<int> sortedT = T;\n        sort(sortedT.begin(), sortedT.end());\n        auto it = costCache.find(sortedT);\n        if (it != costCache.end()) return it->second;\n        \n        // Step 1: MST on metric closure\n        int n = sortedT.size();\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[sortedT[u]][sortedT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        // Step 2: Collect unique edges from paths of MST edges\n        set<pair<int, int>> edgeSet;\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u == -1) continue;\n            int from = sortedT[u], to = sortedT[v];\n            int cur = from;\n            while (cur != to) {\n                int nxt = next[cur][to];\n                int a = cur, b = nxt;\n                if (a > b) swap(a, b);\n                edgeSet.insert({a, b});\n                cur = nxt;\n            }\n        }\n        // Step 3: Sum weights of these edges\n        long long total = 0;\n        for (auto& e : edgeSet) {\n            int idx = edgeIndex[e];\n            total += get<2>(edges[idx]);\n        }\n        costCache[sortedT] = total;\n        return total;\n    };\n\n    // Build initial T (root + vertices with P>0)\n    vector<int> currentT;\n    currentT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            currentT.push_back(i);\n        }\n    }\n    long long currentActualCost = computeActualConnectionCost(currentT);\n    long long currentCost = sumSq + currentActualCost;\n\n    int maxIter = 15000;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> residentDist(0, K-1);\n\n    for (int iter = 0; iter < maxIter; ++iter) {\n        int k = residentDist(gen);\n        int i = assign[k];\n        bool improved = false;\n\n        for (int j : candidateVertices[k]) {\n            if (j == i) continue;\n\n            int oldP_i = P[i], oldP_j = P[j];\n            double d_ik = distVtoR[i][k];\n            double d_jk = distVtoR[j][k];\n\n            // Update data structures\n            distSets[i].erase(distSets[i].find(d_ik));\n            distSets[j].insert(d_jk);\n            residentList[i].erase(remove(residentList[i].begin(), residentList[i].end(), k), residentList[i].end());\n            residentList[j].push_back(k);\n\n            // Compute new P values\n            int newP_i = 0, newP_j = 0;\n            if (!distSets[i].empty()) {\n                double maxDist = *distSets[i].rbegin();\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!distSets[j].empty()) {\n                double maxDist = *distSets[j].rbegin();\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n\n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n\n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n\n            long long newCost;\n            long long newActualCost;\n            if (newT == currentT) {\n                newActualCost = currentActualCost;\n                newCost = newSumSq + newActualCost;\n            } else {\n                newActualCost = computeActualConnectionCost(newT);\n                newCost = newSumSq + newActualCost;\n            }\n\n            if (newCost < currentCost - EPS) {\n                // Accept move\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                assign[k] = j;\n                currentT = newT;\n                currentActualCost = newActualCost;\n                currentCost = newCost;\n                improved = true;\n                break;\n            } else {\n                // Revert\n                distSets[i].insert(d_ik);\n                distSets[j].erase(distSets[j].find(d_jk));\n                residentList[i].push_back(k);\n                residentList[j].pop_back();\n            }\n        }\n    }\n\n    vector<int> finalT;\n    finalT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            finalT.push_back(i);\n        }\n    }\n\n    // Build final edge set\n    set<int> onEdges;\n    auto addPath = [&](int u, int v) {\n        while (u != v) {\n            int nxt = next[u][v];\n            int a = u, b = nxt;\n            if (a > b) swap(a, b);\n            onEdges.insert(edgeIndex[{a, b}]);\n            u = nxt;\n        }\n    };\n\n    int n = finalT.size();\n    if (n > 1) {\n        // Compute MST on metric closure of finalT\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[finalT[u]][finalT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u != -1) {\n                addPath(finalT[u], finalT[v]);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << P[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    for (int j = 0; j < M; ++j) {\n        cout << (onEdges.count(j) ? 1 : 0);\n        if (j < M-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint to_index(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\npair<int, int> to_coord(int idx) {\n    int x = 0;\n    while (idx >= x + 1) {\n        idx -= (x + 1);\n        x++;\n    }\n    return {x, idx};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> ball(N);\n    for (int x = 0; x < N; ++x) {\n        ball[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) {\n            cin >> ball[x][y];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n\n    // Process nodes from bottom to top (decreasing x)\n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cur_x = x;\n            int cur_y = y;\n            int cur_val = ball[cur_x][cur_y];\n\n            // Sift down until heap property satisfied\n            while (cur_x < N - 1) {\n                int left = ball[cur_x + 1][cur_y];\n                int right = ball[cur_x + 1][cur_y + 1];\n                int smaller_child = min(left, right);\n                if (cur_val <= smaller_child) break;\n\n                // Determine which child to swap with\n                int swap_y;\n                if (left < right) {\n                    swap_y = cur_y;\n                } else {\n                    swap_y = cur_y + 1;\n                }\n\n                // Perform the swap\n                swaps.emplace_back(cur_x, cur_y, cur_x + 1, swap_y);\n                swap(ball[cur_x][cur_y], ball[cur_x + 1][swap_y]);\n\n                // Move down to the swapped child position\n                cur_x = cur_x + 1;\n                cur_y = swap_y;\n                cur_val = ball[cur_x][cur_y];\n            }\n        }\n    }\n\n    // Output\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nconst int D = 9;\nconst int entrance_i = 0, entrance_j = 4;\n\nint main() {\n    int N;\n    cin >> D >> N;  // D is always 9, but read anyway\n    bool obstacle[D][D] = {false};\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N; // number of containers\n\n    bool occupied[D][D] = {false};\n    int label_of[D][D];\n    int parent_i[D][D], parent_j[D][D];\n    vector<pair<int, int>> children[D][D];\n\n    vector<int> seen_labels;\n\n    // process containers one by one\n    for (int d = 0; d < M; ++d) {\n        int t;\n        cin >> t;\n\n        // BFS from entrance through empty squares\n        int dist[D][D];\n        memset(dist, -1, sizeof(dist));\n        pair<int, int> bfs_parent[D][D];\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            const int di[4] = {1, -1, 0, 0};\n            const int dj[4] = {0, 0, 1, -1};\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                    !obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    bfs_parent[ni][nj] = {i, j};\n                    q.push({ni, nj});\n                }\n            }\n        }\n\n        // collect leaves (empty squares with exactly one empty neighbor)\n        vector<tuple<int, int, int>> leaves; // (distance, i, j)\n        const int di[4] = {1, -1, 0, 0};\n        const int dj[4] = {0, 0, 1, -1};\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == entrance_i && j == entrance_j) continue;\n                if (dist[i][j] == -1) continue;\n                int empty_neighbors = 0;\n                for (int dir = 0; dir < 4; ++dir) {\n                    int ni = i + di[dir], nj = j + dj[dir];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                        !obstacle[ni][nj] && !occupied[ni][nj]) {\n                        empty_neighbors++;\n                    }\n                }\n                if (empty_neighbors == 1) {\n                    leaves.push_back({dist[i][j], i, j});\n                }\n            }\n        }\n\n        // sort leaves by distance (closest first)\n        sort(leaves.begin(), leaves.end());\n\n        // compute quantile of current label among seen labels\n        double quantile;\n        if (seen_labels.empty()) {\n            quantile = 0.0;\n        } else {\n            int count_smaller = 0;\n            for (int lbl : seen_labels) {\n                if (lbl < t) count_smaller++;\n            }\n            quantile = (double)count_smaller / seen_labels.size();\n        }\n\n        // choose leaf according to quantile\n        int L = leaves.size();\n        int idx = (int)round(quantile * (L - 1));\n        idx = max(0, min(L - 1, idx));\n        auto [dist_val, pi, pj] = leaves[idx];\n\n        // output placement\n        cout << pi << \" \" << pj << endl;\n\n        // record placement\n        occupied[pi][pj] = true;\n        label_of[pi][pj] = t;\n        parent_i[pi][pj] = bfs_parent[pi][pj].first;\n        parent_j[pi][pj] = bfs_parent[pi][pj].second;\n        children[parent_i[pi][pj]][parent_j[pi][pj]].push_back({pi, pj});\n\n        seen_labels.push_back(t);\n    }\n\n    // determine and output transport order\n    priority_queue<pair<int, pair<int, int>>,\n                   vector<pair<int, pair<int, int>>>,\n                   greater<>> pq;\n    bool removed[D][D] = {false};\n\n    // initially, containers whose parent is the entrance are removable\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (occupied[i][j] && parent_i[i][j] == entrance_i && parent_j[i][j] == entrance_j) {\n                pq.push({label_of[i][j], {i, j}});\n            }\n        }\n    }\n\n    while (!pq.empty()) {\n        auto [lbl, coords] = pq.top(); pq.pop();\n        int i = coords.first, j = coords.second;\n        cout << i << \" \" << j << endl;\n        removed[i][j] = true;\n\n        // children of the removed container become removable\n        for (auto child : children[i][j]) {\n            int ci = child.first, cj = child.second;\n            pq.push({label_of[ci][cj], {ci, cj}});\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x < p.x || (x == p.x && y < p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\n// BFS to find shortest path between two sets in a graph defined by allowed cells\nvector<Point> bfs_path(const vector<vector<bool>>& allowed, \n                       const set<Point>& start_set, \n                       const set<Point>& end_set,\n                       int n) {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    vector<vector<Point>> prev(n, vector<Point>(n, Point(-1, -1)));\n    queue<Point> q;\n    \n    for (const Point& p : start_set) {\n        visited[p.x][p.y] = true;\n        q.push(p);\n    }\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        if (end_set.count(cur)) {\n            // Reconstruct path\n            vector<Point> path;\n            Point at = cur;\n            while (!(at.x == -1 && at.y == -1)) {\n                path.push_back(at);\n                at = prev[at.x][at.y];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && allowed[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                prev[nx][ny] = cur;\n                q.push(Point(nx, ny));\n            }\n        }\n    }\n    return {}; // No path found\n}\n\n// Check if removing a point disconnects a set of points\nbool is_articulation(const set<Point>& region, const Point& p, int n) {\n    if (!region.count(p)) return false;\n    \n    set<Point> remaining = region;\n    remaining.erase(p);\n    \n    if (remaining.empty()) return false;\n    \n    // Find first point in remaining\n    Point start = *remaining.begin();\n    set<Point> component;\n    queue<Point> q;\n    q.push(start);\n    component.insert(start);\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    while (!q.empty()) {\n        Point cur = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            Point np(nx, ny);\n            if (remaining.count(np) && !component.count(np)) {\n                component.insert(np);\n                q.push(np);\n            }\n        }\n    }\n    \n    return component.size() != remaining.size();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n = N, m = M;\n    vector<vector<int>> grid(n, vector<int>(n));\n    \n    // Read input\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    // Build adjacency information\n    vector<set<int>> adj_colors(m + 1); // neighbors for each color\n    // For each unordered pair (c,d), store a list of adjacent cell pairs\n    vector<vector<vector<pair<Point, Point>>>> adj_pairs(m + 1, vector<vector<pair<Point, Point>>>(m + 1));\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int color = grid[ni][nj];\n                    if (color != c) {\n                        // Ensure c < color for consistent ordering\n                        if (c < color) {\n                            adj_colors[c].insert(color);\n                            adj_colors[color].insert(c);\n                            adj_pairs[c][color].push_back({Point(i, j), Point(ni, nj)});\n                        } else if (c > color) {\n                            adj_colors[color].insert(c);\n                            adj_colors[c].insert(color);\n                            adj_pairs[color][c].push_back({Point(ni, nj), Point(i, j)});\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Anchor selection: for each edge (c,d), choose one pair\n    vector<set<Point>> anchors(m + 1);\n    \n    for (int c = 1; c <= m; c++) {\n        for (int d : adj_colors[c]) {\n            if (c >= d) continue; // process each edge once\n            \n            // Check if we already have an adjacent pair in anchors\n            bool already_adjacent = false;\n            for (const Point& p1 : anchors[c]) {\n                for (int dir = 0; dir < 4; dir++) {\n                    Point p2(p1.x + dx[dir], p1.y + dy[dir]);\n                    if (anchors[d].count(p2)) {\n                        already_adjacent = true;\n                        break;\n                    }\n                }\n                if (already_adjacent) break;\n            }\n            if (already_adjacent) continue;\n            \n            // Try to find a pair that uses existing anchors\n            bool found = false;\n            for (auto& pr : adj_pairs[c][d]) {\n                Point u = pr.first, v = pr.second;\n                if (anchors[c].count(u)) {\n                    anchors[d].insert(v);\n                    found = true;\n                    break;\n                } else if (anchors[d].count(v)) {\n                    anchors[c].insert(u);\n                    found = true;\n                    break;\n                }\n            }\n            if (!found && !adj_pairs[c][d].empty()) {\n                // Add both cells\n                Point u = adj_pairs[c][d][0].first;\n                Point v = adj_pairs[c][d][0].second;\n                anchors[c].insert(u);\n                anchors[d].insert(v);\n            }\n        }\n    }\n    \n    // For colors with no anchors, add an arbitrary cell\n    for (int c = 1; c <= m; c++) {\n        if (anchors[c].empty()) {\n            // Find any cell of this color\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (grid[i][j] == c) {\n                        anchors[c].insert(Point(i, j));\n                        break;\n                    }\n                }\n                if (!anchors[c].empty()) break;\n            }\n        }\n    }\n    \n    // Build Steiner trees for each color\n    vector<set<Point>> kept(m + 1); // kept cells for each color\n    \n    for (int c = 1; c <= m; c++) {\n        // Create allowed matrix for this color\n        vector<vector<bool>> allowed(n, vector<bool>(n, false));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == c) {\n                    allowed[i][j] = true;\n                }\n            }\n        }\n        \n        set<Point> terminals = anchors[c];\n        set<Point> current = terminals;\n        \n        // Connect components iteratively\n        while (true) {\n            // Find connected components of current\n            vector<set<Point>> components;\n            set<Point> visited;\n            \n            for (const Point& p : current) {\n                if (visited.count(p)) continue;\n                \n                set<Point> comp;\n                queue<Point> q;\n                q.push(p);\n                comp.insert(p);\n                visited.insert(p);\n                \n                while (!q.empty()) {\n                    Point cur = q.front();\n                    q.pop();\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point np(cur.x + dx[d], cur.y + dy[d]);\n                        if (np.x >= 0 && np.x < n && np.y >= 0 && np.y < n && \n                            allowed[np.x][np.y] && current.count(np) && !visited.count(np)) {\n                            comp.insert(np);\n                            visited.insert(np);\n                            q.push(np);\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n            \n            if (components.size() <= 1) break;\n            \n            // Connect first two components\n            set<Point> comp1 = components[0], comp2 = components[1];\n            vector<Point> path = bfs_path(allowed, comp1, comp2, n);\n            \n            if (!path.empty()) {\n                for (const Point& p : path) {\n                    current.insert(p);\n                }\n            } else {\n                // Should not happen since graph is connected\n                break;\n            }\n        }\n        \n        // Prune leaves that are not terminals\n        set<Point> tree = current;\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            vector<Point> to_remove;\n            for (const Point& p : tree) {\n                if (terminals.count(p)) continue;\n                \n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    Point np(p.x + dx[d], p.y + dy[d]);\n                    if (tree.count(np)) deg++;\n                }\n                if (deg <= 1) {\n                    to_remove.push_back(p);\n                }\n            }\n            \n            for (const Point& p : to_remove) {\n                tree.erase(p);\n                changed = true;\n            }\n        }\n        \n        kept[c] = tree;\n    }\n    \n    // Build output grid\n    vector<vector<int>> output(n, vector<int>(n, 0));\n    for (int c = 1; c <= m; c++) {\n        for (const Point& p : kept[c]) {\n            output[p.x][p.y] = c;\n        }\n    }\n    \n    // Check connectivity of 0\n    vector<vector<bool>> visited0(n, vector<bool>(n, false));\n    queue<Point> q0;\n    \n    // Start from boundary 0 cells (connected to outside)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if ((i == 0 || i == n-1 || j == 0 || j == n-1) && output[i][j] == 0) {\n                q0.push(Point(i, j));\n                visited0[i][j] = true;\n            }\n        }\n    }\n    \n    while (!q0.empty()) {\n        Point cur = q0.front();\n        q0.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = cur.x + dx[d];\n            int ny = cur.y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                output[nx][ny] == 0 && !visited0[nx][ny]) {\n                visited0[nx][ny] = true;\n                q0.push(Point(nx, ny));\n            }\n        }\n    }\n    \n    // If there are unvisited 0 cells, try to fix\n    bool disconnected = false;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0 && !visited0[i][j]) {\n                disconnected = true;\n                break;\n            }\n        }\n        if (disconnected) break;\n    }\n    \n    if (disconnected) {\n        // Try to remove some non-zero cells to connect 0\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] != 0 && !visited0[i][j]) {\n                    int c = output[i][j];\n                    Point p(i, j);\n                    \n                    // Check if this cell can be removed\n                    bool can_remove = true;\n                    \n                    // Check if it's a leaf in its tree and not a terminal\n                    if (kept[c].count(p)) {\n                        int deg = 0;\n                        for (int d = 0; d < 4; d++) {\n                            Point np(i + dx[d], j + dy[d]);\n                            if (kept[c].count(np)) deg++;\n                        }\n                        if (deg > 1) can_remove = false;\n                        \n                        // Check if it's the only anchor for some neighbor\n                        for (int d : adj_colors[c]) {\n                            if (d == 0) continue;\n                            bool has_other = false;\n                            for (const Point& q : kept[c]) {\n                                if (q == p) continue;\n                                for (int dir = 0; dir < 4; dir++) {\n                                    Point nq(q.x + dx[dir], q.y + dy[dir]);\n                                    if (nq.x >= 0 && nq.x < n && nq.y >= 0 && nq.y < n && \n                                        output[nq.x][nq.y] == d) {\n                                        has_other = true;\n                                        break;\n                                    }\n                                }\n                                if (has_other) break;\n                            }\n                            if (!has_other) {\n                                can_remove = false;\n                                break;\n                            }\n                        }\n                    } else {\n                        can_remove = false;\n                    }\n                    \n                    if (can_remove) {\n                        // Change to 0 and update\n                        output[i][j] = 0;\n                        kept[c].erase(p);\n                        \n                        // Re-run BFS for 0 connectivity\n                        fill(visited0.begin(), visited0.end(), vector<bool>(n, false));\n                        queue<Point> q0;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if ((ii == 0 || ii == n-1 || jj == 0 || jj == n-1) && output[ii][jj] == 0) {\n                                    q0.push(Point(ii, jj));\n                                    visited0[ii][jj] = true;\n                                }\n                            }\n                        }\n                        while (!q0.empty()) {\n                            Point cur = q0.front();\n                            q0.pop();\n                            for (int d = 0; d < 4; d++) {\n                                int nx = cur.x + dx[d];\n                                int ny = cur.y + dy[d];\n                                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                                    output[nx][ny] == 0 && !visited0[nx][ny]) {\n                                    visited0[nx][ny] = true;\n                                    q0.push(Point(nx, ny));\n                                }\n                            }\n                        }\n                        \n                        // Check if still disconnected\n                        disconnected = false;\n                        for (int ii = 0; ii < n; ii++) {\n                            for (int jj = 0; jj < n; jj++) {\n                                if (output[ii][jj] == 0 && !visited0[ii][jj]) {\n                                    disconnected = true;\n                                    break;\n                                }\n                            }\n                            if (disconnected) break;\n                        }\n                        if (!disconnected) break;\n                    }\n                }\n            }\n            if (!disconnected) break;\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string s;\n    cin >> s;\n    queries_used++;\n    return s[0];\n}\n\nchar compare(int i, int j) {\n    return query({i}, {j});\n}\n\n// Greedy bucket assignment using direct comparisons of bucket sums\nvoid greedy_bucket(vector<int>& ans) {\n    vector<vector<int>> buckets(D);\n    for (int i = 0; i < N; ++i) {\n        // Find a bucket to put this item\n        int best = -1;\n        // First, check if there is any empty bucket\n        for (int j = 0; j < D; ++j) {\n            if (buckets[j].empty()) {\n                best = j;\n                break;\n            }\n        }\n        if (best == -1) {\n            // All buckets are non-empty, find the lightest by comparing\n            best = 0;\n            for (int j = 1; j < D; ++j) {\n                if (queries_used >= Q) break; // cannot compare further\n                vector<int> L = buckets[best];\n                vector<int> R = buckets[j];\n                char res = query(L, R);\n                if (res == '>') {\n                    best = j;\n                }\n                // if '=', keep current best\n            }\n        }\n        buckets[best].push_back(i);\n        ans[i] = best;\n    }\n}\n\n// Sorting and snake assignment\nvoid sorting_snake(vector<int>& ans) {\n    vector<int> items;  // sorted order as much as we know\n    // Insert items one by one using binary search\n    for (int i = 0; i < N; ++i) {\n        if (queries_used >= Q) {\n            items.push_back(i);\n            continue;\n        }\n        int left = 0, right = items.size();\n        while (left < right && queries_used < Q) {\n            int mid = (left + right) / 2;\n            char res = compare(i, items[mid]);\n            if (res == '<') {\n                right = mid;\n            } else {\n                left = mid + 1;\n            }\n        }\n        items.insert(items.begin() + left, i);\n    }\n\n    // Bubble sort to improve order with remaining queries\n    bool swapped = true;\n    while (queries_used < Q && swapped) {\n        swapped = false;\n        for (size_t i = 0; i + 1 < items.size(); ++i) {\n            if (queries_used >= Q) break;\n            char res = compare(items[i], items[i+1]);\n            if (res == '>') {\n                swap(items[i], items[i+1]);\n                swapped = true;\n            }\n        }\n    }\n\n    // Snake assignment\n    for (int i = 0; i < N; ++i) {\n        int item = items[i];\n        int bucket = i % D;\n        if ((i / D) % 2 == 1) {\n            bucket = D - 1 - bucket;\n        }\n        ans[item] = bucket;\n    }\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    vector<int> ans(N, -1);\n\n    // Decide which strategy to use based on available queries\n    int max_comparisons_needed = N * (D - 1);\n    if (Q >= max_comparisons_needed) {\n        greedy_bucket(ans);\n    } else {\n        sorting_snake(ans);\n    }\n\n    // Use any remaining queries as dummy comparisons\n    while (queries_used < Q) {\n        compare(0, 1);  // always valid as N >= 2\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    int h = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    // greedy policy: returns total cost from start_v to n using the heuristic:\n    // move suffix above the next box to the empty stack if top > max_top, else to stack with largest top.\n    auto greedy_policy = [&](vector<vector<int>> st, int start_v) -> int {\n        int cost = 0;\n        for (int v = start_v; v <= n; ++v) {\n            // locate v\n            int s = -1, pos = -1;\n            for (int i = 0; i < m; ++i) {\n                for (int j = 0; j < (int)st[i].size(); ++j) {\n                    if (st[i][j] == v) {\n                        s = i;\n                        pos = j;\n                        break;\n                    }\n                }\n                if (s != -1) break;\n            }\n\n            if (pos == (int)st[s].size() - 1) {   // already on top\n                st[s].pop_back();\n                continue;\n            }\n\n            int k = (int)st[s].size() - pos - 1;  // boxes above v\n            cost += k + 1;\n\n            int T = st[s].back();                 // top of the group to be moved\n            int best_d = -1;\n            bool found_empty = false;\n            int empty_d = -1;\n            int best_top = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if (st[i].empty()) {\n                    found_empty = true;\n                    if (empty_d == -1) empty_d = i;\n                } else {\n                    int top = st[i].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        best_d = i;\n                    }\n                }\n            }\n\n            if (found_empty) {\n                if (best_d == -1 || T > best_top) {\n                    best_d = empty_d;\n                }\n            } // else best_d already holds the stack with largest top\n\n            // move the suffix\n            vector<int> suffix(st[s].begin() + pos + 1, st[s].end());\n            st[s].erase(st[s].begin() + pos + 1, st[s].end());\n            st[best_d].insert(st[best_d].end(), suffix.begin(), suffix.end());\n\n            // remove v (now on top)\n            st[s].pop_back();\n        }\n        return cost;\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        // locate v\n        int s = -1, pos = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == v) {\n                    s = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (pos == (int)stacks[s].size() - 1) {\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n            continue;\n        }\n\n        int k_above = (int)stacks[s].size() - pos - 1;\n        int base_cost = k_above + 1;\n\n        int best_d = -1;\n        int best_total = 1e9;\n\n        for (int d = 0; d < m; ++d) {\n            if (d == s) continue;\n\n            auto st2 = stacks;\n            // move suffix from s to d\n            vector<int> suffix(st2[s].begin() + pos + 1, st2[s].end());\n            st2[s].erase(st2[s].begin() + pos + 1, st2[s].end());\n            st2[d].insert(st2[d].end(), suffix.begin(), suffix.end());\n            // remove v\n            st2[s].pop_back();\n\n            int future = greedy_policy(st2, v + 1);\n            int total = base_cost + future;\n\n            if (total < best_total) {\n                best_total = total;\n                best_d = d;\n            }\n        }\n\n        // execute the chosen move\n        int w = stacks[s][pos + 1];\n        cout << w << \" \" << best_d + 1 << \"\\n\";\n\n        vector<int> suffix(stacks[s].begin() + pos + 1, stacks[s].end());\n        stacks[s].erase(stacks[s].begin() + pos + 1, stacks[s].end());\n        stacks[best_d].insert(stacks[best_d].end(), suffix.begin(), suffix.end());\n\n        // now v is on top, remove it\n        cout << v << \" 0\\n\";\n        stacks[s].pop_back();\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\nusing namespace std;\n\nconst int dx[] = {1, -1, 0, 0}; // D, U, R, L\nconst int dy[] = {0, 0, 1, -1};\nconst char dir_char[] = {'D', 'U', 'R', 'L'};\nconst char opp_char[] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<bool>> visited;\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (visited[ni][nj]) continue;\n        // check wall\n        if (d == 0 && h[i][j] == '1') continue;      // down\n        if (d == 1 && h[ni][nj] == '1') continue;    // up\n        if (d == 2 && v[i][j] == '1') continue;      // right\n        if (d == 3 && v[i][nj] == '1') continue;     // left\n        cout << dir_char[d];\n        dfs(ni, nj);\n        cout << opp_char[d];\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\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    visited.assign(N, vector<bool>(N, false));\n    dfs(0, 0);\n    cout << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nstruct Candidate {\n    vector<pii> pos;      // 5 positions\n    int internal_cost;    // cost to type this occurrence from scratch\n    vector<int> tail_cost; // tail_cost[k]: cost from position k to end (including letter at k)\n};\n\nint manhattan(const pii& a, const pii& b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\n// Transition cost from candidate A to candidate B given valid overlaps\nint transition_cost(const Candidate& A, const Candidate& B, const vector<int>& valid) {\n    int best = 1e9;\n    for (int k : valid) {\n        int cost = manhattan(A.pos[4], B.pos[k]) + B.tail_cost[k];\n        if (cost < best) best = cost;\n    }\n    return best;\n}\n\nint compute_cost(const vector<int>& order_targets, \n                 const vector<int>& order_candidate_idx,\n                 const vector<vector<Candidate>>& candidates,\n                 const vector<vector<vector<int>>>& valid,\n                 const pii& start) {\n    int total = 0;\n    pii cur_pos = start;\n    int cur_target = -1;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& cand = candidates[j][order_candidate_idx[i]];\n        if (cur_target == -1) {\n            total += manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n        } else {\n            total += transition_cost(candidates[cur_target][order_candidate_idx[i-1]], cand, valid[cur_target][j]);\n        }\n        cur_target = j;\n    }\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    pii start;\n    cin >> start.first >> start.second;\n\n    vector<vector<char>> A(N, vector<char>(N));\n    vector<vector<pii>> pos_list(26); // positions for each letter\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            pos_list[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n\n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n\n    // Random number generator with random device for diversity\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist;\n\n    const int RANDOM_CANDIDATES = 4000;\n    const int GREEDY_CANDIDATES = 400;\n    const int KEEP = 50;\n\n    vector<vector<Candidate>> candidates(M);\n\n    // Generate candidate occurrences for each target\n    for (int idx = 0; idx < M; ++idx) {\n        const string& t = targets[idx];\n        vector<Candidate> cands;\n        \n        // Random candidates\n        for (int iter = 0; iter < RANDOM_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            for (int k = 0; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                uniform_int_distribution<int> d(0, (int)lst.size() - 1);\n                pos[k] = lst[d(rng)];\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n        \n        // Greedy candidates: start from random position for first letter,\n        // then for each next letter choose closest position to current\n        for (int iter = 0; iter < GREEDY_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            // Choose random starting position for first letter\n            const auto& lst0 = pos_list[t[0] - 'A'];\n            uniform_int_distribution<int> d0(0, (int)lst0.size() - 1);\n            pos[0] = lst0[d0(rng)];\n            \n            for (int k = 1; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                // Find closest position to current position\n                int best_dist = 1e9;\n                pii best_pos = lst[0];\n                for (const pii& p : lst) {\n                    int d = manhattan(pos[k-1], p);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_pos = p;\n                    }\n                }\n                pos[k] = best_pos;\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n\n        // Keep the best KEEP candidates by internal cost\n        sort(cands.begin(), cands.end(),\n             [](const Candidate& a, const Candidate& b) { return a.internal_cost < b.internal_cost; });\n        if (cands.size() > KEEP) cands.resize(KEEP);\n        candidates[idx] = cands;\n    }\n\n    // Precompute valid overlaps between targets\n    vector<vector<vector<int>>> valid(M, vector<vector<int>>(M));\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            const string& si = targets[i];\n            const string& sj = targets[j];\n            vector<int> v;\n            for (int k = 1; k <= 4; ++k) {\n                if (si.substr(5 - k) == sj.substr(0, k)) {\n                    v.push_back(k);\n                }\n            }\n            v.push_back(0); // k=0 always allowed\n            valid[i][j] = v;\n        }\n    }\n\n    // Greedy construction of the path\n    vector<int> order_targets;\n    vector<int> order_candidate_idx;\n    vector<bool> covered(M, false);\n\n    pii cur_pos = start;\n    int cur_target = -1;\n\n    for (int step = 0; step < M; ++step) {\n        int best_add = 1e9;\n        int best_j = -1, best_c = -1;\n\n        for (int j = 0; j < M; ++j) {\n            if (covered[j]) continue;\n            for (size_t c = 0; c < candidates[j].size(); ++c) {\n                const Candidate& cand = candidates[j][c];\n                if (cur_target == -1) {\n                    int add = manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n                    if (add < best_add) {\n                        best_add = add;\n                        best_j = j;\n                        best_c = c;\n                    }\n                } else {\n                    for (int k : valid[cur_target][j]) {\n                        int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                        if (add < best_add) {\n                            best_add = add;\n                            best_j = j;\n                            best_c = c;\n                        }\n                    }\n                }\n            }\n        }\n\n        covered[best_j] = true;\n        order_targets.push_back(best_j);\n        order_candidate_idx.push_back(best_c);\n\n        cur_target = best_j;\n        cur_pos = candidates[best_j][best_c].pos[4];\n    }\n\n    // Local search with 2-opt (swap any two positions)\n    int current_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < M - 1; ++i) {\n            for (int j = i + 1; j < M; ++j) {\n                // Try swapping i and j\n                swap(order_targets[i], order_targets[j]);\n                swap(order_candidate_idx[i], order_candidate_idx[j]);\n                int new_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n                if (new_cost < current_cost) {\n                    current_cost = new_cost;\n                    improved = true;\n                } else {\n                    // Swap back\n                    swap(order_targets[i], order_targets[j]);\n                    swap(order_candidate_idx[i], order_candidate_idx[j]);\n                }\n            }\n        }\n    }\n\n    // Dynamic programming to re-select candidates for fixed order\n    vector<int> final_candidate_idx(M);\n    int final_cost = 0;\n    {\n        int n = M;\n        vector<vector<int>> dp(n, vector<int>(candidates[order_targets[0]].size(), 1e9));\n        vector<vector<int>> prev(n, vector<int>(candidates[order_targets[0]].size(), -1));\n        \n        // Initialize for first target\n        for (size_t c = 0; c < candidates[order_targets[0]].size(); ++c) {\n            const Candidate& cand = candidates[order_targets[0]][c];\n            dp[0][c] = manhattan(start, cand.pos[0]) + cand.internal_cost;\n        }\n\n        for (int i = 1; i < n; ++i) {\n            int cur_target = order_targets[i];\n            int prev_target = order_targets[i-1];\n            for (size_t c = 0; c < candidates[cur_target].size(); ++c) {\n                const Candidate& cand_cur = candidates[cur_target][c];\n                for (size_t d = 0; d < candidates[prev_target].size(); ++d) {\n                    const Candidate& cand_prev = candidates[prev_target][d];\n                    int add = transition_cost(cand_prev, cand_cur, valid[prev_target][cur_target]);\n                    int total = dp[i-1][d] + add;\n                    if (total < dp[i][c]) {\n                        dp[i][c] = total;\n                        prev[i][c] = d;\n                    }\n                }\n            }\n        }\n\n        // Find best final candidate\n        int best_c = -1;\n        int best_total = 1e9;\n        for (size_t c = 0; c < dp[n-1].size(); ++c) {\n            if (dp[n-1][c] < best_total) {\n                best_total = dp[n-1][c];\n                best_c = c;\n            }\n        }\n\n        // Backtrack\n        final_cost = best_total;\n        int cur_c = best_c;\n        for (int i = n-1; i >= 0; --i) {\n            final_candidate_idx[i] = cur_c;\n            if (i > 0) cur_c = prev[i][cur_c];\n        }\n    }\n\n    // Local search to improve candidates for fixed order\n    {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M; ++i) {\n                int target = order_targets[i];\n                int old_idx = final_candidate_idx[i];\n                for (size_t new_idx = 0; new_idx < candidates[target].size(); ++new_idx) {\n                    if (new_idx == old_idx) continue;\n                    \n                    // Compute delta cost if we change candidate for target i\n                    int delta = 0;\n                    const Candidate& old_cand = candidates[target][old_idx];\n                    const Candidate& new_cand = candidates[target][new_idx];\n                    \n                    // Replace internal cost\n                    delta += new_cand.internal_cost - old_cand.internal_cost;\n                    \n                    // Replace transition from previous target if exists\n                    if (i > 0) {\n                        int prev_target = order_targets[i-1];\n                        const Candidate& prev_cand = candidates[prev_target][final_candidate_idx[i-1]];\n                        delta += transition_cost(prev_cand, new_cand, valid[prev_target][target]) \n                                - transition_cost(prev_cand, old_cand, valid[prev_target][target]);\n                    }\n                    \n                    // Replace transition to next target if exists\n                    if (i < M-1) {\n                        int next_target = order_targets[i+1];\n                        const Candidate& next_cand = candidates[next_target][final_candidate_idx[i+1]];\n                        delta += transition_cost(new_cand, next_cand, valid[target][next_target]) \n                                - transition_cost(old_cand, next_cand, valid[target][next_target]);\n                    }\n                    \n                    if (delta < 0) {\n                        final_candidate_idx[i] = new_idx;\n                        final_cost += delta;\n                        improved = true;\n                        break; // restart loop\n                    }\n                }\n            }\n        }\n    }\n\n    // Second 2-opt pass on order using final candidates\n    {\n        current_cost = compute_cost(order_targets, final_candidate_idx, candidates, valid, start);\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M - 1; ++i) {\n                for (int j = i + 1; j < M; ++j) {\n                    // Try swapping i and j\n                    swap(order_targets[i], order_targets[j]);\n                    swap(final_candidate_idx[i], final_candidate_idx[j]);\n                    int new_cost = compute_cost(order_targets, final_candidate_idx, candidates, valid, start);\n                    if (new_cost < current_cost) {\n                        current_cost = new_cost;\n                        improved = true;\n                    } else {\n                        // Swap back\n                        swap(order_targets[i], order_targets[j]);\n                        swap(final_candidate_idx[i], final_candidate_idx[j]);\n                    }\n                }\n            }\n        }\n    }\n\n    // Build the output sequence of moves using final candidates\n    vector<pii> moves;\n    int cur_target_move = -1;\n    pii cur_pos_move = start;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& occ = candidates[j][final_candidate_idx[i]];\n        if (cur_target_move == -1) {\n            for (int k = 0; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        } else {\n            int best_k = 0;\n            int best_add = 1e9;\n            for (int k : valid[cur_target_move][j]) {\n                int add = manhattan(cur_pos_move, occ.pos[k]) + occ.tail_cost[k];\n                if (add < best_add) {\n                    best_add = add;\n                    best_k = k;\n                }\n            }\n            for (int k = best_k; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        }\n        cur_target_move = j;\n        cur_pos_move = occ.pos[4];\n    }\n\n    // Output the moves\n    for (const pii& p : moves) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <cstdio>\n#include <vector>\nusing namespace std;\n\nint query(const vector<pair<int, int>>& cells) {\n    int k = cells.size();\n    printf(\"q %d\", k);\n    for (auto& p : cells) {\n        printf(\" %d %d\", p.first, p.second);\n    }\n    printf(\"\\n\");\n    fflush(stdout);\n    int val;\n    scanf(\"%d\", &val);\n    return val;\n}\n\nint drill(int i, int j) {\n    printf(\"q 1 %d %d\\n\", i, j);\n    fflush(stdout);\n    int val;\n    scanf(\"%d\", &val);\n    return val;\n}\n\nint main() {\n    int N, M;\n    double eps;\n    scanf(\"%d %d %lf\", &N, &M, &eps);\n\n    // read shapes (unused)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        scanf(\"%d\", &d);\n        for (int i = 0; i < d; ++i) {\n            int x, y;\n            scanf(\"%d %d\", &x, &y);\n        }\n    }\n\n    const int B = 5; // block size\n    vector<pair<int, int>> oil;\n\n    auto block_strategy = [&]() {\n        oil.clear();\n        for (int i0 = 0; i0 < N; i0 += B) {\n            int i1 = min(i0 + B, N);\n            for (int j0 = 0; j0 < N; j0 += B) {\n                int j1 = min(j0 + B, N);\n                vector<pair<int, int>> block;\n                for (int i = i0; i < i1; ++i)\n                    for (int j = j0; j < j1; ++j)\n                        block.emplace_back(i, j);\n                int res = query(block);\n                if (res > 0) {\n                    for (int i = i0; i < i1; ++i)\n                        for (int j = j0; j < j1; ++j) {\n                            int val = drill(i, j);\n                            if (val > 0)\n                                oil.emplace_back(i, j);\n                        }\n                }\n            }\n        }\n        printf(\"a %d\", (int)oil.size());\n        for (auto& p : oil)\n            printf(\" %d %d\", p.first, p.second);\n        printf(\"\\n\");\n        fflush(stdout);\n        int resp;\n        scanf(\"%d\", &resp);\n        return resp;\n    };\n\n    int resp = block_strategy();\n    if (resp == 0) {   // fallback: drill every square\n        oil.clear();\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int val = drill(i, j);\n                if (val > 0)\n                    oil.emplace_back(i, j);\n            }\n        printf(\"a %d\", (int)oil.size());\n        for (auto& p : oil)\n            printf(\" %d %d\", p.first, p.second);\n        printf(\"\\n\");\n        fflush(stdout);\n        scanf(\"%d\", &resp);\n    }\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <climits>\n#include <cassert>\nusing namespace std;\n\nconst int W_MAX = 1000; // grid size\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    int area() const { return (x2 - x1) * (y2 - y1); }\n};\n\n// Recursive partition of the grid into rectangles with areas as close as possible to B\nvoid partition(Rect r, vector<int> indices, const vector<long long>& B, vector<Rect>& rects) {\n    int m = indices.size();\n    if (m == 1) {\n        rects[indices[0]] = r;\n        return;\n    }\n    long long total_target = 0;\n    for (int i : indices) total_target += B[i];\n    long long total_area = (long long)(r.x2 - r.x1) * (r.y2 - r.y1);\n    // sort indices by B to make contiguous groups\n    sort(indices.begin(), indices.end(), [&](int i, int j) { return B[i] < B[j]; });\n    long long best_waste = LLONG_MAX;\n    int best_split = -1;\n    int best_orient = 0; // 0 = horizontal, 1 = vertical\n    int best_cut = 0;\n    int width = r.x2 - r.x1;\n    int height = r.y2 - r.y1;\n    for (int i = 1; i < m; ++i) {\n        long long sum_left = 0;\n        for (int j = 0; j < i; ++j) sum_left += B[indices[j]];\n        long long sum_right = total_target - sum_left;\n        // horizontal split\n        double target_y = (double)sum_left / width;\n        int cut_y = (int)round(target_y);\n        if (cut_y < 1) cut_y = 1;\n        if (cut_y > height-1) cut_y = height-1;\n        long long top_area = (long long)width * cut_y;\n        long long bottom_area = (long long)width * (height - cut_y);\n        long long waste = llabs(top_area - sum_left) + llabs(bottom_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 0;\n            best_cut = cut_y;\n        }\n        // vertical split\n        double target_x = (double)sum_left / height;\n        int cut_x = (int)round(target_x);\n        if (cut_x < 1) cut_x = 1;\n        if (cut_x > width-1) cut_x = width-1;\n        long long left_area = (long long)cut_x * height;\n        long long right_area = (long long)(width - cut_x) * height;\n        waste = llabs(left_area - sum_left) + llabs(right_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 1;\n            best_cut = cut_x;\n        }\n    }\n    // Now split\n    if (best_orient == 0) {\n        // horizontal\n        Rect top(r.x1, r.y1, r.x2, r.y1 + best_cut);\n        Rect bottom(r.x1, r.y1 + best_cut, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(top, left_indices, B, rects);\n        partition(bottom, right_indices, B, rects);\n    } else {\n        // vertical\n        Rect left(r.x1, r.y1, r.x1 + best_cut, r.y2);\n        Rect right(r.x1 + best_cut, r.y1, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(left, left_indices, B, rects);\n        partition(right, right_indices, B, rects);\n    }\n}\n\nvector<Rect> packRectangles(const vector<long long>& B) {\n    int N = B.size();\n    vector<Rect> rects(N);\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    // Recursive partition covering the whole grid\n    partition(Rect{0, 0, W_MAX, W_MAX}, indices, B, rects);\n    return rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    // W_input should be 1000; we ignore it and use W_MAX.\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) {\n            cin >> A[d][k];\n        }\n    }\n\n    // For each day, pack rectangles according to that day's desires\n    for (int d = 0; d < D; ++d) {\n        vector<long long> B(N);\n        for (int k = 0; k < N; ++k) B[k] = A[d][k];\n        vector<Rect> rects = packRectangles(B);\n        // rects are in ascending order of B (since packRectangles sorts indices)\n        // We need to output for each reservation k the rectangle with matching desire.\n        // Compute order of reservations by desire ascending\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[d][i] < A[d][j];\n        });\n        // Create output mapping: for each reservation k, store the rectangle\n        vector<Rect> out(N);\n        for (int rank = 0; rank < N; ++rank) {\n            int k = order[rank]; // reservation with rank-th smallest desire\n            out[k] = rects[rank]; // rects[rank] has area at least B[order[rank]]\n        }\n        // Output in reservation order (0..N-1)\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = out[k];\n            cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\nstruct Move {\n    int m, p, q;\n    vector<pair<int, int>> cells; // (index, value)\n};\n\nstruct State {\n    array<int, N*N> board;\n    long long score;\n    State* parent;\n    int m, p, q; // move that led to this state, or -1 for initial\n};\n\nlong long compute_gain(const array<int, N*N>& board, const Move& move) {\n    long long gain = 0;\n    for (auto [idx, val] : move.cells) {\n        int old_rem = board[idx];\n        int new_rem = (old_rem + val) % MOD;\n        gain += new_rem - old_rem;\n    }\n    return gain;\n}\n\nvoid apply_move(array<int, N*N>& board, const Move& move) {\n    for (auto [idx, val] : move.cells) {\n        board[idx] = (board[idx] + val) % MOD;\n    }\n}\n\nlong long compute_score(const array<int, N*N>& board) {\n    return accumulate(board.begin(), board.end(), 0LL);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    vector<int> a(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i*N + j];\n        }\n    }\n\n    vector<array<array<int, 3>, 3>> 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][i][j];\n            }\n        }\n    }\n\n    // Precompute all possible moves\n    vector<Move> moves_list;\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                Move move;\n                move.m = m;\n                move.p = p;\n                move.q = q;\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        int idx = (p+i)*N + (q+j);\n                        int val = stamps[m][i][j] % MOD;\n                        move.cells.emplace_back(idx, val);\n                    }\n                }\n                moves_list.push_back(move);\n            }\n        }\n    }\n\n    // Create index mapping for quick lookup\n    array<array<array<int, N-2>, N-2>, M> move_index;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < N-2; ++j) {\n            for (int k = 0; k < N-2; ++k) {\n                move_index[i][j][k] = -1;\n            }\n        }\n    }\n    for (int idx = 0; idx < moves_list.size(); ++idx) {\n        const Move& move = moves_list[idx];\n        move_index[move.m][move.p][move.q] = idx;\n    }\n\n    // Beam search\n    const int beam_width = 25;\n    vector<State*> all_states;\n    State* initial = new State;\n    initial->parent = nullptr;\n    initial->m = initial->p = initial->q = -1;\n    copy(a.begin(), a.end(), initial->board.begin());\n    initial->score = accumulate(a.begin(), a.end(), 0LL);\n    all_states.push_back(initial);\n\n    State* global_best = initial;\n    long long global_best_score = initial->score;\n\n    vector<State*> current_beam;\n    current_beam.push_back(initial);\n\n    for (int step = 0; step < K; ++step) {\n        vector<State*> candidates;\n\n        for (State* s : current_beam) {\n            // Option: do nothing\n            candidates.push_back(s);\n\n            // Try every move\n            for (const Move& move : moves_list) {\n                array<int, N*N> new_board = s->board;\n                long long gain = compute_gain(new_board, move);\n                long long new_score = s->score + gain;\n\n                State* new_state = new State;\n                new_state->board = new_board;\n                apply_move(new_state->board, move);\n                new_state->score = new_score;\n                new_state->parent = s;\n                new_state->m = move.m;\n                new_state->p = move.p;\n                new_state->q = move.q;\n\n                candidates.push_back(new_state);\n                all_states.push_back(new_state);\n\n                if (new_score > global_best_score) {\n                    global_best = new_state;\n                    global_best_score = new_score;\n                }\n            }\n        }\n\n        // Select top beam_width states\n        sort(candidates.begin(), candidates.end(),\n             [](State* a, State* b) { return a->score > b->score; });\n\n        if (!candidates.empty() && candidates[0]->score > global_best_score) {\n            global_best = candidates[0];\n            global_best_score = candidates[0]->score;\n        }\n\n        current_beam.clear();\n        for (int i = 0; i < beam_width && i < candidates.size(); ++i) {\n            current_beam.push_back(candidates[i]);\n        }\n    }\n\n    // Reconstruct the sequence of moves from global_best\n    vector<tuple<int, int, int>> sequence;\n    State* cur = global_best;\n    while (cur->parent != nullptr) {\n        sequence.emplace_back(cur->m, cur->p, cur->q);\n        cur = cur->parent;\n    }\n    reverse(sequence.begin(), sequence.end());\n\n    // Greedy extension: add more moves if they improve score and we haven't reached K\n    array<int, N*N> current_board = global_best->board;\n    long long current_score = global_best->score;\n\n    while (sequence.size() < K) {\n        long long best_gain = -1e18;\n        Move best_move;\n        for (const Move& move : moves_list) {\n            long long gain = compute_gain(current_board, move);\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_move = move;\n            }\n        }\n        if (best_gain <= 0) break;\n        apply_move(current_board, best_move);\n        current_score += best_gain;\n        sequence.emplace_back(best_move.m, best_move.p, best_move.q);\n    }\n\n    // Local search: try to improve sequence by replacing one move at a time\n    vector<array<int, N*N>> prefix_boards(sequence.size() + 1);\n    prefix_boards[0] = array<int, N*N>();\n    copy(a.begin(), a.end(), prefix_boards[0].begin());\n    for (int i = 0; i < sequence.size(); ++i) {\n        prefix_boards[i+1] = prefix_boards[i];\n        auto [m, p, q] = sequence[i];\n        const Move& move = moves_list[move_index[m][p][q]];\n        for (auto [idx, val] : move.cells) {\n            prefix_boards[i+1][idx] = (prefix_boards[i+1][idx] + val) % MOD;\n        }\n    }\n    current_score = compute_score(prefix_boards.back());\n\n    auto simulate_from = [&](const array<int, N*N>& start_board, int start_idx) -> long long {\n        array<int, N*N> board = start_board;\n        for (int j = start_idx; j < sequence.size(); ++j) {\n            auto [m, p, q] = sequence[j];\n            const Move& move = moves_list[move_index[m][p][q]];\n            for (auto [idx, val] : move.cells) {\n                board[idx] = (board[idx] + val) % MOD;\n            }\n        }\n        return compute_score(board);\n    };\n\n    bool improved = true;\n    int max_passes = 2; // Reduced from 3 to avoid over-optimization\n    for (int pass = 0; pass < max_passes && improved; ++pass) {\n        improved = false;\n        for (int i = 0; i < sequence.size(); ++i) {\n            array<int, N*N> prefix_board = prefix_boards[i];\n            tuple<int,int,int> original_move = sequence[i];\n            long long best_score = current_score;\n            tuple<int,int,int> best_move = original_move;\n            // Try all candidate moves\n            for (const Move& cand : moves_list) {\n                // apply cand to prefix_board\n                array<int, N*N> new_board = prefix_board;\n                for (auto [idx, val] : cand.cells) {\n                    new_board[idx] = (new_board[idx] + val) % MOD;\n                }\n                // simulate remaining moves from i+1\n                long long final_score = simulate_from(new_board, i+1);\n                if (final_score > best_score) {\n                    best_score = final_score;\n                    best_move = make_tuple(cand.m, cand.p, cand.q);\n                }\n            }\n            if (best_score > current_score) {\n                // update sequence and prefix_boards\n                sequence[i] = best_move;\n                // recompute prefix_boards from i onward\n                for (int j = i; j < sequence.size(); ++j) {\n                    prefix_boards[j+1] = prefix_boards[j];\n                    auto [m, p, q] = sequence[j];\n                    const Move& move = moves_list[move_index[m][p][q]];\n                    for (auto [idx, val] : move.cells) {\n                        prefix_boards[j+1][idx] = (prefix_boards[j+1][idx] + val) % MOD;\n                    }\n                }\n                current_score = best_score;\n                improved = true;\n                break; // restart the inner for loop\n            }\n        }\n    }\n\n    // Output\n    cout << sequence.size() << \"\\n\";\n    for (auto [m, p, q] : sequence) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    // Clean up\n    for (State* s : all_states) {\n        delete s;\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nint grid[N][N];\nint gate_next_idx[N];\nvector<int> gate_queues[N];\nint dispatch_next_needed[N];\nvector<int> dispatched[N];\nbool container_dispatched[N*N] = {false};\n\n// Crane positions and holding status\nint crane_r[N], crane_c[N];\nint crane_holding[N] = {-1, -1, -1, -1, -1};\n\nbool in_bounds(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\nbool has_container(int r, int c) {\n    return grid[r][c] != -1;\n}\n\nbool occupied_by_other_crane(int r, int c, int self) {\n    for (int i = 0; i < N; ++i) {\n        if (i != self && crane_r[i] == r && crane_c[i] == c) {\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid simulate(vector<string>& actions) {\n    // Initialize\n    memset(grid, -1, sizeof(grid));\n    fill(gate_next_idx, gate_next_idx + N, 0);\n    for (int i = 0; i < N; ++i) {\n        dispatch_next_needed[i] = i * N;\n        crane_r[i] = i;\n        crane_c[i] = 0;\n        crane_holding[i] = -1;\n    }\n    \n    actions.resize(N);\n    for (int t = 0; t < MAX_TURNS; ++t) {\n        // Step 1: Place containers at left gates\n        for (int i = 0; i < N; ++i) {\n            if (gate_next_idx[i] >= N) continue;\n            bool crane_holding_here = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_r[k] == i && crane_c[k] == 0 && crane_holding[k] != -1) {\n                    crane_holding_here = true;\n                    break;\n                }\n            }\n            bool can_place = !has_container(i, 0) && !crane_holding_here;\n            if (can_place) {\n                grid[i][0] = gate_queues[i][gate_next_idx[i]++];\n            }\n        }\n        \n        // Step 2: Crane actions\n        vector<char> turn_actions(N, '.');\n        \n        // Process large crane (index 0)\n        if (crane_holding[0] == -1) {\n            // Look for a container to pick up\n            for (int i = 0; i < N; ++i) {\n                if (!has_container(i, 0)) continue;\n                int container_id = grid[i][0];\n                int dest_row = container_id / N;\n                if (dispatch_next_needed[dest_row] == container_id) {\n                    if (crane_r[0] == i && crane_c[0] == 0) {\n                        // Pick up container\n                        crane_holding[0] = container_id;\n                        grid[i][0] = -1;\n                        turn_actions[0] = 'P';\n                    } else {\n                        // Move towards container\n                        int new_r = crane_r[0];\n                        int new_c = crane_c[0];\n                        \n                        // First move horizontally to column 0 if needed\n                        if (crane_c[0] != 0) {\n                            new_c = crane_c[0] - 1;\n                        } else if (crane_r[0] != i) {\n                            // Then move vertically\n                            new_r = crane_r[0] + (crane_r[0] < i ? 1 : -1);\n                        }\n                        \n                        // Check if move is valid\n                        if (in_bounds(new_r, new_c) && \n                            !occupied_by_other_crane(new_r, new_c, 0) &&\n                            (crane_holding[0] == -1 || !has_container(new_r, new_c))) {\n                            \n                            // Determine action\n                            if (new_r < crane_r[0]) turn_actions[0] = 'U';\n                            else if (new_r > crane_r[0]) turn_actions[0] = 'D';\n                            else if (new_c < crane_c[0]) turn_actions[0] = 'L';\n                            else if (new_c > crane_c[0]) turn_actions[0] = 'R';\n                            \n                            crane_r[0] = new_r;\n                            crane_c[0] = new_c;\n                        }\n                    }\n                    break;\n                }\n            }\n        } else {\n            // Move towards destination gate\n            int dest_row = crane_holding[0] / N;\n            int target_c = N - 1;\n            \n            int new_r = crane_r[0];\n            int new_c = crane_c[0];\n            \n            // First move horizontally to target column\n            if (crane_c[0] != target_c) {\n                new_c = crane_c[0] + (crane_c[0] < target_c ? 1 : -1);\n            } else if (crane_r[0] != dest_row) {\n                // Then move vertically\n                new_r = crane_r[0] + (crane_r[0] < dest_row ? 1 : -1);\n            } else {\n                // At destination, release\n                if (!has_container(crane_r[0], crane_c[0])) {\n                    grid[crane_r[0]][crane_c[0]] = crane_holding[0];\n                    crane_holding[0] = -1;\n                    turn_actions[0] = 'Q';\n                }\n            }\n            \n            // Check if move is valid\n            if (in_bounds(new_r, new_c) && \n                !occupied_by_other_crane(new_r, new_c, 0) &&\n                (crane_holding[0] == -1 || !has_container(new_r, new_c))) {\n                \n                // Determine action\n                if (new_r < crane_r[0]) turn_actions[0] = 'U';\n                else if (new_r > crane_r[0]) turn_actions[0] = 'D';\n                else if (new_c < crane_c[0]) turn_actions[0] = 'L';\n                else if (new_c > crane_c[0]) turn_actions[0] = 'R';\n                \n                crane_r[0] = new_r;\n                crane_c[0] = new_c;\n            }\n        }\n        \n        // Small cranes do nothing\n        for (int i = 1; i < N; ++i) {\n            turn_actions[i] = '.';\n        }\n        \n        // Step 3: Dispatch containers from right gates\n        for (int i = 0; i < N; ++i) {\n            if (has_container(i, N-1)) {\n                int container_id = grid[i][N-1];\n                dispatched[i].push_back(container_id);\n                container_dispatched[container_id] = true;\n                grid[i][N-1] = -1;\n                while (dispatch_next_needed[i] < (i+1)*N && container_dispatched[dispatch_next_needed[i]]) {\n                    dispatch_next_needed[i]++;\n                }\n            }\n        }\n        \n        // Record actions\n        for (int i = 0; i < N; ++i) {\n            actions[i] += turn_actions[i];\n        }\n        \n        // Check completion\n        bool all_done = true;\n        for (int id = 0; id < N*N; ++id) {\n            if (!container_dispatched[id]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_input;\n    cin >> N_input;\n    \n    for (int i = 0; i < N_input; ++i) {\n        gate_queues[i].resize(N_input);\n        for (int j = 0; j < N_input; ++j) {\n            cin >> gate_queues[i][j];\n        }\n    }\n    \n    vector<string> actions;\n    simulate(actions);\n    \n    // Pad shorter strings with '.'\n    size_t max_len = 0;\n    for (const string& s : actions) {\n        max_len = max(max_len, s.size());\n    }\n    for (string& s : actions) {\n        if (s.size() < max_len) {\n            s.append(max_len - s.size(), '.');\n        }\n    }\n    \n    for (const string& s : actions) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 20;\nconst int TOTAL_CELLS = N * N;\n\n// Generate snake path by rows\nvector<pair<int, int>> generate_path_rows() {\n    vector<pair<int, int>> path;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) path.emplace_back(i, j);\n        } else {\n            for (int j = N - 1; j >= 0; --j) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate snake path by columns\nvector<pair<int, int>> generate_path_cols() {\n    vector<pair<int, int>> path;\n    for (int j = 0; j < N; ++j) {\n        if (j % 2 == 0) {\n            for (int i = 0; i < N; ++i) path.emplace_back(i, j);\n        } else {\n            for (int i = N - 1; i >= 0; --i) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate clockwise spiral\nvector<pair<int, int>> generate_spiral_cw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) path.emplace_back(top, j);\n        top++;\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, right);\n        right--;\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(bottom, j);\n            bottom--;\n        }\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, left);\n            left++;\n        }\n    }\n    return path;\n}\n\n// Generate counterclockwise spiral\nvector<pair<int, int>> generate_spiral_ccw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, left);\n        left++;\n        for (int j = left; j <= right; ++j) path.emplace_back(bottom, j);\n        bottom--;\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, right);\n            right--;\n        }\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(top, j);\n            top++;\n        }\n    }\n    return path;\n}\n\n// Compute load-distance for a single tour (interleaved loading/unloading)\nint compute_load_distance(const vector<pair<int, int>>& path, const vector<vector<int>>& h) {\n    int load = 0;\n    int total_ld = 0;\n    for (int idx = 0; idx < (int)path.size(); ++idx) {\n        int i = path[idx].first, j = path[idx].second;\n        if (h[i][j] > 0) {\n            load += h[i][j];\n        } else if (h[i][j] < 0) {\n            int unload = min(load, -h[i][j]);\n            load -= unload;\n        }\n        if (idx < (int)path.size() - 1) {\n            total_ld += load;\n        }\n    }\n    return total_ld;\n}\n\n// Determine move direction\nstring get_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return \"U\";\n    if (ni == i + 1) return \"D\";\n    if (nj == j - 1) return \"L\";\n    if (nj == j + 1) return \"R\";\n    return \"\"; // should not happen\n}\n\nint main() {\n    // Read input\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    // Generate candidate paths\n    vector<vector<pair<int, int>>> candidates;\n    candidates.push_back(generate_path_rows());\n    candidates.push_back(generate_path_cols());\n    candidates.push_back(generate_spiral_cw());\n    candidates.push_back(generate_spiral_ccw());\n\n    // Choose path with minimal load-distance for single tour\n    int best_ld = INT_MAX;\n    vector<pair<int, int>> best_path;\n    for (const auto& path : candidates) {\n        int ld = compute_load_distance(path, h);\n        if (ld < best_ld) {\n            best_ld = ld;\n            best_path = path;\n        }\n    }\n\n    // Simulate operations for the chosen path (single tour)\n    vector<string> ops;\n    vector<vector<int>> cur_h = h;\n    int load = 0;\n    int cur_i = best_path[0].first, cur_j = best_path[0].second;\n\n    for (int idx = 0; idx < (int)best_path.size(); ++idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Process cell\n        if (cur_h[i][j] > 0) {\n            int d = cur_h[i][j];\n            ops.push_back(\"+\" + to_string(d));\n            load += d;\n            cur_h[i][j] = 0;\n        } else if (cur_h[i][j] < 0) {\n            int unload = min(load, -cur_h[i][j]);\n            if (unload > 0) {\n                ops.push_back(\"-\" + to_string(unload));\n                load -= unload;\n                cur_h[i][j] += unload;\n            }\n        }\n        // Move to next cell if not last\n        if (idx < (int)best_path.size() - 1) {\n            int ni = best_path[idx+1].first, nj = best_path[idx+1].second;\n            ops.push_back(get_move(cur_i, cur_j, ni, nj));\n            cur_i = ni; cur_j = nj;\n        }\n    }\n\n    // Output operations\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <utility>\n#include <set>\n#include <cstdlib>\n#include <ctime>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int T = 10;\nconst int K = 2 * N * (N - 1); // 60\nconst int MAX_ITER = 20000;    // iterations per SA run\nconst double INIT_TEMP = 100.0;\nconst double COOLING = 0.9999;\nconst int SA_RUNS = 2;         // number of independent SA runs\nconst double COMPLEMENT_WEIGHT = 0.5; // weight for complementarity in seed selection\n\n// Global seeds for current turn\nvector<vector<int>> seeds(K, vector<int>(M));\n\n// Compute potential max sum for a pair of seeds (indices)\nint potential_max(int a, int b) {\n    int sum = 0;\n    for (int l = 0; l < M; ++l) {\n        sum += max(seeds[a][l], seeds[b][l]);\n    }\n    return sum;\n}\n\n// Precompute adjacency list for the grid cells (0..35)\nvector<vector<int>> grid_adj() {\n    vector<vector<int>> adj(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int idx = i * N + j;\n            if (i + 1 < N) adj[idx].push_back((i+1)*N + j);\n            if (i - 1 >= 0) adj[idx].push_back((i-1)*N + j);\n            if (j + 1 < N) adj[idx].push_back(i*N + (j+1));\n            if (j - 1 >= 0) adj[idx].push_back(i*N + (j-1));\n        }\n    }\n    return adj;\n}\n\n// Simulated annealing on a given initial assignment, returns best assignment and its score\npair<vector<int>, int> run_sa(const vector<int>& init_assign,\n                               const vector<vector<int>>& pot,\n                               const vector<vector<int>>& adj,\n                               mt19937& rng) {\n    int num_cells = N*N;\n    vector<int> assign = init_assign;\n    // Compute initial total score\n    int total = 0;\n    for (int i = 0; i < num_cells; ++i) {\n        for (int j : adj[i]) {\n            if (i < j) { // each edge once\n                total += pot[assign[i]][assign[j]];\n            }\n        }\n    }\n    int best_total = total;\n    vector<int> best_assign = assign;\n\n    double temp = INIT_TEMP;\n    uniform_int_distribution<int> cell_dist(0, num_cells-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        int a = cell_dist(rng), b = cell_dist(rng);\n        while (a == b) b = cell_dist(rng);\n\n        // Collect edges incident to a or b (each edge once)\n        set<pair<int, int>> edge_set;\n        for (int nb : adj[a]) {\n            int u = a, v = nb;\n            if (u > v) swap(u, v);\n            edge_set.insert({u, v});\n        }\n        for (int nb : adj[b]) {\n            int u = b, v = nb;\n            if (u > v) swap(u, v);\n            edge_set.insert({u, v});\n        }\n\n        // Compute old contribution of these edges\n        int old_contrib = 0;\n        for (auto& e : edge_set) {\n            old_contrib += pot[assign[e.first]][assign[e.second]];\n        }\n\n        // Swap assignments\n        swap(assign[a], assign[b]);\n\n        // Compute new contribution\n        int new_contrib = 0;\n        for (auto& e : edge_set) {\n            new_contrib += pot[assign[e.first]][assign[e.second]];\n        }\n\n        int delta = new_contrib - old_contrib;\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            double prob = exp(delta / temp);\n            if (prob_dist(rng) < prob) accept = true;\n        }\n\n        if (accept) {\n            total += delta;\n            if (total > best_total) {\n                best_total = total;\n                best_assign = assign;\n            }\n        } else {\n            // revert swap\n            swap(assign[a], assign[b]);\n        }\n\n        temp *= COOLING;\n    }\n\n    return {best_assign, best_total};\n}\n\nint main() {\n    srand(time(0));\n    mt19937 rng(time(0));\n\n    // Read initial seeds\n    for (int i = 0; i < K; ++i) {\n        for (int l = 0; l < M; ++l) {\n            cin >> seeds[i][l];\n        }\n    }\n\n    // Precompute grid adjacency (once)\n    auto adj = grid_adj();\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Compute total sums\n        vector<int> sums(K, 0);\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                sums[i] += seeds[i][l];\n            }\n        }\n\n        // Select champion (highest sum)\n        int champion = 0;\n        for (int i = 1; i < K; ++i) {\n            if (sums[i] > sums[champion]) champion = i;\n        }\n\n        // Compute a score for each seed: sum + weight * potential_max with champion\n        vector<pair<int, double>> scores; // (seed_index, score)\n        for (int i = 0; i < K; ++i) {\n            if (i == champion) continue;\n            double score = sums[i] + COMPLEMENT_WEIGHT * potential_max(champion, i);\n            scores.emplace_back(i, score);\n        }\n        sort(scores.begin(), scores.end(),\n             [](const auto& a, const auto& b) { return a.second > b.second; });\n\n        // Select the top 35 seeds (excluding champion) to make total 36\n        vector<int> selected;\n        selected.push_back(champion);\n        for (int i = 0; i < 35; ++i) {\n            selected.push_back(scores[i].first);\n        }\n\n        // Map original index to local index (0..35)\n        vector<int> local_idx(K, -1);\n        for (int i = 0; i < 36; ++i) {\n            local_idx[selected[i]] = i;\n        }\n\n        // Precompute potential matrix for the selected seeds\n        vector<vector<int>> pot(36, vector<int>(36));\n        for (int i = 0; i < 36; ++i) {\n            for (int j = 0; j < 36; ++j) {\n                pot[i][j] = potential_max(selected[i], selected[j]);\n            }\n        }\n\n        // Generate an initial assignment: champion at center, rest in row-major order\n        vector<int> init_assign(N*N, -1);\n        int center = (N/2)*N + (N/2); // for N=6, center index = 3*6+3=21\n        init_assign[center] = local_idx[champion];\n        int cur = 0;\n        for (int cell = 0; cell < N*N; ++cell) {\n            if (cell == center) continue;\n            while (cur < 36 && (selected[cur] == champion)) ++cur;\n            init_assign[cell] = local_idx[selected[cur]];\n            ++cur;\n        }\n\n        // Run multiple SA runs and keep the best assignment\n        vector<int> best_assign;\n        int best_score = -1;\n\n        for (int run = 0; run < SA_RUNS; ++run) {\n            // Shuffle the non-champion seeds for diversity\n            vector<int> shuffled_assign = init_assign;\n            // Randomly permute the non-center cells\n            vector<int> non_center;\n            for (int cell = 0; cell < N*N; ++cell) {\n                if (cell != center) non_center.push_back(cell);\n            }\n            shuffle(non_center.begin(), non_center.end(), rng);\n            // Reassign the non-champion seeds randomly\n            vector<int> non_champion_local;\n            for (int i = 0; i < 36; ++i) {\n                if (selected[i] != champion) non_champion_local.push_back(i);\n            }\n            shuffle(non_champion_local.begin(), non_champion_local.end(), rng);\n            for (size_t i = 0; i < non_center.size(); ++i) {\n                shuffled_assign[non_center[i]] = non_champion_local[i];\n            }\n            shuffled_assign[center] = local_idx[champion];\n\n            auto [assign, score] = run_sa(shuffled_assign, pot, adj, rng);\n            if (score > best_score) {\n                best_score = score;\n                best_assign = assign;\n            }\n        }\n\n        // Convert local indices back to original seed indices for output\n        vector<vector<int>> grid(N, vector<int>(N));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                int cell = i * N + j;\n                int local = best_assign[cell];\n                grid[i][j] = selected[local];\n            }\n        }\n\n        // Output comments for debugging (ignored by judge)\n        cout << \"# Turn \" << turn << endl;\n        cout << \"# Champion: \" << champion << \" (sum=\" << sums[champion] << \")\" << endl;\n        cout << \"# Best SA score: \" << best_score << endl;\n\n        // Output the grid\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j > 0) cout << \" \";\n                cout << grid[i][j];\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read the next set of seeds (for the next turn)\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                cin >> seeds[i][l];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\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 sources that are not targets\n    vector<Point> src_no_target;\n    // Collect targets that are not sources\n    vector<Point> tgt_no_source;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0')\n                src_no_target.emplace_back(i, j);\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0')\n                tgt_no_source.emplace_back(i, j);\n        }\n    }\n\n    // Use 2 vertices: root (0) and leaf (1) with edge length 1\n    int V_prime = 2;\n    cout << V_prime << '\\n';\n    cout << 0 << ' ' << 1 << '\\n';\n\n    // Initial root position\n    int init_x = 0, init_y = 0;\n    cout << init_x << ' ' << init_y << '\\n';\n\n    // Simulation state\n    int rx = init_x, ry = init_y;\n    int leaf_dir = 0; // 0: right, 1: down, 2: left, 3: up\n    bool leaf_holding = false;\n\n    // Track occupancy of takoyaki\n    vector<vector<bool>> occupied(N, vector<bool>(N, false));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') occupied[i][j] = true;\n        }\n    }\n\n    vector<string> ops;\n\n    auto add_turn = [&](char move, int rot_vertex, char rot, int grab_vertex, char grab) {\n        string s(2 * V_prime, '.');\n        s[0] = move;\n        if (rot_vertex != -1) {\n            s[rot_vertex] = rot;\n        }\n        if (grab_vertex != -1) {\n            s[V_prime + grab_vertex] = grab;\n        }\n        ops.push_back(s);\n    };\n\n    // Helper to move from current position to target\n    auto move_to = [&](int tx, int ty) {\n        while (rx != tx) {\n            if (rx > tx) {\n                add_turn('U', -1, '.', -1, '.');\n                --rx;\n            } else {\n                add_turn('D', -1, '.', -1, '.');\n                ++rx;\n            }\n        }\n        while (ry != ty) {\n            if (ry > ty) {\n                add_turn('L', -1, '.', -1, '.');\n                --ry;\n            } else {\n                add_turn('R', -1, '.', -1, '.');\n                ++ry;\n            }\n        }\n    };\n\n    // Helper to rotate leaf to target direction\n    auto rotate_to = [&](int target_dir) {\n        int steps = (target_dir - leaf_dir + 4) % 4;\n        if (steps == 0) return;\n        if (steps == 1) {\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = target_dir;\n        } else if (steps == 3) {\n            add_turn('.', 1, 'L', -1, '.');\n            leaf_dir = target_dir;\n        } else { // steps == 2\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = (leaf_dir + 1) % 4;\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = target_dir;\n        }\n    };\n\n    // Process all sources that need to be moved\n    vector<Point> remaining_sources = src_no_target;\n    vector<Point> remaining_targets = tgt_no_source;\n    \n    while (!remaining_sources.empty()) {\n        // Get next source\n        Point src = remaining_sources.back();\n        remaining_sources.pop_back();\n        \n        // Find a valid neighbor for pickup\n        int pickup_x = -1, pickup_y = -1, pickup_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = src.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = src.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                pickup_x = nx;\n                pickup_y = ny;\n                pickup_dir = (d + 2) % 4;\n                break;\n            }\n        }\n        if (pickup_x == -1) continue; // Should not happen\n        \n        // Move to pickup position\n        move_to(pickup_x, pickup_y);\n        \n        // Rotate to point to source\n        rotate_to(pickup_dir);\n        \n        // Grab if not holding and source has takoyaki\n        if (!leaf_holding && occupied[src.x][src.y]) {\n            add_turn('.', 1, '.', 1, 'P');\n            leaf_holding = true;\n            occupied[src.x][src.y] = false;\n        }\n        \n        // Find an empty target\n        Point dst;\n        bool found_target = false;\n        for (int i = 0; i < remaining_targets.size(); ++i) {\n            if (!occupied[remaining_targets[i].x][remaining_targets[i].y]) {\n                dst = remaining_targets[i];\n                remaining_targets.erase(remaining_targets.begin() + i);\n                found_target = true;\n                break;\n            }\n        }\n        if (!found_target) continue; // Should not happen\n        \n        // Find a valid neighbor for drop\n        int drop_x = -1, drop_y = -1, drop_dir = -1;\n        for (int d = 0; d < 4; ++d) {\n            int nx = dst.x + (d == 1 ? 1 : (d == 3 ? -1 : 0));\n            int ny = dst.y + (d == 0 ? 1 : (d == 2 ? -1 : 0));\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                drop_x = nx;\n                drop_y = ny;\n                drop_dir = (d + 2) % 4;\n                break;\n            }\n        }\n        if (drop_x == -1) continue; // Should not happen\n        \n        // Move to drop position\n        move_to(drop_x, drop_y);\n        \n        // Rotate to point to target\n        rotate_to(drop_dir);\n        \n        // Release if holding and target is empty\n        if (leaf_holding && !occupied[dst.x][dst.y]) {\n            add_turn('.', 1, '.', 1, 'P');\n            leaf_holding = false;\n            occupied[dst.x][dst.y] = true;\n        }\n    }\n\n    // Output operations\n    for (const string& s : ops) {\n        cout << s << '\\n';\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_PERIMETER = 400000;\nconst vector<int> GRID_SIZES = {500, 250, 125};  // add finer grid\n\nstruct Rectangle {\n    int left, right, top, bottom;\n    int net;\n    int x_min, x_max, y_min, y_max;\n\n    Rectangle() : net(0) {}\n    Rectangle(int l, int r, int t, int b, int net_val,\n              const vector<int>& x_start, const vector<int>& x_end,\n              const vector<int>& y_start, const vector<int>& y_end)\n        : left(l), right(r), top(t), bottom(b), net(net_val) {\n        x_min = x_start[left];\n        x_max = x_end[right];\n        y_min = y_start[top];\n        y_max = y_end[bottom];\n    }\n\n    int perimeter() const {\n        int width = x_max - x_min + 1;\n        int height = y_max - y_min + 1;\n        return 2 * (width + height);\n    }\n};\n\nRectangle find_best_rectangle(const vector<vector<int>>& net, int G) {\n    int rows = net.size();\n    int cols = net[0].size();\n\n    vector<int> x_start(cols), x_end(cols);\n    for (int j = 0; j < cols; ++j) {\n        x_start[j] = j * G;\n        x_end[j] = (j == cols - 1) ? MAX_COORD : (j + 1) * G - 1;\n    }\n    vector<int> y_start(rows), y_end(rows);\n    for (int i = 0; i < rows; ++i) {\n        y_start[i] = i * G;\n        y_end[i] = (i == rows - 1) ? MAX_COORD : (i + 1) * G - 1;\n    }\n\n    Rectangle best;\n    best.net = 0;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (net[i][j] == 0) {\n                best = Rectangle(j, j, i, i, 0, x_start, x_end, y_start, y_end);\n                break;\n            }\n        }\n        if (best.net == 0) break;\n    }\n\n    for (int top = 0; top < rows; ++top) {\n        vector<int> col_sum(cols, 0);\n        for (int bottom = top; bottom < rows; ++bottom) {\n            for (int c = 0; c < cols; ++c) {\n                col_sum[c] += net[bottom][c];\n            }\n            int cur = 0, best_cur = 0;\n            int start = 0, best_start = 0, best_end = -1;\n            for (int c = 0; c < cols; ++c) {\n                if (cur <= 0) {\n                    cur = col_sum[c];\n                    start = c;\n                } else {\n                    cur += col_sum[c];\n                }\n                if (cur > best_cur) {\n                    best_cur = cur;\n                    best_start = start;\n                    best_end = c;\n                }\n            }\n            if (best_end == -1) continue;\n\n            Rectangle candidate(best_start, best_end, top, bottom, best_cur,\n                                x_start, x_end, y_start, y_end);\n            if (candidate.perimeter() <= MAX_PERIMETER && candidate.net > best.net) {\n                best = candidate;\n            }\n        }\n    }\n    return best;\n}\n\nstruct RegionGrower {\n    int G, rows, cols;\n    const vector<vector<int>>& net;\n    vector<vector<bool>> in_region;\n    int perimeter, total_net;\n    vector<pair<int, int>> region_cells;\n\n    static const int dx[4];\n    static const int dy[4];\n\n    RegionGrower(int G, const vector<vector<int>>& net)\n        : G(G), net(net), rows(net.size()), cols(net[0].size()) {\n        in_region.assign(rows, vector<bool>(cols, false));\n        perimeter = 0;\n        total_net = 0;\n    }\n\n    void add_cell(int i, int j) {\n        in_region[i][j] = true;\n        region_cells.emplace_back(i, j);\n        total_net += net[i][j];\n        int neighbors = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                ++neighbors;\n        }\n        perimeter += 4 - 2 * neighbors;\n    }\n\n    void grow() {\n        // Find seed with maximum net\n        int best_i = -1, best_j = -1, best_val = -1e9;\n        for (int i = 0; i < rows; ++i) {\n            for (int j = 0; j < cols; ++j) {\n                if (net[i][j] > best_val) {\n                    best_val = net[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        if (best_val <= 0) return;\n        add_cell(best_i, best_j);\n\n        set<pair<int, int>> candidates;\n        for (int d = 0; d < 4; ++d) {\n            int ni = best_i + dx[d], nj = best_j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                candidates.insert({ni, nj});\n        }\n\n        while (!candidates.empty() && perimeter <= MAX_PERIMETER) {\n            double best_priority = -1e18;\n            pair<int, int> best_cand;\n            for (const auto& cand : candidates) {\n                int i = cand.first, j = cand.second;\n                // Only consider cells with non-negative net\n                if (net[i][j] < 0) continue;\n                int delta_net = net[i][j];\n                int neighbors = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                        ++neighbors;\n                }\n                int delta_perim = 4 - 2 * neighbors;\n                double priority;\n                if (delta_perim > 0)\n                    priority = delta_net / (double)delta_perim;\n                else\n                    priority = delta_net * 1000.0;  // strongly favor perimeter reduction\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_cand = cand;\n                }\n            }\n            if (best_priority <= 0) break;\n\n            int i = best_cand.first, j = best_cand.second;\n            candidates.erase(best_cand);\n\n            int neighbors = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                    ++neighbors;\n            }\n            int delta_perim = 4 - 2 * neighbors;\n            if (perimeter + delta_perim > MAX_PERIMETER)\n                continue;\n\n            add_cell(i, j);\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                    candidates.insert({ni, nj});\n            }\n        }\n    }\n};\n\nconst int RegionGrower::dx[4] = {1, -1, 0, 0};\nconst int RegionGrower::dy[4] = {0, 0, 1, -1};\n\nvector<pair<int, int>> trace_boundary(const vector<vector<bool>>& in_region, int G, int rows, int cols) {\n    map<pair<int, int>, vector<pair<int, int>>> graph;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (!in_region[i][j]) continue;\n            if (j == 0 || !in_region[i][j - 1]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, j * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (j == cols - 1 || !in_region[i][j + 1]) {\n                pair<int, int> p1 = {i * G, (j + 1) * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == 0 || !in_region[i - 1][j]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {i * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == rows - 1 || !in_region[i + 1][j]) {\n                pair<int, int> p1 = {(i + 1) * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n        }\n    }\n    if (graph.empty()) return {};\n\n    auto start = graph.begin()->first;\n    vector<pair<int, int>> cycle;\n    pair<int, int> cur = start;\n    pair<int, int> prev = {-1, -1};\n    do {\n        cycle.push_back(cur);\n        const auto& neighbors = graph[cur];\n        pair<int, int> next;\n        for (const auto& nb : neighbors) {\n            if (nb != prev) {\n                next = nb;\n                break;\n            }\n        }\n        prev = cur;\n        cur = next;\n    } while (cur != start);\n\n    // Simplify collinear points\n    vector<pair<int, int>> simplified;\n    int n = cycle.size();\n    for (int i = 0; i < n; ++i) {\n        auto prev = cycle[(i - 1 + n) % n];\n        auto cur = cycle[i];\n        auto next = cycle[(i + 1) % n];\n        if (prev.first == cur.first && cur.first == next.first) continue;\n        if (prev.second == cur.second && cur.second == next.second) continue;\n        simplified.push_back(cur);\n    }\n    return simplified;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) cin >> mackerels[i].first >> mackerels[i].second;\n    for (int i = 0; i < N; ++i) cin >> sardines[i].first >> sardines[i].second;\n\n    int best_net = 0;\n    vector<pair<int, int>> best_polygon;\n    bool found_nonempty = false;\n\n    for (int G : GRID_SIZES) {\n        int rows = (MAX_COORD + G) / G;\n        int cols = rows;\n\n        vector<vector<int>> count_m(rows, vector<int>(cols, 0));\n        vector<vector<int>> count_s(rows, vector<int>(cols, 0));\n\n        for (auto& p : mackerels) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_m[i][j];\n        }\n        for (auto& p : sardines) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_s[i][j];\n        }\n\n        vector<vector<int>> net(rows, vector<int>(cols));\n        for (int i = 0; i < rows; ++i)\n            for (int j = 0; j < cols; ++j)\n                net[i][j] = count_m[i][j] - count_s[i][j];\n\n        // Rectangle search\n        Rectangle rect = find_best_rectangle(net, G);\n        if (rect.net > best_net) {\n            best_net = rect.net;\n            best_polygon = {\n                {rect.x_min, rect.y_min},\n                {rect.x_max, rect.y_min},\n                {rect.x_max, rect.y_max},\n                {rect.x_min, rect.y_max}\n            };\n            found_nonempty = (best_net > 0);\n        }\n\n        // Region growing\n        RegionGrower grower(G, net);\n        grower.grow();\n        if (grower.total_net > best_net) {\n            best_net = grower.total_net;\n            best_polygon = trace_boundary(grower.in_region, G, rows, cols);\n            found_nonempty = (best_net > 0);\n        }\n    }\n\n    if (!found_nonempty) {\n        best_polygon = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};\n    }\n\n    cout << best_polygon.size() << \"\\n\";\n    for (auto& p : best_polygon) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <map>\n#include <set>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Structure for a placement instruction\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference index or -1\n};\n\n// Simulation state: bounding boxes of placed rectangles\nstruct Rect {\n    double x1, y1, x2, y2;\n};\n\n// Check if two rectangles overlap (allowing touching)\nbool overlap(const Rect& a, const Rect& b) {\n    return (a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1);\n}\n\n// Simulate the placement sequence using estimated dimensions.\n// Returns true if valid (no overlap, all coordinates non-negative).\n// Also returns the bounding box (W, H).\nbool simulate(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est,\n              double& W, double& H, map<int, Rect>& boxes) {\n    boxes.clear();\n    W = 0.0;\n    H = 0.0;\n    set<int> placed;\n    for (const Placement& pl : seq) {\n        int id = pl.p;\n        double w, h;\n        if (pl.r == 0) {\n            w = w_est[id];\n            h = h_est[id];\n        } else {\n            w = h_est[id];\n            h = w_est[id];\n        }\n        Rect r;\n        if (pl.d == 'U') {\n            if (pl.b == -1) {\n                r.x1 = 0.0;\n                r.y1 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x1 = ref.x2;\n                r.y1 = ref.y2;\n            }\n            r.x2 = r.x1 + w;\n            r.y2 = r.y1 + h;\n        } else if (pl.d == 'L') {\n            if (pl.b == -1) {\n                r.x2 = 0.0;\n                r.y2 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x2 = ref.x1;\n                r.y2 = ref.y1;\n            }\n            r.x1 = r.x2 - w;\n            r.y1 = r.y2 - h;\n        } else {\n            return false; // invalid direction\n        }\n        // Check bounds\n        if (r.x1 < 0.0 || r.y1 < 0.0) return false;\n        // Check overlap with existing rectangles\n        for (const auto& kv : boxes) {\n            if (overlap(r, kv.second)) return false;\n        }\n        boxes[id] = r;\n        placed.insert(id);\n        W = max(W, r.x2);\n        H = max(H, r.y2);\n    }\n    return true;\n}\n\n// Compute estimated score for a sequence\ndouble estimated_score(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est) {\n    map<int, Rect> boxes;\n    double W, H;\n    if (!simulate(seq, w_est, h_est, W, H, boxes)) {\n        return 1e30; // invalid\n    }\n    set<int> placed;\n    for (const Placement& pl : seq) placed.insert(pl.p);\n    double penalty = 0.0;\n    for (size_t i = 0; i < w_est.size(); ++i) {\n        if (placed.count(i) == 0) {\n            penalty += w_est[i] + h_est[i];\n        }\n    }\n    return W + H + penalty;\n}\n\n// Greedy packing with balance choice\nvector<Placement> greedy_packing(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, bool randomize = true) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        struct Option {\n            double delta;\n            double newW, newH;\n            Placement pl;\n        };\n        vector<Option> options;\n\n        for (int rot = 0; rot < 2; ++rot) {\n            for (char dir : {'U', 'L'}) {\n                vector<int> refs = {-1};\n                for (int idx : placed) refs.push_back(idx);\n                for (int b : refs) {\n                    if (dir == 'L' && b == -1) continue;\n                    Placement pl{ i, rot, dir, b };\n                    vector<Placement> test_seq = seq;\n                    test_seq.push_back(pl);\n                    map<int, Rect> test_boxes;\n                    double newW, newH;\n                    if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                        double delta = (newW + newH) - (curW + curH);\n                        options.push_back({ delta, newW, newH, pl });\n                    }\n                }\n            }\n        }\n        double skip_penalty = w_est[i] + h_est[i];\n\n        if (options.empty()) continue;\n\n        // Find best delta\n        double best_delta = 1e30;\n        for (const auto& opt : options) {\n            if (opt.delta < best_delta) best_delta = opt.delta;\n        }\n        // Collect options with delta close to best\n        vector<Option> best_options;\n        for (const auto& opt : options) {\n            if (abs(opt.delta - best_delta) < 1e-6) best_options.push_back(opt);\n        }\n        // Choose option that minimizes |W - H|\n        Option chosen = best_options[0];\n        double best_balance = 1e30;\n        for (const auto& opt : best_options) {\n            double balance = fabs(opt.newW - opt.newH);\n            if (balance < best_balance) {\n                best_balance = balance;\n                chosen = opt;\n            }\n        }\n        // Add small randomness\n        if (randomize && best_options.size() > 1 && uniform_real_distribution<double>(0,1)(rng) < 0.2) {\n            chosen = best_options[uniform_int_distribution<int>(0, best_options.size()-1)(rng)];\n        }\n\n        if (best_delta < skip_penalty) {\n            seq.push_back(chosen.pl);\n            simulate(seq, w_est, h_est, curW, curH, current_boxes);\n            placed.insert(i);\n        }\n    }\n    return seq;\n}\n\n// Generate a random valid sequence\nvector<Placement> random_valid_sequence(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Decide whether to place this rectangle (probability 0.9)\n        if (uniform_real_distribution<double>(0,1)(rng) > 0.9) continue;\n        // Try to place with random parameters\n        bool placed_ok = false;\n        for (int attempt = 0; attempt < 10; ++attempt) {\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_real_distribution<double>(0,1)(rng) < 0.5) ? 'U' : 'L';\n            vector<int> refs = {-1};\n            for (int idx : placed) refs.push_back(idx);\n            int b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n            if (dir == 'L' && b == -1) continue; // invalid\n            Placement pl{i, rot, dir, b};\n            vector<Placement> test_seq = seq;\n            test_seq.push_back(pl);\n            map<int, Rect> test_boxes;\n            double newW, newH;\n            if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                // Valid\n                seq.push_back(pl);\n                current_boxes = test_boxes;\n                curW = newW;\n                curH = newH;\n                placed.insert(i);\n                placed_ok = true;\n                break;\n            }\n        }\n        // if not placed after attempts, skip\n    }\n    return seq;\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    vector<int> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Initialize measurement accumulators with the initial observations as one measurement each\n    vector<double> w_meas_sum(N), h_meas_sum(N);\n    vector<int> cnt_w(N, 1), cnt_h(N, 1);\n    for (int i = 0; i < N; ++i) {\n        w_meas_sum[i] = w_obs[i];\n        h_meas_sum[i] = h_obs[i];\n    }\n    // Current estimates\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = w_meas_sum[i] / cnt_w[i];\n        h_est[i] = h_meas_sum[i] / cnt_h[i];\n    }\n\n    // Determine number of measurement attempts\n    int M;\n    if (T >= 2 * N) {\n        M = 2 * N; // we will do 2N measurements (each rectangle measured twice)\n    } else if (T >= N) {\n        M = N; // each rectangle measured once\n    } else {\n        M = T / 2; // half for measurement, half for packing\n    }\n    int measurement_done = 0;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Placement> best_est_seq; // best sequence by estimated score\n    double best_est_score = 1e30;\n    vector<Placement> best_actual_seq; // best sequence by actual score\n    double best_actual_score = 1e30;\n\n    for (int t = 0; t < T; ++t) {\n        // Decide whether to do a measurement attempt\n        if (measurement_done < M) {\n            // Choose a random rectangle to measure\n            int i = uniform_int_distribution<int>(0, N-1)(rng);\n            int r = uniform_int_distribution<int>(0,1)(rng);\n            // Output single rectangle placement\n            cout << 1 << '\\n';\n            cout << i << ' ' << r << ' ' << 'U' << ' ' << -1 << '\\n';\n            cout.flush();\n\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n\n            // Update measurements\n            if (r == 0) {\n                w_meas_sum[i] += W_meas;\n                h_meas_sum[i] += H_meas;\n            } else {\n                w_meas_sum[i] += H_meas;\n                h_meas_sum[i] += W_meas;\n            }\n            cnt_w[i]++;\n            cnt_h[i]++;\n            w_est[i] = w_meas_sum[i] / cnt_w[i];\n            h_est[i] = h_meas_sum[i] / cnt_h[i];\n\n            measurement_done++;\n            // No need to compute score for measurement attempts (they are poor)\n            continue;\n        }\n\n        // Packing attempt\n        vector<Placement> cur_seq;\n        // With probability 0.3, generate a new random sequence; else use best_est_seq or generate greedy\n        if (uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n            // Generate a random sequence\n            cur_seq = random_valid_sequence(w_est, h_est, rng);\n        } else if (!best_est_seq.empty() && uniform_real_distribution<double>(0,1)(rng) < 0.7) {\n            // Use the current best estimated sequence\n            cur_seq = best_est_seq;\n        } else {\n            // Generate a greedy packing with perturbed estimates\n            vector<double> pert_w = w_est, pert_h = h_est;\n            normal_distribution<double> noise(0.0, sigma * 0.5);\n            for (int i = 0; i < N; ++i) {\n                pert_w[i] += noise(rng);\n                pert_h[i] += noise(rng);\n                if (pert_w[i] < 1.0) pert_w[i] = 1.0;\n                if (pert_h[i] < 1.0) pert_h[i] = 1.0;\n            }\n            cur_seq = greedy_packing(pert_w, pert_h, rng, true);\n        }\n\n        // Ensure sequence is valid under current estimates; if not, fallback to greedy\n        {\n            map<int, Rect> dummy_boxes;\n            double dummyW, dummyH;\n            if (!simulate(cur_seq, w_est, h_est, dummyW, dummyH, dummy_boxes)) {\n                cur_seq = greedy_packing(w_est, h_est, rng, true);\n            }\n        }\n\n        // Compute estimated score for this sequence\n        double est_score = estimated_score(cur_seq, w_est, h_est);\n        if (est_score < best_est_score) {\n            best_est_score = est_score;\n            best_est_seq = cur_seq;\n        }\n\n        // Decide which sequence to output\n        vector<Placement> output_seq;\n        if (t % 5 == 0 && !best_actual_seq.empty()) {\n            // Occasionally output the best actual sequence found so far\n            output_seq = best_actual_seq;\n        } else {\n            // Otherwise output the current sequence\n            output_seq = cur_seq;\n        }\n\n        // Output the sequence\n        cout << output_seq.size() << '\\n';\n        for (const Placement& pl : output_seq) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout.flush();\n\n        // Read measurement\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n\n        // Compute actual score\n        set<int> placed_ids;\n        for (const Placement& pl : output_seq) placed_ids.insert(pl.p);\n        double penalty = 0.0;\n        for (int i = 0; i < N; ++i) {\n            if (placed_ids.count(i) == 0) {\n                penalty += w_est[i] + h_est[i];\n            }\n        }\n        double score = W_meas + H_meas + penalty;\n\n        // Update best actual\n        if (score < best_actual_score) {\n            best_actual_score = score;\n            best_actual_seq = output_seq;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int INF = 1000; // larger than any possible distance\n\n// Perform weighted set cover with given cost function\nvector<int> set_cover(const vector<bitset<MAXN>>& cover,\n                      const vector<int>& A, int N,\n                      function<double(int)> cost_func) {\n    bitset<MAXN> uncovered;\n    uncovered.set();\n    vector<int> roots;\n    while (uncovered.any()) {\n        int best = -1;\n        double best_ratio = 1e18;\n        for (int v = 0; v < N; ++v) {\n            bitset<MAXN> cur = cover[v] & uncovered;\n            if (cur.none()) continue;\n            int gain = cur.count();\n            double ratio = cost_func(v) / gain;\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best = v;\n            }\n        }\n        if (best == -1) break;\n        roots.push_back(best);\n        uncovered &= ~cover[best];\n    }\n    return roots;\n}\n\n// Build forest from roots: assign each vertex to nearest root, then BFS tree\nvoid build_forest(const vector<int>& roots,\n                  const vector<vector<short>>& dist,\n                  const vector<vector<int>>& adj,\n                  vector<int>& parent,\n                  vector<int>& depth,\n                  vector<int>& root_of,\n                  int N, int H) {\n    // assign nearest root and distance\n    for (int v = 0; v < N; ++v) {\n        int best_r = -1, best_d = INF;\n        for (int r : roots) {\n            int d = dist[v][r];\n            if (d < best_d) {\n                best_d = d;\n                best_r = r;\n            }\n        }\n        root_of[v] = best_r;\n        depth[v] = best_d;\n    }\n\n    // build parent pointers (choose one neighbor closer to root)\n    for (int v = 0; v < N; ++v) {\n        if (root_of[v] == v) {\n            parent[v] = -1;\n            continue;\n        }\n        int r = root_of[v];\n        int d = depth[v];\n        bool found = false;\n        for (int u : adj[v]) {\n            if (root_of[u] == r && dist[u][r] == d - 1) {\n                parent[v] = u;\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            // fallback: any neighbor with same root and smaller distance\n            for (int u : adj[v]) {\n                if (root_of[u] == r && dist[u][r] < d) {\n                    parent[v] = u;\n                    break;\n                }\n            }\n        }\n    }\n}\n\n// Local improvement: try to increase depth of vertices with high A\nvoid local_improvement(vector<int>& parent,\n                       vector<int>& depth,\n                       vector<int>& root_of,\n                       const vector<vector<int>>& adj,\n                       const vector<int>& A,\n                       int N, int H) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // Create order based on potential gain: A[v] * (H - depth[v])\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return A[a] * (H - depth[a]) > A[b] * (H - depth[b]);\n        });\n\n        for (int v : order) {\n            if (parent[v] == -1) continue; // root\n            if (depth[v] >= H) continue; // cannot go deeper\n\n            // Collect subtree of v (descendants)\n            vector<int> subtree;\n            stack<int> stk;\n            stk.push(v);\n            while (!stk.empty()) {\n                int x = stk.top(); stk.pop();\n                subtree.push_back(x);\n                for (int y : adj[x]) {\n                    if (parent[y] == x && root_of[y] == root_of[v]) {\n                        stk.push(y);\n                    }\n                }\n            }\n\n            // Try each neighbor u as potential new parent\n            for (int u : adj[v]) {\n                if (root_of[u] != root_of[v]) continue;\n                if (u == parent[v]) continue; // same parent\n                // u must not be in the subtree of v\n                bool in_subtree = false;\n                for (int x : subtree) {\n                    if (x == u) {\n                        in_subtree = true;\n                        break;\n                    }\n                }\n                if (in_subtree) continue;\n\n                // Only consider if depth[u] >= depth[v] to potentially increase depth\n                if (depth[u] < depth[v]) continue;\n\n                int new_depth_v = depth[u] + 1;\n                if (new_depth_v <= depth[v]) continue; // not increasing\n                if (new_depth_v > H) continue; // would exceed H for v\n\n                int delta = new_depth_v - depth[v];\n                // Check that after increasing, all vertices in subtree have depth <= H\n                bool ok = true;\n                for (int x : subtree) {\n                    if (depth[x] + delta > H) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (!ok) continue;\n\n                // Perform the change\n                parent[v] = u;\n                // Increase depth of all vertices in subtree by delta\n                for (int x : subtree) {\n                    depth[x] += delta;\n                }\n                improved = true;\n                break; // move to next vertex after change\n            }\n        }\n    }\n}\n\n// Compute total attractiveness\nlong long compute_score(const vector<int>& depth, const vector<int>& A, int N) {\n    long long score = 0;\n    for (int v = 0; v < N; ++v) {\n        score += (depth[v] + 1) * 1LL * A[v];\n    }\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    // coordinates are not needed for this algorithm\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // All-pairs shortest distances (BFS from each vertex)\n    vector<vector<short>> dist(N, vector<short>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        queue<int> q;\n        dist[s][s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Precompute cover bitsets\n    vector<bitset<MAXN>> cover(N);\n    for (int r = 0; r < N; ++r) {\n        for (int v = 0; v < N; ++v) {\n            short d = dist[r][v];\n            if (d != -1 && d <= H) {\n                cover[r].set(v);\n            }\n        }\n    }\n\n    // Try several root selection strategies\n    vector<pair<long long, vector<int>>> candidates;\n\n    auto evaluate = [&](const vector<int>& roots) {\n        vector<int> parent(N, -1);\n        vector<int> depth(N, INF);\n        vector<int> root_of(N, -1);\n        build_forest(roots, dist, adj, parent, depth, root_of, N, H);\n        local_improvement(parent, depth, root_of, adj, A, N, H);\n        long long score = compute_score(depth, A, N);\n        return make_pair(score, parent);\n    };\n\n    // Strategy 1: cost = A[v] (weighted)\n    auto roots1 = set_cover(cover, A, N, [&](int v) { return A[v]; });\n    candidates.push_back(evaluate(roots1));\n\n    // Strategy 2: cost = 1 (unweighted)\n    auto roots2 = set_cover(cover, A, N, [](int v) { return 1.0; });\n    candidates.push_back(evaluate(roots2));\n\n    // Strategy 3: cost = A[v] * (H+1) (penalize high A more)\n    auto roots3 = set_cover(cover, A, N, [&](int v) { return A[v] * (H + 1); });\n    candidates.push_back(evaluate(roots3));\n\n    // Strategy 4: cost = sqrt(A[v]) (less penalty)\n    auto roots4 = set_cover(cover, A, N, [&](int v) { return sqrt(A[v]); });\n    candidates.push_back(evaluate(roots4));\n\n    // Choose best\n    int best_idx = 0;\n    for (size_t i = 1; i < candidates.size(); ++i) {\n        if (candidates[i].first > candidates[best_idx].first) {\n            best_idx = i;\n        }\n    }\n\n    // Output best parent array\n    const auto& best_parent = candidates[best_idx].second;\n    for (int i = 0; i < N; ++i) {\n        cout << best_parent[i];\n        if (i < N - 1) cout << ' ';\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<pair<char, int>> moves;\n    const int MAX_MOVES = 4 * N * N;\n\n    // Helper functions to perform a single shift and record the move\n    auto shiftRowLeft = [&](int i) {\n        char removed = board[i][0]; // not used\n        for (int j = 0; j < N - 1; ++j) {\n            board[i][j] = board[i][j + 1];\n        }\n        board[i][N - 1] = '.';\n        moves.push_back({'L', i});\n    };\n\n    auto shiftRowRight = [&](int i) {\n        char removed = board[i][N - 1];\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n        moves.push_back({'R', i});\n    };\n\n    auto shiftColUp = [&](int j) {\n        char removed = board[0][j];\n        for (int i = 0; i < N - 1; ++i) {\n            board[i][j] = board[i + 1][j];\n        }\n        board[N - 1][j] = '.';\n        moves.push_back({'U', j});\n    };\n\n    auto shiftColDown = [&](int j) {\n        char removed = board[N - 1][j];\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n        moves.push_back({'D', j});\n    };\n\n    // Check if a shift can be performed safely (edge not Fukunokami)\n    auto canShiftSafely = [&](char dir, int idx) -> bool {\n        if (dir == 'L') {\n            return board[idx][0] != 'o';\n        } else if (dir == 'R') {\n            return board[idx][N-1] != 'o';\n        } else if (dir == 'U') {\n            return board[0][idx] != 'o';\n        } else { // 'D'\n            return board[N-1][idx] != 'o';\n        }\n    };\n\n    // Try to remove a specific Oni by attempting each direction, checking safety per shift\n    auto tryRemoveOni = [&](int i, int j) -> bool {\n        vector<pair<char, int>> directions = {\n            {'U', j},\n            {'D', j},\n            {'L', i},\n            {'R', i}\n        };\n        vector<int> shifts_needed = {i+1, N-i, j+1, N-j};\n        \n        for (int d = 0; d < 4; ++d) {\n            char dir = directions[d].first;\n            int idx = directions[d].second;\n            int shifts = shifts_needed[d];\n            \n            bool safe = true;\n            vector<string> temp = board;\n            for (int s = 0; s < shifts; ++s) {\n                if (!canShiftSafely(dir, idx)) {\n                    safe = false;\n                    break;\n                }\n                // Perform the shift on temp board\n                if (dir == 'L') {\n                    for (int c = 0; c < N-1; ++c) temp[i][c] = temp[i][c+1];\n                    temp[i][N-1] = '.';\n                } else if (dir == 'R') {\n                    for (int c = N-1; c > 0; --c) temp[i][c] = temp[i][c-1];\n                    temp[i][0] = '.';\n                } else if (dir == 'U') {\n                    for (int r = 0; r < N-1; ++r) temp[r][j] = temp[r+1][j];\n                    temp[N-1][j] = '.';\n                } else { // 'D'\n                    for (int r = N-1; r > 0; --r) temp[r][j] = temp[r-1][j];\n                    temp[0][j] = '.';\n                }\n            }\n            if (safe) {\n                // Actually perform the shifts on the real board\n                if (dir == 'U') {\n                    for (int s = 0; s < shifts; ++s) shiftColUp(j);\n                } else if (dir == 'D') {\n                    for (int s = 0; s < shifts; ++s) shiftColDown(j);\n                } else if (dir == 'L') {\n                    for (int s = 0; s < shifts; ++s) shiftRowLeft(i);\n                } else if (dir == 'R') {\n                    for (int s = 0; s < shifts; ++s) shiftRowRight(i);\n                }\n                return true;\n            }\n        }\n        return false;\n    };\n\n    // Find a clean row (no Fukunokami) and the best direction to remove all its Oni\n    auto findBestCleanRow = [&]() -> pair<int, char> {\n        int bestRow = -1;\n        char bestDir = ' ';\n        int bestShifts = N+1;\n        for (int i = 0; i < N; ++i) {\n            bool has_fuku = false;\n            int maxCol = -1, minCol = N;\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'o') {\n                    has_fuku = true;\n                    break;\n                }\n                if (board[i][j] == 'x') {\n                    maxCol = max(maxCol, j);\n                    minCol = min(minCol, j);\n                }\n            }\n            if (has_fuku) continue;\n            if (maxCol == -1) continue; // no Oni\n            int shiftsLeft = maxCol + 1;\n            if (shiftsLeft < bestShifts) {\n                bestShifts = shiftsLeft;\n                bestRow = i;\n                bestDir = 'L';\n            }\n            int shiftsRight = N - minCol;\n            if (shiftsRight < bestShifts) {\n                bestShifts = shiftsRight;\n                bestRow = i;\n                bestDir = 'R';\n            }\n        }\n        return {bestRow, bestDir};\n    };\n\n    // Find a clean column (no Fukunokami) and the best direction to remove all its Oni\n    auto findBestCleanCol = [&]() -> pair<int, char> {\n        int bestCol = -1;\n        char bestDir = ' ';\n        int bestShifts = N+1;\n        for (int j = 0; j < N; ++j) {\n            bool has_fuku = false;\n            int maxRow = -1, minRow = N;\n            for (int i = 0; i < N; ++i) {\n                if (board[i][j] == 'o') {\n                    has_fuku = true;\n                    break;\n                }\n                if (board[i][j] == 'x') {\n                    maxRow = max(maxRow, i);\n                    minRow = min(minRow, i);\n                }\n            }\n            if (has_fuku) continue;\n            if (maxRow == -1) continue;\n            int shiftsUp = maxRow + 1;\n            if (shiftsUp < bestShifts) {\n                bestShifts = shiftsUp;\n                bestCol = j;\n                bestDir = 'U';\n            }\n            int shiftsDown = N - minRow;\n            if (shiftsDown < bestShifts) {\n                bestShifts = shiftsDown;\n                bestCol = j;\n                bestDir = 'D';\n            }\n        }\n        return {bestCol, bestDir};\n    };\n\n    // Helper to count Oni with safe directions in a given board state\n    auto countSafeDirections = [&](const vector<string>& b) -> int {\n        int cnt = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (b[i][j] != 'x') continue;\n                bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n                for (int r = 0; r < i; ++r) if (b[r][j] == 'o') safeUp = false;\n                for (int r = i+1; r < N; ++r) if (b[r][j] == 'o') safeDown = false;\n                for (int c = 0; c < j; ++c) if (b[i][c] == 'o') safeLeft = false;\n                for (int c = j+1; c < N; ++c) if (b[i][c] == 'o') safeRight = false;\n                if (safeUp || safeDown || safeLeft || safeRight) cnt++;\n            }\n        }\n        return cnt;\n    };\n\n    int stuck_counter = 0;\n    const int MAX_STUCK = 100;\n\n    while (moves.size() < MAX_MOVES) {\n        // High\u2011priority: remove all Oni from a clean row or column in one batch\n        auto [cleanRow, rowDir] = findBestCleanRow();\n        auto [cleanCol, colDir] = findBestCleanCol();\n        bool didBatch = false;\n        if (cleanRow != -1 && (cleanCol == -1 || \n            (rowDir == 'L' ? (cleanRow + 1) : (N - cleanRow)) <= \n            (colDir == 'U' ? (cleanCol + 1) : (N - cleanCol)))) {\n            if (rowDir == 'L') {\n                for (int k = 0; k <= cleanRow; ++k) shiftRowLeft(cleanRow);\n            } else { // 'R'\n                for (int k = 0; k < N - cleanRow; ++k) shiftRowRight(cleanRow);\n            }\n            didBatch = true;\n        } else if (cleanCol != -1) {\n            if (colDir == 'U') {\n                for (int k = 0; k <= cleanCol; ++k) shiftColUp(cleanCol);\n            } else { // 'D'\n                for (int k = 0; k < N - cleanCol; ++k) shiftColDown(cleanCol);\n            }\n            didBatch = true;\n        }\n        if (didBatch) {\n            stuck_counter = 0;\n            continue;\n        }\n\n        // Compute current Oni and their safe directions count\n        vector<pair<int, int>> oniList;\n        vector<int> safeCount;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    oniList.emplace_back(i, j);\n                    bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n                    for (int r = 0; r < i; ++r) if (board[r][j] == 'o') safeUp = false;\n                    for (int r = i+1; r < N; ++r) if (board[r][j] == 'o') safeDown = false;\n                    for (int c = 0; c < j; ++c) if (board[i][c] == 'o') safeLeft = false;\n                    for (int c = j+1; c < N; ++c) if (board[i][c] == 'o') safeRight = false;\n                    int cnt = safeUp + safeDown + safeLeft + safeRight;\n                    safeCount.push_back(cnt);\n                }\n            }\n        }\n        if (oniList.empty()) break;\n\n        // Find Oni with minimum safeCount (>0)\n        int minSafe = 5;\n        for (int cnt : safeCount) if (cnt > 0 && cnt < minSafe) minSafe = cnt;\n        if (minSafe == 5) {\n            // No Oni with safe direction -> stuck handling\n            stuck_counter++;\n            if (stuck_counter > MAX_STUCK) break; // safety break\n\n            // Generate all safe shifts and pick the one that maximizes Oni with safe directions after shift\n            int bestScore = -1;\n            char bestDir = ' ';\n            int bestIdx = -1; // row or col index\n            bool isRow = true;\n\n            // Try row left/right\n            for (int i = 0; i < N; ++i) {\n                if (board[i][0] != 'o') {\n                    // left shift safe\n                    vector<string> temp = board;\n                    // simulate left shift\n                    for (int c = 0; c < N-1; ++c) temp[i][c] = temp[i][c+1];\n                    temp[i][N-1] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'L';\n                        bestIdx = i;\n                        isRow = true;\n                    }\n                }\n                if (board[i][N-1] != 'o') {\n                    // right shift safe\n                    vector<string> temp = board;\n                    for (int c = N-1; c > 0; --c) temp[i][c] = temp[i][c-1];\n                    temp[i][0] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'R';\n                        bestIdx = i;\n                        isRow = true;\n                    }\n                }\n            }\n            // Try column up/down\n            for (int j = 0; j < N; ++j) {\n                if (board[0][j] != 'o') {\n                    // up shift safe\n                    vector<string> temp = board;\n                    for (int r = 0; r < N-1; ++r) temp[r][j] = temp[r+1][j];\n                    temp[N-1][j] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'U';\n                        bestIdx = j;\n                        isRow = false;\n                    }\n                }\n                if (board[N-1][j] != 'o') {\n                    // down shift safe\n                    vector<string> temp = board;\n                    for (int r = N-1; r > 0; --r) temp[r][j] = temp[r-1][j];\n                    temp[0][j] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'D';\n                        bestIdx = j;\n                        isRow = false;\n                    }\n                }\n            }\n\n            if (bestIdx != -1) {\n                if (isRow) {\n                    if (bestDir == 'L') shiftRowLeft(bestIdx);\n                    else shiftRowRight(bestIdx);\n                } else {\n                    if (bestDir == 'U') shiftColUp(bestIdx);\n                    else shiftColDown(bestIdx);\n                }\n                continue;\n            } else {\n                // No safe shift at all -> try fallback removal (might remove Fukunokami? but we accept as last resort)\n                for (auto [i, j] : oniList) {\n                    if (tryRemoveOni(i, j)) break;\n                }\n                continue;\n            }\n        }\n\n        // Among Oni with minSafe, pick the one with best removal ratio\n        int bestIdx = -1;\n        char bestDir = ' ';\n        double bestScore = -1.0;\n        for (size_t idx = 0; idx < oniList.size(); ++idx) {\n            if (safeCount[idx] != minSafe) continue;\n            auto [i, j] = oniList[idx];\n            bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n            for (int r = 0; r < i; ++r) if (board[r][j] == 'o') safeUp = false;\n            for (int r = i+1; r < N; ++r) if (board[r][j] == 'o') safeDown = false;\n            for (int c = 0; c < j; ++c) if (board[i][c] == 'o') safeLeft = false;\n            for (int c = j+1; c < N; ++c) if (board[i][c] == 'o') safeRight = false;\n\n            if (safeUp) {\n                int shifts = i + 1;\n                int removed = 0;\n                for (int r = 0; r <= i; ++r) if (board[r][j] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'U';\n                }\n            }\n            if (safeDown) {\n                int shifts = N - i;\n                int removed = 0;\n                for (int r = i; r < N; ++r) if (board[r][j] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'D';\n                }\n            }\n            if (safeLeft) {\n                int shifts = j + 1;\n                int removed = 0;\n                for (int c = 0; c <= j; ++c) if (board[i][c] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'L';\n                }\n            }\n            if (safeRight) {\n                int shifts = N - j;\n                int removed = 0;\n                for (int c = j; c < N; ++c) if (board[i][c] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestIdx = idx;\n                    bestDir = 'R';\n                }\n            }\n        }\n\n        if (bestIdx == -1) {\n            // Should not happen, but fallback\n            for (auto [i, j] : oniList) {\n                if (tryRemoveOni(i, j)) break;\n            }\n            stuck_counter++;\n            if (stuck_counter > MAX_STUCK) break;\n            continue;\n        }\n\n        auto [i, j] = oniList[bestIdx];\n        if (bestDir == 'U') {\n            for (int k = 0; k < i + 1; ++k) shiftColUp(j);\n        } else if (bestDir == 'D') {\n            for (int k = 0; k < N - i; ++k) shiftColDown(j);\n        } else if (bestDir == 'L') {\n            for (int k = 0; k < j + 1; ++k) shiftRowLeft(i);\n        } else if (bestDir == 'R') {\n            for (int k = 0; k < N - j; ++k) shiftRowRight(i);\n        }\n        stuck_counter = 0;\n    }\n\n    // Output the moves\n    for (auto [d, p] : moves) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast simulation that reuses a preallocated cnt array\npair<long long, vector<int>&> simulate(vector<int>& cnt, const vector<int>& a, const vector<int>& b, const vector<long long>& T, int N, long long L) {\n    fill(cnt.begin(), cnt.end(), 0);\n    int current = 0;\n    cnt[current] = 1;\n    for (long long week = 2; week <= L; ++week) {\n        if (cnt[current] & 1) {  // faster than modulo\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        ++cnt[current];\n    }\n    long long error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(cnt[i] - T[i]);\n    }\n    return {error, cnt};\n}\n\n// Dinic's max flow\nstruct Edge {\n    int to, rev;\n    long long cap;\n};\nclass Dinic {\npublic:\n    vector<vector<Edge>> graph;\n    vector<int> level, iter;\n    Dinic(int n) : graph(n), level(n), iter(n) {}\n    void add_edge(int from, int to, long long cap) {\n        graph[from].push_back({to, (int)graph[to].size(), cap});\n        graph[to].push_back({from, (int)graph[from].size() - 1, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto& e : graph[v]) {\n                if (e.cap > 0 && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    long long dfs(int v, int t, long long f) {\n        if (v == t) return f;\n        for (int& i = iter[v]; i < (int)graph[v].size(); ++i) {\n            Edge& e = graph[v][i];\n            if (e.cap > 0 && level[v] < level[e.to]) {\n                long long d = dfs(e.to, t, min(f, e.cap));\n                if (d > 0) {\n                    e.cap -= d;\n                    graph[e.to][e.rev].cap += d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    long long max_flow(int s, int t) {\n        long long flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            long long f;\n            while ((f = dfs(s, t, 1e18)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 100;\n    const long long L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // Build flow network\n    int source = 0;\n    int left_start = 1;                     // 1 .. 200\n    int right_start = left_start + 2 * N;   // 201 .. 300\n    int sink = right_start + N;             // 301\n    Dinic dinic(sink + 1);\n\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n        dinic.add_edge(source, node1, T[i]);\n        dinic.add_edge(source, node2, T[i]);\n    }\n    for (int j = 0; j < N; ++j) {\n        int node = right_start + j;\n        dinic.add_edge(node, sink, 2 * T[j]);\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node1 = left_start + 2 * i;\n            int node2 = left_start + 2 * i + 1;\n            int right_node = right_start + j;\n            dinic.add_edge(node1, right_node, L);\n            dinic.add_edge(node2, right_node, L);\n        }\n    }\n    long long flow = dinic.max_flow(source, sink);\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n\n        long long max_fl1 = -1;\n        int best_j1 = 0;\n        for (auto& e : dinic.graph[node1]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl1) {\n                    max_fl1 = fl;\n                    best_j1 = e.to - right_start;\n                }\n            }\n        }\n        a[i] = best_j1;\n\n        long long max_fl2 = -1;\n        int best_j2 = 0;\n        for (auto& e : dinic.graph[node2]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl2) {\n                    max_fl2 = fl;\n                    best_j2 = e.to - right_start;\n                }\n            }\n        }\n        b[i] = best_j2;\n    }\n\n    // Initial simulation\n    vector<int> cnt(N);\n    auto [best_error, _] = simulate(cnt, a, b, T, N, L);\n    vector<int> best_a = a, best_b = b;\n    vector<long long> err(N);\n    for (int i = 0; i < N; ++i) err[i] = cnt[i] - T[i];\n\n    // Local search with bias\n    const int max_iter = 2000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_emp(0, N-1);\n    uniform_int_distribution<int> rand_bool(0, 1);\n    uniform_int_distribution<int> rand_val(0, N-1);\n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        int i = rand_emp(rng);\n        bool change_a = rand_bool(rng);\n        int new_val;\n\n        if (err[i] > 0) {\n            // Collect under-visited employees\n            vector<int> candidates;\n            for (int j = 0; j < N; ++j) if (err[j] < 0) candidates.push_back(j);\n            if (!candidates.empty()) {\n                uniform_int_distribution<int> rand_cand(0, candidates.size()-1);\n                new_val = candidates[rand_cand(rng)];\n            } else {\n                new_val = rand_val(rng);\n            }\n        } else {\n            new_val = rand_val(rng);\n        }\n\n        int old_val = change_a ? best_a[i] : best_b[i];\n        if (change_a) a[i] = new_val;\n        else b[i] = new_val;\n\n        auto [new_error, new_cnt] = simulate(cnt, a, b, T, N, L);\n        if (new_error < best_error) {\n            best_error = new_error;\n            if (change_a) best_a[i] = new_val;\n            else best_b[i] = new_val;\n            for (int j = 0; j < N; ++j) err[j] = new_cnt[j] - T[j];\n        } else {\n            if (change_a) a[i] = old_val;\n            else b[i] = old_val;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int, int>;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\n\nvector<vector<int>> groups;\nvector<vector<pii>> group_edges;\n\n// Fortune\u2011telling query\nvector<pii> query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    vector<pii> edges;\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\n// Hilbert curve index for integer coordinates (14\u2011bit precision)\nuint64_t hilbertOrder(int x, int y) {\n    int pow = 14;\n    uint64_t d = 0;\n    int s = 1 << (pow - 1);\n    for (int i = pow - 1; i >= 0; --i) {\n        int rx = (x & s) ? 1 : 0;\n        int ry = (y & s) ? 1 : 0;\n        d = (d << 2) | ((rx * 3) ^ ry);\n        if (!ry) {\n            if (rx) {\n                x = (1 << pow) - 1 - x;\n                y = (1 << pow) - 1 - y;\n            }\n            swap(x, y);\n        }\n        s >>= 1;\n    }\n    return d;\n}\n\n// Approximate TSP order using nearest neighbor heuristic with Euclidean distance between centers\nvector<int> approximateTSPorder(const vector<int>& group) {\n    int n = group.size();\n    vector<bool> visited(n, false);\n    vector<int> order;\n    // start from the first city\n    int current = 0;\n    order.push_back(group[current]);\n    visited[current] = true;\n    for (int i = 1; i < n; ++i) {\n        int next = -1;\n        double best = 1e18;\n        for (int j = 0; j < n; ++j) {\n            if (!visited[j]) {\n                double dx = cx[group[current]] - cx[group[j]];\n                double dy = cy[group[current]] - cy[group[j]];\n                double d = sqrt(dx*dx + dy*dy);\n                if (d < best) {\n                    best = d;\n                    next = j;\n                }\n            }\n        }\n        current = next;\n        order.push_back(group[current]);\n        visited[current] = true;\n    }\n    return order;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Global ordering by Hilbert curve index\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n    });\n\n    // Partition into groups according to G\n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n\n    int total_queries = 0;\n    for (int i = 0; i < M; ++i) {\n        int s = groups[i].size();\n        if (s == 1) continue;\n        if (s <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n            ++total_queries;\n        } else {\n            // Reorder cities within the group using nearest neighbor TSP order\n            vector<int> reordered = approximateTSPorder(groups[i]);\n            int start = 0;\n            while (start < s) {\n                int end = min(start + L, s);\n                int window_size = end - start;\n                if (window_size >= 2) {\n                    vector<int> window(reordered.begin() + start, reordered.begin() + end);\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                    ++total_queries;\n                }\n                start += L - 1;  // overlap by exactly one city\n            }\n        }\n        if (total_queries > Q) break;  // safety, should not happen\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // City list of the group (using the original grouping order for output)\n        for (size_t j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> points(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n\n    pair<int, int> cur = points[0];\n    vector<pair<int, int>> targets(points.begin() + 1, points.end());\n    vector<string> actions;\n\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n    const string dir_name[4] = {\"D\", \"U\", \"R\", \"L\"};\n\n    for (size_t k = 0; k < targets.size(); ++k) {\n        auto [ti, tj] = targets[k];\n\n        // Build blocked cells: future targets (index > k)\n        vector<vector<bool>> blocked_future(N, vector<bool>(N, false));\n        for (size_t i = k + 1; i < targets.size(); ++i) {\n            int x = targets[i].first, y = targets[i].second;\n            blocked_future[x][y] = true;\n        }\n\n        // Case 1: already aligned and target on boundary -> direct slide\n        if (cur.first == ti) {\n            if (tj == 0) {\n                actions.push_back(\"S L\");\n                cur.second = tj;\n                continue;\n            } else if (tj == N - 1) {\n                actions.push_back(\"S R\");\n                cur.second = tj;\n                continue;\n            }\n        } else if (cur.second == tj) {\n            if (ti == 0) {\n                actions.push_back(\"S U\");\n                cur.first = ti;\n                continue;\n            } else if (ti == N - 1) {\n                actions.push_back(\"S D\");\n                cur.first = ti;\n                continue;\n            }\n        }\n\n        // Case 2: target on a boundary, try align-then-slide if straight path clear\n        bool used_align_slide = false;\n        if (ti == 0 || ti == N-1 || tj == 0 || tj == N-1) {\n            // Target on top/bottom boundary: move horizontally to column tj, then slide vertically\n            if (ti == 0 || ti == N-1) {\n                // Check horizontal segment from (cur.first, cur.second) to (cur.first, tj)\n                bool clear = true;\n                if (cur.second != tj) {\n                    int step = (cur.second < tj) ? 1 : -1;\n                    for (int j = cur.second; j != tj; j += step) {\n                        if (blocked_future[cur.first][j]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                // Also ensure the destination cell (cur.first, tj) is not a future target\n                if (clear && blocked_future[cur.first][tj]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform horizontal moves\n                    if (cur.second < tj) {\n                        for (int j = cur.second; j < tj; ++j) actions.push_back(\"M R\");\n                    } else if (cur.second > tj) {\n                        for (int j = cur.second; j > tj; --j) actions.push_back(\"M L\");\n                    }\n                    cur.second = tj;\n                    // Perform slide\n                    if (ti == 0) {\n                        actions.push_back(\"S U\");\n                        cur.first = ti;\n                    } else {\n                        actions.push_back(\"S D\");\n                        cur.first = ti;\n                    }\n                    used_align_slide = true;\n                }\n            }\n            // If not used, try the other orientation if target on left/right boundary\n            if (!used_align_slide && (tj == 0 || tj == N-1)) {\n                // Move vertically to row ti, then slide horizontally\n                bool clear = true;\n                if (cur.first != ti) {\n                    int step = (cur.first < ti) ? 1 : -1;\n                    for (int i = cur.first; i != ti; i += step) {\n                        if (blocked_future[i][cur.second]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                if (clear && blocked_future[ti][cur.second]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform vertical moves\n                    if (cur.first < ti) {\n                        for (int i = cur.first; i < ti; ++i) actions.push_back(\"M D\");\n                    } else if (cur.first > ti) {\n                        for (int i = cur.first; i > ti; --i) actions.push_back(\"M U\");\n                    }\n                    cur.first = ti;\n                    // Perform slide\n                    if (tj == 0) {\n                        actions.push_back(\"S L\");\n                        cur.second = tj;\n                    } else {\n                        actions.push_back(\"S R\");\n                        cur.second = tj;\n                    }\n                    used_align_slide = true;\n                }\n            }\n        }\n        if (used_align_slide) {\n            continue;\n        }\n\n        // Case 3: fallback to BFS with moves and slides\n        vector<vector<int>> prev_x(N, vector<int>(N, -1));\n        vector<vector<int>> prev_y(N, vector<int>(N, -1));\n        vector<vector<int>> prev_dir(N, vector<int>(N, -1)); // 0-3: move, 4-7: slide\n        queue<pair<int, int>> q;\n        q.push(cur);\n        prev_x[cur.first][cur.second] = cur.first;\n        prev_y[cur.first][cur.second] = cur.second;\n\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            if (x == ti && y == tj) break;\n\n            // Move actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                if (blocked_future[nx][ny]) continue;\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = d; // 0-3 for moves\n                q.push({nx, ny});\n            }\n\n            // Slide actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x, ny = y;\n                // Simulate slide\n                while (true) {\n                    int next_x = nx + dx[d];\n                    int next_y = ny + dy[d];\n                    if (next_x < 0 || next_x >= N || next_y < 0 || next_y >= N) break;\n                    // If next cell is a future target, we can still move into it (since it's not a block),\n                    // but we must not end on it. We'll continue moving.\n                    // However, we cannot move into a cell that is a block. Since we have no blocks,\n                    // we just move.\n                    nx = next_x;\n                    ny = next_y;\n                }\n                // Now (nx, ny) is the final cell after sliding.\n                if (nx == x && ny == y) continue; // no movement\n                if (blocked_future[nx][ny]) continue; // cannot end on future target\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = 4 + d; // 4-7 for slides\n                q.push({nx, ny});\n            }\n        }\n\n        // Reconstruct path\n        vector<string> path_actions;\n        int x = ti, y = tj;\n        while (x != cur.first || y != cur.second) {\n            int dir = prev_dir[x][y];\n            int px = prev_x[x][y];\n            int py = prev_y[x][y];\n            if (dir < 4) {\n                // move action\n                path_actions.push_back(\"M \" + dir_name[dir]);\n            } else {\n                // slide action\n                path_actions.push_back(\"S \" + dir_name[dir - 4]);\n            }\n            x = px;\n            y = py;\n        }\n        reverse(path_actions.begin(), path_actions.end());\n\n        for (const string& a : path_actions) {\n            actions.push_back(a);\n        }\n\n        cur = {ti, tj};\n    }\n\n    // Output actions\n    for (const string& a : actions) {\n        cout << a << \"\\n\";\n    }\n\n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <climits>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r, idx;\n};\n\nvector<Company> companies;\nvector<int> a, b, c, d;\nvector<vector<double>> sat_precomp;   // sat_precomp[i][w] for w=1..10000\nvector<vector<int>> cand_base;        // candidate widths for each company\n\n// Precompute satisfaction and candidate widths for all companies\nvoid precompute() {\n    int n = companies.size();\n    sat_precomp.assign(n, vector<double>(10001, 0.0));\n    cand_base.resize(n);\n    for (int i = 0; i < n; ++i) {\n        long long r = companies[i].r;\n        for (int w = 1; w <= 10000; ++w) {\n            int h = (r + w / 2) / w;\n            if (h > 10000) h = 10000;\n            if (h < 1) h = 1;\n            long long s = w * (long long)h;\n            double ratio = min(r, s) / (double)max(r, s);\n            sat_precomp[i][w] = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        }\n        // Generate candidate widths\n        int w_min_possible = max(1, (int)ceil(r / 10000.0));\n        int w_max_possible = min(10000, (int)r);\n        vector<int> cand;\n        // Add a range of candidates\n        int step = max(1, (w_max_possible - w_min_possible) / 20);\n        for (int w = w_min_possible; w <= w_max_possible; w += step) {\n            cand.push_back(w);\n        }\n        cand.push_back(1);\n        cand.push_back(10000);\n        // Add widths for extreme heights\n        cand.push_back(w_min_possible); // gives h=10000\n        cand.push_back(w_max_possible); // gives h=1\n        int w_opt = max(1, (int)round(sqrt(r)));\n        cand.push_back(w_opt);\n        for (int d = 1; d <= 5; ++d) {\n            if (w_opt - d >= 1) cand.push_back(w_opt - d);\n            if (w_opt + d <= 10000) cand.push_back(w_opt + d);\n        }\n        // Remove duplicates and sort\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n        cand_base[i] = cand;\n    }\n}\n\n// assign a rectangle to a single company within given rect\nvoid assign_single(int i, int rect_l, int rect_b, int rect_r, int rect_t) {\n    long long r = companies[i].r;\n    int x = companies[i].x;\n    int y = companies[i].y;\n    int w_max = rect_r - rect_l;\n    int h_max = rect_t - rect_b;\n    double best_sat = -1.0;\n    int best_a = 0, best_b = 0, best_c = 0, best_d = 0;\n\n    // Try all widths\n    for (int w = 1; w <= w_max; ++w) {\n        int h = (r + w / 2) / w;\n        if (h > h_max) h = h_max;\n        if (h < 1) h = 1;\n        long long s = w * (long long)h;\n        double ratio = min(r, s) / (double)max(r, s);\n        double sat = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n\n        if (sat == 1.0) {\n            best_sat = sat;\n            best_a = max(rect_l, x - w + 1);\n            best_b = max(rect_b, y - h + 1);\n            best_c = best_a + w;\n            best_d = best_b + h;\n            break;\n        }\n\n        int a_min = max(rect_l, x - w + 1);\n        int a_max = min(x, rect_r - w);\n        if (a_min > a_max) continue;\n        int b_min = max(rect_b, y - h + 1);\n        int b_max = min(y, rect_t - h);\n        if (b_min > b_max) continue;\n\n        int a = a_min;\n        int b = b_min;\n        if (sat > best_sat) {\n            best_sat = sat;\n            best_a = a;\n            best_b = b;\n            best_c = a + w;\n            best_d = b + h;\n        }\n    }\n\n    // Try all heights (in case width enumeration missed a better combination)\n    for (int h = 1; h <= h_max; ++h) {\n        int w = (r + h / 2) / h;\n        if (w > w_max) w = w_max;\n        if (w < 1) w = 1;\n        long long s = w * (long long)h;\n        double ratio = min(r, s) / (double)max(r, s);\n        double sat = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n\n        if (sat == 1.0) {\n            best_sat = sat;\n            best_a = max(rect_l, x - w + 1);\n            best_b = max(rect_b, y - h + 1);\n            best_c = best_a + w;\n            best_d = best_b + h;\n            break;\n        }\n\n        int a_min = max(rect_l, x - w + 1);\n        int a_max = min(x, rect_r - w);\n        if (a_min > a_max) continue;\n        int b_min = max(rect_b, y - h + 1);\n        int b_max = min(y, rect_t - h);\n        if (b_min > b_max) continue;\n\n        int a = a_min;\n        int b = b_min;\n        if (sat > best_sat) {\n            best_sat = sat;\n            best_a = a;\n            best_b = b;\n            best_c = a + w;\n            best_d = b + h;\n        }\n    }\n\n    a[companies[i].idx] = best_a;\n    b[companies[i].idx] = best_b;\n    c[companies[i].idx] = best_c;\n    d[companies[i].idx] = best_d;\n}\n\n// fallback: column packing within given rect\nvoid fallback_column_packing(int rect_l, int rect_b, int rect_r, int rect_t,\n                             vector<int> indices) {\n    if (indices.empty()) return;\n\n    // sort indices by x coordinate\n    sort(indices.begin(), indices.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    int n = indices.size();\n    int W = rect_r - rect_l;\n    int H = rect_t - rect_b;  // available height\n\n    // If group is small (<=30), use DP for better width allocation\n    if (n <= 30) {\n        // DP tables\n        vector<vector<double>> dp(n+1, vector<double>(W+1, -1e18));\n        vector<vector<int>> prev_offset(n+1, vector<int>(W+1, -1));\n        vector<vector<int>> prev_width(n+1, vector<int>(W+1, -1));\n        dp[0][0] = 0.0;\n\n        for (int i = 0; i < n; ++i) {\n            int comp_idx = indices[i];\n            for (int off = 0; off <= W; ++off) {\n                if (dp[i][off] < -1e17) continue;\n                int x = rect_l + off;\n                int w_min = max(1, companies[comp_idx].x - x + 1);\n                int w_max = W - off;\n                // Generate candidates for this state\n                vector<int> ws;\n                if (w_max - w_min + 1 <= 100) {\n                    // Small range: consider all widths\n                    for (int w = w_min; w <= w_max; ++w) ws.push_back(w);\n                } else {\n                    ws = cand_base[comp_idx];\n                    ws.push_back(w_min);\n                    ws.push_back(w_max);\n                    int w_opt = max(1, (int)round(sqrt(companies[comp_idx].r)));\n                    ws.push_back(w_opt);\n                    ws.push_back(w_opt - 1);\n                    ws.push_back(w_opt + 1);\n                    sort(ws.begin(), ws.end());\n                    ws.erase(unique(ws.begin(), ws.end()), ws.end());\n                }\n                for (int w : ws) {\n                    if (w < w_min || w > w_max) continue;\n                    int new_off = off + w;\n                    double sat = sat_precomp[comp_idx][w];\n                    if (dp[i+1][new_off] < dp[i][off] + sat) {\n                        dp[i+1][new_off] = dp[i][off] + sat;\n                        prev_offset[i+1][new_off] = off;\n                        prev_width[i+1][new_off] = w;\n                    }\n                }\n            }\n        }\n\n        // Find best final offset\n        int best_off = -1;\n        double best_val = -1e18;\n        for (int off = 0; off <= W; ++off) {\n            if (dp[n][off] > best_val) {\n                best_val = dp[n][off];\n                best_off = off;\n            }\n        }\n\n        if (best_off != -1) {\n            // Reconstruct widths\n            vector<int> widths(n);\n            int cur_off = best_off;\n            for (int i = n; i >= 1; --i) {\n                widths[i-1] = prev_width[i][cur_off];\n                cur_off = prev_offset[i][cur_off];\n            }\n            // Assign rectangles\n            long long cur_start = rect_l;\n            for (int k = 0; k < n; ++k) {\n                int i = indices[k];\n                int wi = widths[k];\n                long long ri = companies[i].r;\n                int h = (ri + wi / 2) / wi;\n                if (h > 10000) h = 10000;\n                if (h > H) h = H;  // clamp to available height\n                if (h < 1) h = 1;\n                int ai = cur_start;\n                int ci = ai + wi;\n                int bi = max(rect_b, companies[i].y - h + 1);\n                int di = bi + h;\n                if (bi < rect_b) bi = rect_b;\n                if (di > rect_t) {\n                    di = rect_t;\n                    bi = di - h;\n                    if (bi < rect_b) bi = rect_b;  // ensure non-negative\n                }\n                a[companies[i].idx] = ai;\n                b[companies[i].idx] = bi;\n                c[companies[i].idx] = ci;\n                d[companies[i].idx] = di;\n                cur_start += wi;\n            }\n            return;\n        }\n        // If DP failed, fall through to greedy\n    }\n\n    // Greedy width assignment with reduction\n    vector<int> w(n);\n    long long cur_start = rect_l;\n\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        long long w_min_cov = max(1LL, (long long)companies[i].x - cur_start + 1);\n        long long w_min_area = (companies[i].r + 9999) / 10000;\n        w[k] = max(w_min_cov, w_min_area);\n        cur_start += w[k];\n    }\n\n    long long total_width = cur_start - rect_l;\n    long long avail_width = rect_r - rect_l;\n    long long excess = total_width - avail_width;\n\n    while (excess > 0) {\n        vector<long long> start_pos(n);\n        cur_start = rect_l;\n        for (int k = 0; k < n; ++k) {\n            start_pos[k] = cur_start;\n            cur_start += w[k];\n        }\n        int best_k = -1;\n        double best_loss = 1e18;\n        for (int k = 0; k < n; ++k) {\n            int i = indices[k];\n            long long w_min_cov = max(1LL, (long long)companies[i].x - start_pos[k] + 1);\n            if (w[k] <= w_min_cov) continue;\n            double p_curr = sat_precomp[i][w[k]];\n            double p_red = sat_precomp[i][w[k] - 1];\n            double loss = p_curr - p_red;\n            if (loss < best_loss) {\n                best_loss = loss;\n                best_k = k;\n            }\n        }\n        if (best_k == -1) break;\n        w[best_k]--;\n        excess--;\n    }\n\n    // Assign rectangles\n    cur_start = rect_l;\n    for (int k = 0; k < n; ++k) {\n        int i = indices[k];\n        int wi = w[k];\n        long long ri = companies[i].r;\n        int h = (ri + wi / 2) / wi;\n        if (h > 10000) h = 10000;\n        if (h > H) h = H;\n        if (h < 1) h = 1;\n        int ai = cur_start;\n        int ci = ai + wi;\n        int bi = max(rect_b, companies[i].y - h + 1);\n        int di = bi + h;\n        if (bi < rect_b) bi = rect_b;\n        if (di > rect_t) {\n            di = rect_t;\n            bi = di - h;\n            if (bi < rect_b) bi = rect_b;\n        }\n        a[companies[i].idx] = ai;\n        b[companies[i].idx] = bi;\n        c[companies[i].idx] = ci;\n        d[companies[i].idx] = di;\n        cur_start += wi;\n    }\n}\n\n// recursive splitting\nvoid solve(int rect_l, int rect_b, int rect_r, int rect_t, vector<int> indices) {\n    if (indices.empty()) return;\n    if (indices.size() == 1) {\n        assign_single(indices[0], rect_l, rect_b, rect_r, rect_t);\n        return;\n    }\n\n    // try vertical split\n    bool vertical_ok = false;\n    int best_s = -1;\n    double best_error = 1e18;\n    vector<int> best_left, best_right;\n\n    vector<int> sorted_idx = indices;\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].x < companies[j].x; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> left(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> right(sorted_idx.begin() + k, sorted_idx.end());\n        int max_x_left = companies[left.back()].x;\n        int min_x_right = companies[right.front()].x;\n        if (max_x_left + 1 > min_x_right) continue;\n\n        long long sum_left = 0, sum_right = 0;\n        for (int i : left) sum_left += companies[i].r;\n        for (int i : right) sum_right += companies[i].r;\n        long long height = rect_t - rect_b;\n        double s_ideal = (double)sum_left / height;\n        int s_low = max_x_left + 1;\n        int s_high = min_x_right;\n        int s = max(s_low, min(s_high, (int)round(s_ideal)));\n        \n        long long left_area = (s - rect_l) * height;\n        long long right_area = (rect_r - s) * height;\n        double error = (sum_left - left_area) * (sum_left - left_area) + (sum_right - right_area) * (sum_right - right_area);\n        if (error < best_error) {\n            best_error = error;\n            best_s = s;\n            best_left = left;\n            best_right = right;\n            vertical_ok = true;\n        }\n    }\n\n    if (vertical_ok) {\n        solve(rect_l, rect_b, best_s, rect_t, best_left);\n        solve(best_s, rect_b, rect_r, rect_t, best_right);\n        return;\n    }\n\n    // try horizontal split\n    bool horizontal_ok = false;\n    int best_t = -1;\n    double best_error_h = 1e18;\n    vector<int> best_bottom, best_top;\n\n    sort(sorted_idx.begin(), sorted_idx.end(),\n         [](int i, int j) { return companies[i].y < companies[j].y; });\n\n    for (size_t k = 1; k < sorted_idx.size(); ++k) {\n        vector<int> bottom(sorted_idx.begin(), sorted_idx.begin() + k);\n        vector<int> top(sorted_idx.begin() + k, sorted_idx.end());\n        int max_y_bottom = companies[bottom.back()].y;\n        int min_y_top = companies[top.front()].y;\n        if (max_y_bottom + 1 > min_y_top) continue;\n\n        long long sum_bottom = 0, sum_top = 0;\n        for (int i : bottom) sum_bottom += companies[i].r;\n        for (int i : top) sum_top += companies[i].r;\n        long long width = rect_r - rect_l;\n        double t_ideal = (double)sum_bottom / width;\n        int t_low = max_y_bottom + 1;\n        int t_high = min_y_top;\n        int t = max(t_low, min(t_high, (int)round(t_ideal)));\n        \n        long long bottom_area = width * (t - rect_b);\n        long long top_area = width * (rect_t - t);\n        double error = (sum_bottom - bottom_area) * (sum_bottom - bottom_area) + (sum_top - top_area) * (sum_top - top_area);\n        if (error < best_error_h) {\n            best_error_h = error;\n            best_t = t;\n            best_bottom = bottom;\n            best_top = top;\n            horizontal_ok = true;\n        }\n    }\n\n    if (horizontal_ok) {\n        solve(rect_l, rect_b, rect_r, best_t, best_bottom);\n        solve(rect_l, best_t, rect_r, rect_t, best_top);\n        return;\n    }\n\n    // no feasible split found, fallback to column packing for the whole region\n    fallback_column_packing(rect_l, rect_b, rect_r, rect_t, indices);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].idx = i;\n    }\n\n    precompute();\n\n    a.resize(n);\n    b.resize(n);\n    c.resize(n);\n    d.resize(n);\n\n    vector<int> all_idx(n);\n    iota(all_idx.begin(), all_idx.end(), 0);\n\n    solve(0, 0, 10000, 10000, all_idx);\n\n    for (int i = 0; i < n; ++i) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <bitset>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500; // Maximum possible tiles (50x50)\n\nstruct State {\n    int row, col;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n    \n    State(int r, int c, int s, const string& p, const bitset<MAX_TILES>& v) \n        : row(r), col(c), score(s), path(p), visited(v) {}\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    vector<vector<int>> value(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> value[i][j];\n        }\n    }\n    \n    // Find number of distinct tiles\n    int num_tiles = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n        }\n    }\n    \n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n    \n    // Beam search parameters\n    const int BEAM_WIDTH = 2000;\n    \n    // Priority queue to keep top BEAM_WIDTH states (min-heap based on score)\n    auto cmp = [](const State& a, const State& b) {\n        return a.score > b.score; // For min-heap, we want smallest score at top\n    };\n    priority_queue<State, vector<State>, decltype(cmp)> beam(cmp);\n    \n    // Start with initial state\n    bitset<MAX_TILES> start_visited;\n    start_visited.set(tile[si][sj]);\n    beam.push(State(si, sj, value[si][sj], \"\", start_visited));\n    \n    string best_path = \"\";\n    int best_score = value[si][sj];\n    \n    // Iterate until beam is empty\n    while (!beam.empty()) {\n        // Collect all next states\n        vector<State> next_states;\n        \n        while (!beam.empty()) {\n            State current = beam.top();\n            beam.pop();\n            \n            // Try all moves from current state\n            for (int d = 0; d < 4; ++d) {\n                int nr = current.row + dr[d];\n                int nc = current.col + dc[d];\n                \n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                \n                int tid = tile[nr][nc];\n                if (current.visited[tid]) continue;\n                \n                // Create new state\n                bitset<MAX_TILES> new_visited = current.visited;\n                new_visited.set(tid);\n                int new_score = current.score + value[nr][nc];\n                string new_path = current.path + dir_char[d];\n                \n                State new_state(nr, nc, new_score, new_path, new_visited);\n                \n                // Update best if this is a terminal state (no more moves)\n                bool can_extend = false;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int nnr = nr + dr[d2];\n                    int nnc = nc + dc[d2];\n                    if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N) continue;\n                    int ntid = tile[nnr][nnc];\n                    if (!new_visited[ntid]) {\n                        can_extend = true;\n                        break;\n                    }\n                }\n                \n                if (!can_extend) {\n                    // Terminal state\n                    if (new_score > best_score) {\n                        best_score = new_score;\n                        best_path = new_path;\n                    }\n                } else {\n                    next_states.push_back(new_state);\n                }\n            }\n        }\n        \n        if (next_states.empty()) break;\n        \n        // Sort by score and keep top BEAM_WIDTH\n        sort(next_states.begin(), next_states.end(), \n            [](const State& a, const State& b) {\n                return a.score > b.score;\n            });\n        \n        int keep = min((int)next_states.size(), BEAM_WIDTH);\n        for (int i = 0; i < keep; ++i) {\n            beam.push(next_states[i]);\n        }\n    }\n    \n    // Output the best path found\n    cout << best_path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    const int N = 30;\n    // Base estimates for rows and columns\n    vector<double> row_base(N, 5000.0);\n    vector<double> col_base(N, 5000.0);\n    \n    // Helper to compute edge estimate from base values\n    auto get_edge_weight = [&](bool is_horizontal, int i, int j) {\n        return is_horizontal ? row_base[i] : col_base[j];\n    };\n\n    double lr = 0.2;  // initial learning rate\n    int total_updates = 0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        int start = si * N + sj;\n        int target = ti * N + tj;\n\n        const double INF = 1e18;\n        vector<double> dist(N*N, INF);\n        vector<int> prev(N*N, -1);\n        vector<char> prev_move(N*N);\n        dist[start] = 0.0;\n        priority_queue<pair<double, int>,\n                       vector<pair<double, int>>,\n                       greater<pair<double, int>>> pq;\n        pq.emplace(0.0, start);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            int ui = u / N, uj = u % N;\n\n            // Up\n            if (ui > 0) {\n                int v = (ui-1)*N + uj;\n                double w = get_edge_weight(false, ui-1, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'U';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Down\n            if (ui < N-1) {\n                int v = (ui+1)*N + uj;\n                double w = get_edge_weight(false, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'D';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Left\n            if (uj > 0) {\n                int v = ui*N + (uj-1);\n                double w = get_edge_weight(true, ui, uj-1);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'L';\n                    pq.emplace(dist[v], v);\n                }\n            }\n            // Right\n            if (uj < N-1) {\n                int v = ui*N + (uj+1);\n                double w = get_edge_weight(true, ui, uj);\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    prev[v] = u;\n                    prev_move[v] = 'R';\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        // Reconstruct path and collect row/column usage\n        vector<char> moves;\n        vector<pair<bool, int>> path_edges; // (is_horizontal, index)\n        map<int, int> row_count, col_count;\n\n        int cur = target;\n        while (cur != start) {\n            int p = prev[cur];\n            char dir = prev_move[cur];\n            moves.push_back(dir);\n\n            int pi = p / N, pj = p % N;\n            int ci = cur / N, cj = cur % N;\n\n            if (pi == ci) { // horizontal move\n                int j = min(pj, cj);\n                path_edges.push_back({true, pi});\n                row_count[pi]++;\n            } else { // vertical move\n                int i = min(pi, ci);\n                path_edges.push_back({false, pj});\n                col_count[pj]++;\n            }\n            cur = p;\n        }\n        reverse(moves.begin(), moves.end());\n\n        // Output\n        for (char c : moves) cout << c;\n        cout << endl;\n\n        // Read result\n        int res;\n        cin >> res;\n\n        // Compute predicted length using current base estimates\n        double L_est = 0.0;\n        for (auto& [is_h, idx] : path_edges) {\n            L_est += is_h ? row_base[idx] : col_base[idx];\n        }\n        int len = path_edges.size();\n        double measured = res;\n\n        // Multiplicative update factor\n        double factor = pow(measured / L_est, lr / len);\n\n        // Update row and column base values\n        for (auto& [is_h, idx] : path_edges) {\n            if (is_h) {\n                row_base[idx] *= factor;\n                row_base[idx] = max(1000.0, min(9000.0, row_base[idx]));\n            } else {\n                col_base[idx] *= factor;\n                col_base[idx] = max(1000.0, min(9000.0, col_base[idx]));\n            }\n        }\n\n        total_updates += len;\n        // Decay learning rate more slowly\n        lr = 0.2 / (1 + total_updates * 0.0001);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_K = 12;\nconst uint64_t BASE = 131;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int M;\n    cin >> M;\n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n    \n    // Hash each string\n    vector<uint64_t> str_hash(M);\n    unordered_map<uint64_t, int> hash_to_str;\n    for (int i = 0; i < M; ++i) {\n        uint64_t h = 0;\n        for (char ch : strs[i]) {\n            h = h * BASE + (ch - 'A' + 1);\n        }\n        str_hash[i] = h;\n        hash_to_str[h] = i;\n    }\n    \n    // Initialize random grid\n    vector<vector<char>> grid(N, vector<char>(N));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_letter(0, 7);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + dist_letter(rng);\n        }\n    }\n    \n    // Precompute row and column updates for each cell\n    vector<vector<pair<int, int>>> row_updates(N * N);\n    vector<vector<pair<int, int>>> col_updates(N * N);\n    \n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cell = r * N + c;\n            // Row updates: all substrings containing (r,c)\n            for (int k = 2; k <= MAX_K; ++k) {\n                for (int s = 0; s < N; ++s) {\n                    if ((c - s + N) % N < k) {\n                        row_updates[cell].push_back({s, k});\n                    }\n                }\n            }\n            // Column updates: all substrings containing (r,c)\n            for (int k = 2; k <= MAX_K; ++k) {\n                for (int s = 0; s < N; ++s) {\n                    if ((r - s + N) % N < k) {\n                        col_updates[cell].push_back({s, k});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Initialize row and column hash sets\n    vector<unordered_set<uint64_t>> row_hashes(N);\n    vector<unordered_set<uint64_t>> col_hashes(N);\n    \n    auto compute_hash_row = [&](int r, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int col = (start + i) % N;\n            h = h * BASE + (grid[r][col] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    auto compute_hash_col = [&](int c, int start, int k) -> uint64_t {\n        uint64_t h = 0;\n        for (int i = 0; i < k; ++i) {\n            int row = (start + i) % N;\n            h = h * BASE + (grid[row][c] - 'A' + 1);\n        }\n        return h;\n    };\n    \n    for (int r = 0; r < N; ++r) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= MAX_K; ++k) {\n                row_hashes[r].insert(compute_hash_row(r, s, k));\n            }\n        }\n    }\n    for (int c = 0; c < N; ++c) {\n        for (int s = 0; s < N; ++s) {\n            for (int k = 2; k <= MAX_K; ++k) {\n                col_hashes[c].insert(compute_hash_col(c, s, k));\n            }\n        }\n    }\n    \n    // Count satisfied strings\n    vector<int> str_count(M, 0);\n    int total_sat = 0;\n    for (int i = 0; i < M; ++i) {\n        bool found = false;\n        for (int r = 0; r < N && !found; ++r) {\n            if (row_hashes[r].count(str_hash[i])) {\n                found = true;\n                str_count[i]++;\n            }\n        }\n        for (int c = 0; c < N && !found; ++c) {\n            if (col_hashes[c].count(str_hash[i])) {\n                found = true;\n                str_count[i]++;\n            }\n        }\n        if (str_count[i] > 0) total_sat++;\n    }\n    \n    // Simulated annealing\n    const int iterations = 50000;\n    double temp = 10.0;\n    const double cooling = 0.9999;\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n    uniform_int_distribution<int> dist_cell(0, N - 1);\n    uniform_int_distribution<int> dist_newchar(0, 7);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int r = dist_cell(rng);\n        int c = dist_cell(rng);\n        char old_char = grid[r][c];\n        char new_char = 'A' + dist_newchar(rng);\n        \n        if (new_char == old_char) continue;\n        \n        int cell = r * N + c;\n        int old_total = total_sat;\n        \n        // Remove old hashes from row r\n        vector<uint64_t> old_row_hashes;\n        for (auto &[s, k] : row_updates[cell]) {\n            uint64_t old_hash = compute_hash_row(r, s, k);\n            old_row_hashes.push_back(old_hash);\n            row_hashes[r].erase(old_hash);\n            \n            if (hash_to_str.count(old_hash)) {\n                int i = hash_to_str[old_hash];\n                str_count[i]--;\n                if (str_count[i] == 0) total_sat--;\n            }\n        }\n        \n        // Remove old hashes from column c\n        vector<uint64_t> old_col_hashes;\n        for (auto &[s, k] : col_updates[cell]) {\n            uint64_t old_hash = compute_hash_col(c, s, k);\n            old_col_hashes.push_back(old_hash);\n            col_hashes[c].erase(old_hash);\n            \n            if (hash_to_str.count(old_hash)) {\n                int i = hash_to_str[old_hash];\n                str_count[i]--;\n                if (str_count[i] == 0) total_sat--;\n            }\n        }\n        \n        // Apply change\n        grid[r][c] = new_char;\n        \n        // Add new hashes to row r\n        vector<uint64_t> new_row_hashes;\n        for (auto &[s, k] : row_updates[cell]) {\n            uint64_t new_hash = compute_hash_row(r, s, k);\n            new_row_hashes.push_back(new_hash);\n            row_hashes[r].insert(new_hash);\n            \n            if (hash_to_str.count(new_hash)) {\n                int i = hash_to_str[new_hash];\n                str_count[i]++;\n                if (str_count[i] == 1) total_sat++;\n            }\n        }\n        \n        // Add new hashes to column c\n        vector<uint64_t> new_col_hashes;\n        for (auto &[s, k] : col_updates[cell]) {\n            uint64_t new_hash = compute_hash_col(c, s, k);\n            new_col_hashes.push_back(new_hash);\n            col_hashes[c].insert(new_hash);\n            \n            if (hash_to_str.count(new_hash)) {\n                int i = hash_to_str[new_hash];\n                str_count[i]++;\n                if (str_count[i] == 1) total_sat++;\n            }\n        }\n        \n        int new_total = total_sat;\n        double delta = new_total - old_total;\n        \n        // Accept or reject\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else if (temp > 1e-6 && exp(delta / temp) > dist_real(rng)) {\n            accept = true;\n        }\n        \n        if (!accept) {\n            // Revert changes\n            grid[r][c] = old_char;\n            \n            // Remove new hashes from row r\n            for (uint64_t h : new_row_hashes) {\n                row_hashes[r].erase(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]--;\n                    if (str_count[i] == 0) total_sat--;\n                }\n            }\n            \n            // Remove new hashes from column c\n            for (uint64_t h : new_col_hashes) {\n                col_hashes[c].erase(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]--;\n                    if (str_count[i] == 0) total_sat--;\n                }\n            }\n            \n            // Add back old hashes to row r\n            for (uint64_t h : old_row_hashes) {\n                row_hashes[r].insert(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]++;\n                    if (str_count[i] == 1) total_sat++;\n                }\n            }\n            \n            // Add back old hashes to column c\n            for (uint64_t h : old_col_hashes) {\n                col_hashes[c].insert(h);\n                if (hash_to_str.count(h)) {\n                    int i = hash_to_str[h];\n                    str_count[i]++;\n                    if (str_count[i] == 1) total_sat++;\n                }\n            }\n            \n            total_sat = old_total;\n        }\n        \n        temp *= cooling;\n        if (total_sat == M) break;\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n};\n\n// Hopcroft\u2013Karp for bipartite matching\nint hopcroft_karp(const vector<vector<int>>& adj, int L, int R,\n                  vector<int>& matchL, vector<int>& matchR) {\n    vector<int> dist(L, -1);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            dist[u] = 0;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (matchR[v] != -1 && dist[matchR[v]] == -1) {\n                dist[matchR[v]] = dist[u] + 1;\n                q.push(matchR[v]);\n            }\n        }\n    }\n    function<bool(int)> dfs = [&](int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 ||\n                (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n    int matching = 0;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1 && dfs(u)) ++matching;\n    }\n    return matching;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; ++i) cin >> grid_str[i];\n\n    // Convert grid: -1 for obstacle, otherwise cost (5-9)\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Point> roads;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid_str[i][j];\n            if (c != '#') {\n                grid[i][j] = c - '0';\n                roads.push_back({i, j});\n            }\n        }\n    }\n\n    // ---------- row segments ----------\n    vector<vector<int>> row_seg(N, vector<int>(N, -1));\n    int L = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] != -1) {\n                int start = j;\n                while (j < N && grid[i][j] != -1) ++j;\n                int end = j - 1;\n                for (int k = start; k <= end; ++k) row_seg[i][k] = L;\n                ++L;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ---------- column segments ----------\n    vector<vector<int>> col_seg(N, vector<int>(N, -1));\n    int R = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] != -1) {\n                int start = i;\n                while (i < N && grid[i][j] != -1) ++i;\n                int end = i - 1;\n                for (int k = start; k <= end; ++k) col_seg[k][j] = R;\n                ++R;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ---------- bipartite graph (row segments vs column segments) ----------\n    vector<vector<int>> adj(L);\n    vector<vector<pair<int, Point>>> edge_coord(L); // for each row segment: (col_segment, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        adj[u].push_back(v);\n        edge_coord[u].push_back({v, {p.i, p.j}});\n    }\n\n    // ---------- minimum vertex cover (via maximum matching) ----------\n    vector<int> matchL(L, -1), matchR(R, -1);\n    hopcroft_karp(adj, L, R, matchL, matchR);\n\n    vector<bool> visL(L, false), visR(R, false);\n    queue<int> q;\n    for (int u = 0; u < L; ++u) {\n        if (matchL[u] == -1) {\n            visL[u] = true;\n            q.push(u);\n        }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (!visR[v]) {\n                visR[v] = true;\n                if (matchR[v] != -1 && !visL[matchR[v]]) {\n                    visL[matchR[v]] = true;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n    }\n    vector<bool> selected_row(L, false), selected_col(R, false);\n    for (int u = 0; u < L; ++u) selected_row[u] = !visL[u];\n    for (int v = 0; v < R; ++v) selected_col[v] = visR[v];\n\n    // ---------- selected segments ----------\n    vector<int> sel_row_list, sel_col_list;\n    for (int u = 0; u < L; ++u) if (selected_row[u]) sel_row_list.push_back(u);\n    for (int v = 0; v < R; ++v) if (selected_col[v]) sel_col_list.push_back(v);\n    int L2 = sel_row_list.size(), R2 = sel_col_list.size();\n    map<int, int> row_idx, col_idx;\n    for (int i = 0; i < L2; ++i) row_idx[sel_row_list[i]] = i;\n    for (int i = 0; i < R2; ++i) col_idx[sel_col_list[i]] = i;\n\n    // ---------- induced graph on selected segments ----------\n    vector<vector<int>> adj2(L2);\n    vector<vector<int>> radj2(R2);\n    vector<vector<pair<int, Point>>> edge_coord2(L2); // (col_idx, point)\n    for (auto& p : roads) {\n        int u = row_seg[p.i][p.j];\n        int v = col_seg[p.i][p.j];\n        if (selected_row[u] && selected_col[v]) {\n            int u2 = row_idx[u];\n            int v2 = col_idx[v];\n            adj2[u2].push_back(v2);\n            radj2[v2].push_back(u2);\n            edge_coord2[u2].push_back({v2, {p.i, p.j}});\n        }\n    }\n\n    // ---------- minimum edge cover on induced graph ----------\n    vector<int> matchL2(L2, -1), matchR2(R2, -1);\n    hopcroft_karp(adj2, L2, R2, matchL2, matchR2);\n\n    vector<Point> S; // squares to visit\n    vector<bool> row_covered(L2, false), col_covered(R2, false);\n\n    // 1. take all matching edges\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (matchL2[u2] != -1) {\n            int v2 = matchL2[u2];\n            for (auto& e : edge_coord2[u2]) {\n                if (e.first == v2) {\n                    S.push_back(e.second);\n                    break;\n                }\n            }\n            row_covered[u2] = true;\n            col_covered[v2] = true;\n        }\n    }\n\n    // 2. cover unmatched rows\n    for (int u2 = 0; u2 < L2; ++u2) {\n        if (!row_covered[u2]) {\n            if (!adj2[u2].empty()) {\n                int v2 = adj2[u2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n                col_covered[v2] = true;\n            } else { // isolated row segment\n                int u_orig = sel_row_list[u2];\n                for (auto& p : roads) {\n                    if (row_seg[p.i][p.j] == u_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                row_covered[u2] = true;\n            }\n        }\n    }\n\n    // 3. cover unmatched columns\n    for (int v2 = 0; v2 < R2; ++v2) {\n        if (!col_covered[v2]) {\n            if (!radj2[v2].empty()) {\n                int u2 = radj2[v2][0];\n                for (auto& e : edge_coord2[u2]) {\n                    if (e.first == v2) {\n                        S.push_back(e.second);\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            } else { // isolated column segment\n                int v_orig = sel_col_list[v2];\n                for (auto& p : roads) {\n                    if (col_seg[p.i][p.j] == v_orig) {\n                        S.push_back({p.i, p.j});\n                        break;\n                    }\n                }\n                col_covered[v2] = true;\n            }\n        }\n    }\n\n    // ---------- nodes for TSP (start + S without duplicates) ----------\n    vector<Point> nodes;\n    nodes.push_back({si, sj});\n    set<pair<int, int>> visited_set;\n    for (auto& p : S) {\n        if (p.i == si && p.j == sj) continue;\n        if (visited_set.insert({p.i, p.j}).second) {\n            nodes.push_back(p);\n        }\n    }\n    int n = nodes.size();\n\n    // ---------- Dijkstra from each node, build distance matrix and predecessors ----------\n    const int INF = 1e9;\n    vector<vector<int>> dist_mat(n, vector<int>(n, INF));\n    vector<vector<vector<char>>> pred(n, vector<vector<char>>(N, vector<char>(N, 0)));\n\n    auto dijkstra = [&](int src_idx) {\n        int si = nodes[src_idx].i, sj = nodes[src_idx].j;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        dist[si][sj] = 0;\n        pred[src_idx][si][sj] = 0; // 0 marks the source\n        priority_queue<pair<int, pair<int, int>>,\n                       vector<pair<int, pair<int, int>>>,\n                       greater<>> pq;\n        pq.push({0, {si, sj}});\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dir[4] = {'U', 'D', 'L', 'R'};\n        while (!pq.empty()) {\n            auto top = pq.top(); pq.pop();\n            int d = top.first;\n            int i = top.second.first, j = top.second.second;\n            if (d != dist[i][j]) continue;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid[ni][nj] == -1) continue;\n                int nd = d + grid[ni][nj];\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    pred[src_idx][ni][nj] = dir[k];\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n        for (int t = 0; t < n; ++t) {\n            int ti = nodes[t].i, tj = nodes[t].j;\n            dist_mat[src_idx][t] = dist[ti][tj];\n        }\n    };\n    for (int s = 0; s < n; ++s) dijkstra(s);\n\n    // ---------- TSP solution ----------\n    vector<int> best_tour;\n    int best_cost = INF;\n\n    if (n <= 16) {\n        // Held\u2013Karp DP for small n (directed TSP)\n        int full = (1 << n) - 1;\n        vector<vector<int>> dp(1 << n, vector<int>(n, INF));\n        vector<vector<int>> parent(1 << n, vector<int>(n, -1));\n        dp[1 << 0][0] = 0;\n        for (int mask = 1; mask < (1 << n); ++mask) {\n            for (int i = 0; i < n; ++i) {\n                if (dp[mask][i] == INF) continue;\n                if (!(mask & (1 << i))) continue;\n                for (int j = 0; j < n; ++j) {\n                    if (mask & (1 << j)) continue;\n                    int new_mask = mask | (1 << j);\n                    int new_cost = dp[mask][i] + dist_mat[i][j];\n                    if (new_cost < dp[new_mask][j]) {\n                        dp[new_mask][j] = new_cost;\n                        parent[new_mask][j] = i;\n                    }\n                }\n            }\n        }\n        int best_last = -1;\n        for (int i = 0; i < n; ++i) {\n            if (dp[full][i] + dist_mat[i][0] < best_cost) {\n                best_cost = dp[full][i] + dist_mat[i][0];\n                best_last = i;\n            }\n        }\n        // reconstruct path from 0 to best_last\n        vector<int> rev_path;\n        int mask = full, cur = best_last;\n        while (cur != 0) {\n            rev_path.push_back(cur);\n            int prev = parent[mask][cur];\n            mask ^= (1 << cur);\n            cur = prev;\n        }\n        rev_path.push_back(0);\n        reverse(rev_path.begin(), rev_path.end());\n        best_tour = rev_path;\n        best_tour.push_back(0); // return to start\n    } else {\n        // Helper function to evaluate tour cost\n        auto tour_cost = [&](const vector<int>& t) {\n            int cost = 0;\n            for (size_t i = 0; i < t.size() - 1; ++i) cost += dist_mat[t[i]][t[i+1]];\n            return cost;\n        };\n\n        // Local search function (2-opt + or-opt single + swap)\n        auto local_search = [&](vector<int>& tour) {\n            int m = tour.size();\n            // Precompute prefix sums for forward and reverse distances\n            vector<int> pref_fwd(m, 0), pref_rev(m, 0);\n            for (int i = 0; i < m - 1; ++i) {\n                pref_fwd[i+1] = pref_fwd[i] + dist_mat[tour[i]][tour[i+1]];\n                pref_rev[i+1] = pref_rev[i] + dist_mat[tour[i+1]][tour[i]];\n            }\n            bool improved = true;\n            while (improved) {\n                improved = false;\n                // 2-opt\n                for (size_t i = 0; i < m - 2; ++i) {\n                    for (size_t j = i + 2; j < m - 1; ++j) {\n                        int a = tour[i], b = tour[i+1], c = tour[j], d = tour[j+1];\n                        int cur_cost = dist_mat[a][b] + dist_mat[c][d];\n                        int seg_orig = pref_fwd[j] - pref_fwd[i+1];\n                        int new_cost = dist_mat[a][c] + dist_mat[b][d];\n                        int seg_rev = pref_rev[j] - pref_rev[i+1];\n                        if (cur_cost + seg_orig > new_cost + seg_rev) {\n                            reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                            improved = true;\n                            goto next_iter;\n                        }\n                    }\n                }\n                // or-opt: relocate single nodes\n                for (size_t i = 1; i < tour.size() - 1; ++i) {\n                    int u = tour[i];\n                    int a = tour[i-1], c = tour[i+1];\n                    for (size_t j = 1; j < tour.size() - 1; ++j) {\n                        if (j == i-1 || j == i || j == i+1) continue;\n                        int d = tour[j-1], e = tour[j];\n                        int delta = -dist_mat[a][u] - dist_mat[u][c] + dist_mat[a][c]\n                                    - dist_mat[d][e] + dist_mat[d][u] + dist_mat[u][e];\n                        if (delta < 0) {\n                            tour.erase(tour.begin() + i);\n                            if (j > i) j--;\n                            tour.insert(tour.begin() + j, u);\n                            improved = true;\n                            goto next_iter;\n                        }\n                    }\n                }\n                // swap two non-adjacent nodes (excluding start)\n                for (size_t i = 1; i < tour.size() - 1; ++i) {\n                    for (size_t j = i + 2; j < tour.size() - 1; ++j) {\n                        int u = tour[i], v = tour[j];\n                        int a = tour[i-1], b = tour[i+1];\n                        int c = tour[j-1], d = tour[j+1];\n                        int delta = (dist_mat[a][v] + dist_mat[v][b] + dist_mat[c][u] + dist_mat[u][d])\n                                  - (dist_mat[a][u] + dist_mat[u][b] + dist_mat[c][v] + dist_mat[v][d]);\n                        if (delta < 0) {\n                            swap(tour[i], tour[j]);\n                            improved = true;\n                            goto next_iter;\n                        }\n                    }\n                }\n                next_iter:;\n                // Recompute prefix sums for the next iteration if needed\n                if (improved) {\n                    m = tour.size();\n                    pref_fwd.assign(m, 0);\n                    pref_rev.assign(m, 0);\n                    for (size_t i = 0; i < m - 1; ++i) {\n                        pref_fwd[i+1] = pref_fwd[i] + dist_mat[tour[i]][tour[i+1]];\n                        pref_rev[i+1] = pref_rev[i] + dist_mat[tour[i+1]][tour[i]];\n                    }\n                }\n            }\n        };\n\n        // Nearest neighbor initial tour\n        vector<int> nn_tour;\n        {\n            vector<bool> vis(n, false);\n            nn_tour.push_back(0);\n            vis[0] = true;\n            int cur = 0;\n            for (int iter = 0; iter < n - 1; ++iter) {\n                int nxt = -1, best = INF;\n                for (int v = 0; v < n; ++v) {\n                    if (!vis[v] && dist_mat[cur][v] < best) {\n                        best = dist_mat[cur][v];\n                        nxt = v;\n                    }\n                }\n                nn_tour.push_back(nxt);\n                vis[nxt] = true;\n                cur = nxt;\n            }\n            nn_tour.push_back(0);\n            local_search(nn_tour);\n            best_cost = tour_cost(nn_tour);\n            best_tour = nn_tour;\n        }\n\n        // One random start\n        {\n            vector<int> perm;\n            for (int i = 0; i < n; ++i) perm.push_back(i);\n            random_device rd;\n            mt19937 g(rd());\n            shuffle(perm.begin() + 1, perm.end(), g); // keep start at position 0\n            vector<int> rand_tour = perm;\n            rand_tour.push_back(0);\n            local_search(rand_tour);\n            int cost = tour_cost(rand_tour);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_tour = rand_tour;\n            }\n        }\n    }\n\n    // ---------- build move string ----------\n    string moves;\n    for (size_t idx = 0; idx < best_tour.size() - 1; ++idx) {\n        int src_idx = best_tour[idx];\n        int tgt_idx = best_tour[idx+1];\n        int ci = nodes[tgt_idx].i, cj = nodes[tgt_idx].j;\n        vector<char> path;\n        while (!(ci == nodes[src_idx].i && cj == nodes[src_idx].j)) {\n            char d = pred[src_idx][ci][cj];\n            path.push_back(d);\n            // move to parent\n            if (d == 'U') ci++;\n            else if (d == 'D') ci--;\n            else if (d == 'L') cj++;\n            else if (d == 'R') cj--;\n        }\n        reverse(path.begin(), path.end());\n        for (char c : path) moves.push_back(c);\n    }\n\n    cout << moves << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Function to compute expected completion time given estimated deficit w\ndouble expected_time(double w) {\n    if (w <= 0.0) return 1.0;\n    if (w >= 4.0) return w;\n    // Precomputed expected times for integer w (0 to 4)\n    const double E0 = 1.0;\n    const double E1 = 13.0 / 7.0;\n    const double E2 = 17.0 / 7.0;\n    const double E3 = 22.0 / 7.0;\n    const double E4 = 4.0;\n    int floor_w = (int)w;\n    double frac = w - floor_w;\n    if (floor_w == 0) return E0 + frac * (E1 - E0);\n    if (floor_w == 1) return E1 + frac * (E2 - E1);\n    if (floor_w == 2) return E2 + frac * (E3 - E2);\n    if (floor_w == 3) return E3 + frac * (E4 - E3);\n    return w; // fallback\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            cin >> d[i][k];\n        }\n    }\n\n    vector<vector<int>> children(N);\n    vector<int> prereq_count(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        prereq_count[v]++;\n    }\n\n    // Critical path length L[i]\n    vector<int> L(N, 1);\n    for (int i = N - 1; i >= 0; --i) {\n        for (int v : children[i]) {\n            L[i] = max(L[i], 1 + L[v]);\n        }\n    }\n\n    // Available tasks (prerequisites satisfied)\n    vector<int> avail;\n    for (int i = 0; i < N; ++i) {\n        if (prereq_count[i] == 0) {\n            avail.push_back(i);\n        }\n    }\n\n    // Task status: 0=not started, 1=started, 2=completed\n    vector<int> task_status(N, 0);\n\n    // Team member state\n    vector<int> current_task(M, -1);      // -1 if idle\n    vector<int> start_day(M, -1);\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));  // estimated skill levels\n\n    int cur_day = 1;\n\n    while (true) {\n        // Collect idle members\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // Collect currently available tasks (status 0)\n        vector<int> today_avail;\n        for (int i : avail) {\n            if (task_status[i] == 0) {\n                today_avail.push_back(i);\n            }\n        }\n\n        // Sort by critical path length descending\n        sort(today_avail.begin(), today_avail.end(),\n             [&](int a, int b) { return L[a] > L[b]; });\n\n        vector<pair<int, int>> assignments; // (member, task)\n        vector<bool> member_used(M, false);\n\n        for (int i : today_avail) {\n            if (idle_members.empty()) break;\n\n            int best_j = -1;\n            double best_expected = 1e9;\n            for (int j : idle_members) {\n                if (member_used[j]) continue;\n                double w_est = 0.0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        w_est += d[i][k] - s_est[j][k];\n                    }\n                }\n                double exp_t = expected_time(w_est);\n                if (exp_t < best_expected) {\n                    best_expected = exp_t;\n                    best_j = j;\n                }\n            }\n            if (best_j != -1) {\n                assignments.emplace_back(best_j, i);\n                member_used[best_j] = true;\n                // Update current task and start day immediately\n                current_task[best_j] = i;\n                start_day[best_j] = cur_day;\n                task_status[i] = 1; // mark as started\n            }\n        }\n\n        // Output assignments\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        // Read response line\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        istringstream iss(line);\n        int n;\n        iss >> n;\n        vector<int> completing;\n        for (int i = 0; i < n; ++i) {\n            int f;\n            iss >> f;\n            completing.push_back(f - 1); // to 0-index\n        }\n\n        // Process completions\n        for (int j : completing) {\n            int i = current_task[j];\n            if (i == -1) continue; // should not happen\n\n            int t = cur_day - start_day[j] + 1; // actual duration\n\n            // Update skill estimates for member j\n            double w_est = 0.0;\n            int num_deficient = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[i][k] > s_est[j][k]) {\n                    w_est += d[i][k] - s_est[j][k];\n                    num_deficient++;\n                }\n            }\n            if (num_deficient > 0) {\n                double delta = (w_est - t) / num_deficient;\n                for (int k = 0; k < K; ++k) {\n                    if (d[i][k] > s_est[j][k]) {\n                        s_est[j][k] += delta;\n                        if (s_est[j][k] < 0.0) s_est[j][k] = 0.0;\n                    }\n                }\n            }\n\n            // Mark task as completed\n            task_status[i] = 2;\n            current_task[j] = -1;\n\n            // Update dependent tasks\n            for (int v : children[i]) {\n                prereq_count[v]--;\n                if (prereq_count[v] == 0) {\n                    avail.push_back(v);\n                }\n            }\n        }\n\n        ++cur_day;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <ctime>\n#include <cassert>\n#include <random>\n\nusing namespace std;\n\nstruct Order {\n    int id;          // original index (0-based)\n    int a, b, c, d;  // restaurant and destination\n};\n\nvector<Order> orders; // all 1000 orders\n\n// Manhattan distance\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Point in the route: (order_index, type) type: 0=restaurant, 1=destination\nusing Point = pair<int, int>;\n\n// Compute total distance for a sequence of points\nint total_distance(const vector<Point>& seq, const vector<Order>& sel) {\n    int cur_x = 400, cur_y = 400;\n    int total = 0;\n    for (const auto& p : seq) {\n        int idx = p.first;\n        if (p.second == 0) { // restaurant\n            total += dist(cur_x, cur_y, sel[idx].a, sel[idx].b);\n            cur_x = sel[idx].a;\n            cur_y = sel[idx].b;\n        } else { // destination\n            total += dist(cur_x, cur_y, sel[idx].c, sel[idx].d);\n            cur_x = sel[idx].c;\n            cur_y = sel[idx].d;\n        }\n    }\n    total += dist(cur_x, cur_y, 400, 400);\n    return total;\n}\n\n// Check precedence constraints: for each order, restaurant before destination\nbool is_valid(const vector<Point>& seq, int m) {\n    vector<int> rest_pos(m, -1), dest_pos(m, -1);\n    for (size_t i = 0; i < seq.size(); ++i) {\n        int idx = seq[i].first;\n        if (seq[i].second == 0) {\n            rest_pos[idx] = i;\n        } else {\n            dest_pos[idx] = i;\n        }\n    }\n    for (int i = 0; i < m; ++i) {\n        if (rest_pos[i] == -1 || dest_pos[i] == -1) return false;\n        if (rest_pos[i] >= dest_pos[i]) return false;\n    }\n    return true;\n}\n\n// Build a sequence using nearest neighbor with random tie-breaking\nvector<Point> build_sequence(const vector<Order>& selected, int m, mt19937& rng) {\n    vector<Point> seq;\n    vector<bool> rest_done(m, false), dest_done(m, false);\n    vector<int> available; // orders whose restaurant done but destination not\n    int cur_x = 400, cur_y = 400;\n\n    for (int step = 0; step < 2 * m; ++step) {\n        int best_cost = 1e9;\n        vector<pair<int, int>> candidates; // (order_index, type) with cost == best_cost\n\n        // Restaurants of unvisited orders\n        for (int i = 0; i < m; ++i) {\n            if (rest_done[i]) continue;\n            int cost = dist(cur_x, cur_y, selected[i].a, selected[i].b);\n            if (cost < best_cost) {\n                best_cost = cost;\n                candidates.clear();\n                candidates.emplace_back(i, 0);\n            } else if (cost == best_cost) {\n                candidates.emplace_back(i, 0);\n            }\n        }\n        // Destinations of available orders\n        for (int i : available) {\n            int cost = dist(cur_x, cur_y, selected[i].c, selected[i].d);\n            if (cost < best_cost) {\n                best_cost = cost;\n                candidates.clear();\n                candidates.emplace_back(i, 1);\n            } else if (cost == best_cost) {\n                candidates.emplace_back(i, 1);\n            }\n        }\n\n        // Randomly pick one of the candidates\n        uniform_int_distribution<int> dist(0, candidates.size() - 1);\n        int pick = dist(rng);\n        int best_idx = candidates[pick].first;\n        int best_type = candidates[pick].second;\n\n        seq.emplace_back(best_idx, best_type);\n        if (best_type == 0) {\n            rest_done[best_idx] = true;\n            available.push_back(best_idx);\n        } else {\n            dest_done[best_idx] = true;\n            auto it = find(available.begin(), available.end(), best_idx);\n            if (it != available.end()) available.erase(it);\n        }\n        // Update current position\n        if (best_type == 0) {\n            cur_x = selected[best_idx].a;\n            cur_y = selected[best_idx].b;\n        } else {\n            cur_x = selected[best_idx].c;\n            cur_y = selected[best_idx].d;\n        }\n    }\n    return seq;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read all orders\n    orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n\n    // Selection: pick 50 orders with smallest round-trip cost\n    vector<int> indices(1000);\n    for (int i = 0; i < 1000; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int cost_i = dist(400, 400, orders[i].a, orders[i].b) +\n                     dist(orders[i].a, orders[i].b, orders[i].c, orders[i].d) +\n                     dist(orders[i].c, orders[i].d, 400, 400);\n        int cost_j = dist(400, 400, orders[j].a, orders[j].b) +\n                     dist(orders[j].a, orders[j].b, orders[j].c, orders[j].d) +\n                     dist(orders[j].c, orders[j].d, 400, 400);\n        return cost_i < cost_j;\n    });\n    vector<Order> selected;\n    vector<bool> used(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        selected.push_back(orders[indices[i]]);\n        used[indices[i]] = true;\n    }\n    int m = 50;\n\n    // Multi-start: try up to 5 different random sequences\n    clock_t start_time = clock();\n    const double total_time_limit = 1.8 * CLOCKS_PER_SEC;\n    vector<Point> best_seq;\n    int best_total = 1e9;\n\n    for (int seed = 0; seed < 5; ++seed) {\n        if (clock() - start_time > total_time_limit * 0.9) break; // stop if little time left\n        mt19937 rng(seed * 12345 + 67890);\n        vector<Point> seq = build_sequence(selected, m, rng);\n        int total = total_distance(seq, selected);\n\n        // Local search on this sequence\n        clock_t local_start = clock();\n        double local_time_limit = (total_time_limit - (clock() - start_time)) / (5 - seed);\n        bool improved = true;\n        while (improved && (clock() - local_start) < local_time_limit) {\n            improved = false;\n            // Try all segment reversals\n            for (size_t i = 0; i < seq.size(); ++i) {\n                for (size_t j = i + 1; j < seq.size(); ++j) {\n                    vector<Point> new_seq = seq;\n                    reverse(new_seq.begin() + i, new_seq.begin() + j + 1);\n                    if (!is_valid(new_seq, m)) continue;\n                    int new_total = total_distance(new_seq, selected);\n                    if (new_total < total) {\n                        seq = new_seq;\n                        total = new_total;\n                        improved = true;\n                    }\n                }\n                if ((clock() - local_start) >= local_time_limit) break;\n            }\n            // Try all point swaps\n            for (size_t i = 0; i < seq.size(); ++i) {\n                for (size_t j = i + 1; j < seq.size(); ++j) {\n                    vector<Point> new_seq = seq;\n                    swap(new_seq[i], new_seq[j]);\n                    if (!is_valid(new_seq, m)) continue;\n                    int new_total = total_distance(new_seq, selected);\n                    if (new_total < total) {\n                        seq = new_seq;\n                        total = new_total;\n                        improved = true;\n                    }\n                }\n                if ((clock() - local_start) >= local_time_limit) break;\n            }\n        }\n        if (total < best_total) {\n            best_total = total;\n            best_seq = seq;\n        }\n    }\n\n    // Simple order replacement: try to replace each selected order with an unused one\n    // Keep it simple to avoid memory issues\n    for (int i = 0; i < m; ++i) {\n        if (clock() - start_time > total_time_limit * 0.95) break;\n        \n        // Find positions of current order in best_seq\n        int rest_pos = -1, dest_pos = -1;\n        for (size_t j = 0; j < best_seq.size(); ++j) {\n            if (best_seq[j].first == i && best_seq[j].second == 0) rest_pos = j;\n            if (best_seq[j].first == i && best_seq[j].second == 1) dest_pos = j;\n        }\n        assert(rest_pos != -1 && dest_pos != -1);\n        \n        // Try all unused orders\n        for (int j = 0; j < 1000; ++j) {\n            if (used[j]) continue;\n            \n            // Temporarily replace order\n            Order old_order = selected[i];\n            selected[i] = orders[j];\n            \n            // Create new sequence with replaced points\n            vector<Point> new_seq = best_seq;\n            new_seq[rest_pos] = {i, 0}; // Keep same index i\n            new_seq[dest_pos] = {i, 1}; // Keep same index i\n            \n            if (is_valid(new_seq, m)) {\n                int new_total = total_distance(new_seq, selected);\n                if (new_total < best_total) {\n                    // Accept replacement\n                    used[old_order.id] = false;\n                    used[j] = true;\n                    best_seq = new_seq;\n                    best_total = new_total;\n                    break; // Move to next order\n                }\n            }\n            \n            // Revert if not accepted\n            selected[i] = old_order;\n        }\n    }\n\n    // Output selected orders (1-based indices)\n    cout << m;\n    for (const auto& order : selected) {\n        cout << ' ' << order.id + 1;\n    }\n    cout << '\\n';\n\n    // Output route: office, then points in best_seq, then office\n    cout << 1 + 2 * m + 1; // start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : best_seq) {\n        int idx = p.first;\n        if (p.second == 0) {\n            cout << ' ' << selected[idx].a << ' ' << selected[idx].b;\n        } else {\n            cout << ' ' << selected[idx].c << ' ' << selected[idx].d;\n        }\n    }\n    cout << \" 400 400\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct DSU {\n    vector<int> parent, rank;\n    int components;\n    DSU(int n) : parent(n), rank(n, 0), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        components--;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (accepted == 399) {\n            cout << 0 << endl;\n            continue;\n        }\n        if (dsu.find(u[i]) == dsu.find(v[i])) {\n            cout << 0 << endl;\n            continue;\n        }\n        cout << 1 << endl;\n        dsu.unite(u[i], v[i]);\n        accepted++;\n        cout.flush();\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 30;\nconst double WALL_BONUS = 0.5;  // Bonus for placing any wall\nconst double PET_PENALTY = 2.0; // Penalty per pet in component\n\nint N, M;\nint px[20], py[20], pt[20];\nint hx[10], hy[10];\nbool passable[31][31];\n\nbool pet_at[31][31];\nbool human_at[31][31];\nbool adj_to_pet[31][31];\n\nbool blocked_this_turn[31][31];\n\nrandom_device rd;\nmt19937 rng(rd());\n\n// BFS that counts pets and returns size\nint bfs(int sx, int sy, int& pet_count, bool temp_blocked = false, int tbx = -1, int tby = -1) {\n    static bool visited[31][31];\n    memset(visited, 0, sizeof(visited));\n    queue<pair<int,int>> q;\n    if (passable[sx][sy] && !blocked_this_turn[sx][sy] && \n        !(temp_blocked && sx==tbx && sy==tby)) {\n        q.push({sx, sy});\n        visited[sx][sy] = true;\n    }\n    int size = 0;\n    pet_count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        size++;\n        if (pet_at[x][y]) pet_count++;\n        for (int dx = -1; dx <= 1; dx++) {\n            for (int dy = -1; dy <= 1; dy++) {\n                if (abs(dx) + abs(dy) != 1) continue;\n                int nx = x + dx, ny = y + dy;\n                if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) continue;\n                if (!passable[nx][ny]) continue;\n                if (blocked_this_turn[nx][ny]) continue;\n                if (temp_blocked && nx==tbx && ny==tby) continue;\n                if (visited[nx][ny]) continue;\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    return size;\n}\n\n// Simulate pet movement for one step to estimate future pet positions\nvoid simulate_pet_step(int& x, int& y, int type) {\n    // Simplified: for now, just move randomly (can be improved per type)\n    vector<pair<int,int>> moves = {{-1,0},{1,0},{0,-1},{0,1}};\n    vector<pair<int,int>> valid;\n    for (auto [dx, dy] : moves) {\n        int nx = x + dx, ny = y + dy;\n        if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN && passable[nx][ny]) {\n            valid.push_back({nx, ny});\n        }\n    }\n    if (!valid.empty()) {\n        auto [nx, ny] = valid[rng() % valid.size()];\n        x = nx; y = ny;\n    }\n}\n\nint main() {\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> px[i] >> py[i] >> pt[i];\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> hx[i] >> hy[i];\n    }\n\n    // Initialize passable grid\n    for (int i = 1; i <= MAXN; i++) {\n        for (int j = 1; j <= MAXN; j++) {\n            passable[i][j] = true;\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        // Precompute grids\n        memset(pet_at, 0, sizeof(pet_at));\n        for (int i = 0; i < N; i++) pet_at[px[i]][py[i]] = true;\n        memset(human_at, 0, sizeof(human_at));\n        for (int i = 0; i < M; i++) human_at[hx[i]][hy[i]] = true;\n        memset(adj_to_pet, 0, sizeof(adj_to_pet));\n        for (int i = 0; i < N; i++) {\n            int x = px[i], y = py[i];\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    if (abs(dx) + abs(dy) != 1) continue;\n                    int nx = x + dx, ny = y + dy;\n                    if (nx >= 1 && nx <= MAXN && ny >= 1 && ny <= MAXN) {\n                        adj_to_pet[nx][ny] = true;\n                    }\n                }\n            }\n        }\n\n        memset(blocked_this_turn, 0, sizeof(blocked_this_turn));\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        string actions(M, '.');\n\n        for (int idx : order) {\n            int x = hx[idx], y = hy[idx];\n            double best_value = -1e9;\n            char best_action = '.';\n\n            // Compute current pet count for reference\n            int P0;\n            bfs(x, y, P0);\n\n            auto evaluate = [&](char action) -> double {\n                int nx = x, ny = y;\n                bool is_block = false;\n                bool is_move = false;\n                int tbx = -1, tby = -1;\n\n                if (action == '.') {\n                    // Stay\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    // Block\n                    is_block = true;\n                    if (action == 'u') { nx = x-1; ny = y; }\n                    else if (action == 'd') { nx = x+1; ny = y; }\n                    else if (action == 'l') { nx = x; ny = y-1; }\n                    else if (action == 'r') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (pet_at[nx][ny]) return -1e9;\n                    if (human_at[nx][ny]) return -1e9;\n                    if (adj_to_pet[nx][ny]) return -1e9;\n                    tbx = nx; tby = ny;\n                } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // Move\n                    is_move = true;\n                    if (action == 'U') { nx = x-1; ny = y; }\n                    else if (action == 'D') { nx = x+1; ny = y; }\n                    else if (action == 'L') { nx = x; ny = y-1; }\n                    else if (action == 'R') { nx = x; ny = y+1; }\n                    // Check legality\n                    if (nx < 1 || nx > MAXN || ny < 1 || ny > MAXN) return -1e9;\n                    if (!passable[nx][ny]) return -1e9;\n                    if (blocked_this_turn[nx][ny]) return -1e9;\n                } else {\n                    return -1e9;\n                }\n\n                // Compute component after action\n                int start_x = is_move ? nx : x;\n                int start_y = is_move ? ny : y;\n                int pet_count;\n                int comp_size = bfs(start_x, start_y, pet_count, is_block, tbx, tby);\n                \n                // Base value with heavy pet penalty\n                double value = (comp_size / 900.0) * pow(0.5, pet_count * PET_PENALTY);\n                \n                // Bonus for placing a wall\n                if (is_block) {\n                    value += WALL_BONUS;\n                    // Additional bonus for removing pets\n                    if (P0 > pet_count) {\n                        value += 2.0 * (P0 - pet_count);\n                    }\n                }\n                \n                // Small random noise to break ties\n                value += (rng() % 1000) / 1000000.0;\n                return value;\n            };\n\n            vector<char> actions_list = {'.', 'u', 'd', 'l', 'r', 'U', 'D', 'L', 'R'};\n            for (char a : actions_list) {\n                double val = evaluate(a);\n                if (val > best_value) {\n                    best_value = val;\n                    best_action = a;\n                }\n            }\n\n            actions[idx] = best_action;\n\n            if (best_action == 'u' || best_action == 'd' || best_action == 'l' || best_action == 'r') {\n                int bx = x, by = y;\n                if (best_action == 'u') bx = x-1;\n                else if (best_action == 'd') bx = x+1;\n                else if (best_action == 'l') by = y-1;\n                else if (best_action == 'r') by = y+1;\n                blocked_this_turn[bx][by] = true;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        // Read and apply 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') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n            }\n        }\n\n        // Update passable grid with walls\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'u' || a == 'd' || a == 'l' || a == 'r') {\n                int bx = hx[i], by = hy[i];\n                if (a == 'u') bx = hx[i]-1;\n                else if (a == 'd') bx = hx[i]+1;\n                else if (a == 'l') by = hy[i]-1;\n                else if (a == 'r') by = hy[i]+1;\n                passable[bx][by] = false;\n            }\n        }\n\n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') hx[i]--;\n            else if (a == 'D') hx[i]++;\n            else if (a == 'L') hy[i]--;\n            else if (a == 'R') hy[i]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0:U, 1:D, 2:L, 3:R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst double EPS = 1e-12;\nconst int BEAM_WIDTH = 300;   // increased width\n\n// Precompute next cell for each cell and direction\nint next_cell[4][20][20][2]; // [dir][i][j][0]=ni, [1]=nj\n\nvoid precompute_next(const vector<vector<int>>& h,\n                     const vector<vector<int>>& v) {\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            // U\n            if (i > 0 && v[i-1][j] == 0) {\n                next_cell[0][i][j][0] = i-1;\n                next_cell[0][i][j][1] = j;\n            } else {\n                next_cell[0][i][j][0] = i;\n                next_cell[0][i][j][1] = j;\n            }\n            // D\n            if (i < 19 && v[i][j] == 0) {\n                next_cell[1][i][j][0] = i+1;\n                next_cell[1][i][j][1] = j;\n            } else {\n                next_cell[1][i][j][0] = i;\n                next_cell[1][i][j][1] = j;\n            }\n            // L\n            if (j > 0 && h[i][j-1] == 0) {\n                next_cell[2][i][j][0] = i;\n                next_cell[2][i][j][1] = j-1;\n            } else {\n                next_cell[2][i][j][0] = i;\n                next_cell[2][i][j][1] = j;\n            }\n            // R\n            if (j < 19 && h[i][j] == 0) {\n                next_cell[3][i][j][0] = i;\n                next_cell[3][i][j][1] = j+1;\n            } else {\n                next_cell[3][i][j][0] = i;\n                next_cell[3][i][j][1] = j;\n            }\n        }\n    }\n}\n\n// BFS to find a shortest path from start to target\nstring bfs_path(int si, int sj, int ti, int tj,\n                const vector<vector<int>>& h,\n                const vector<vector<int>>& v) {\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move(20, vector<char>(20, ' '));\n    queue<pair<int, int>> q;\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            if (d == 0 && (i == 0 || v[i-1][j] == 1)) continue;\n            if (d == 1 && (i == 19 || v[i][j] == 1)) continue;\n            if (d == 2 && (j == 0 || h[i][j-1] == 1)) continue;\n            if (d == 3 && (j == 19 || h[i][j] == 1)) continue;\n            if (!visited[ni][nj]) {\n                visited[ni][nj] = true;\n                parent[ni][nj] = {i, j};\n                move[ni][nj] = dir_char[d];\n                q.emplace(ni, nj);\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        char m = move[i][j];\n        path += m;\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Simulate the stochastic process and compute expected score\ndouble simulate(const string& s, int si, int sj, int ti, int tj, double p) {\n    double dist[20][20] = {};\n    dist[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int t = 1; t <= L; ++t) {\n        char c = s[t-1];\n        int d = -1;\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        double new_dist[20][20] = {};\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                double prob = dist[i][j];\n                if (prob == 0.0) continue;\n                new_dist[i][j] += prob * p;\n                int ni = next_cell[d][i][j][0];\n                int nj = next_cell[d][i][j][1];\n                if (ni == ti && nj == tj) {\n                    score += prob * (1-p) * (401 - t);\n                } else {\n                    new_dist[ni][nj] += prob * (1-p);\n                }\n            }\n        }\n        memcpy(dist, new_dist, sizeof(dist));\n    }\n    return score;\n}\n\n// Generate greedy nominal string (always try to move towards target)\nstring greedy_nominal(int si, int sj, int ti, int tj,\n                      const vector<vector<int>>& h,\n                      const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char best = 'R';\n        bool moved = false;\n        if (cur_c < tj && h[cur_r][cur_c] == 0) {\n            best = 'R';\n            moved = true;\n        }\n        if (!moved && cur_r < ti && v[cur_r][cur_c] == 0) {\n            best = 'D';\n            moved = true;\n        }\n        if (!moved && cur_c > tj && (cur_c > 0 && h[cur_r][cur_c-1] == 0)) {\n            best = 'L';\n            moved = true;\n        }\n        if (!moved && cur_r > ti && (cur_r > 0 && v[cur_r-1][cur_c] == 0)) {\n            best = 'U';\n            moved = true;\n        }\n        if (!moved) {\n            if (cur_c < 19 && h[cur_r][cur_c] == 0) best = 'R';\n            else if (cur_r < 19 && v[cur_r][cur_c] == 0) best = 'D';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) best = 'L';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) best = 'U';\n            else best = 'R';\n        }\n        cand += best;\n        if (best == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (best == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (best == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n        else if (best == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n    }\n    return cand;\n}\n\n// Generate alternating direction string (prioritize down then right)\nstring alternating_string(int si, int sj, int ti, int tj,\n                          const vector<vector<int>>& h,\n                          const vector<vector<int>>& v) {\n    string cand = \"\";\n    int cur_r = si, cur_c = sj;\n    for (int step = 0; step < 200; ++step) {\n        if (cur_r == ti && cur_c == tj) {\n            cand += 'R';\n            continue;\n        }\n        char dir = 'D';\n        if (cur_r > ti) dir = 'U';\n        else if (cur_c < tj) dir = 'R';\n        else if (cur_c > tj) dir = 'L';\n        bool possible = false;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) possible = true;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) possible = true;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) possible = true;\n        if (!possible) {\n            if (cur_r < 19 && v[cur_r][cur_c] == 0) dir = 'D';\n            else if (cur_r > 0 && v[cur_r-1][cur_c] == 0) dir = 'U';\n            else if (cur_c < 19 && h[cur_r][cur_c] == 0) dir = 'R';\n            else if (cur_c > 0 && h[cur_r][cur_c-1] == 0) dir = 'L';\n            else dir = 'R';\n        }\n        cand += dir;\n        if (dir == 'D' && cur_r < 19 && v[cur_r][cur_c] == 0) cur_r++;\n        else if (dir == 'U' && cur_r > 0 && v[cur_r-1][cur_c] == 0) cur_r--;\n        else if (dir == 'R' && cur_c < 19 && h[cur_r][cur_c] == 0) cur_c++;\n        else if (dir == 'L' && cur_c > 0 && h[cur_r][cur_c-1] == 0) cur_c--;\n    }\n    return cand;\n}\n\n// DP for optimal adaptive value function V[t][i][j] (t steps remaining)\ndouble V[201][20][20];\n// DP for fixed greedy policy value function W[t][i][j]\ndouble W[201][20][20];\nint policy_action[20][20]; // action for each cell under greedy policy\n\nvoid compute_policy(int ti, int tj, const vector<vector<int>>& h,\n                    const vector<vector<int>>& v) {\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            if (i == ti && j == tj) {\n                policy_action[i][j] = 0; // arbitrary\n                continue;\n            }\n            // down\n            if (i < ti && v[i][j] == 0) {\n                policy_action[i][j] = 1;\n            } else if (j < tj && h[i][j] == 0) {\n                policy_action[i][j] = 3;\n            } else if (i > ti && i > 0 && v[i-1][j] == 0) {\n                policy_action[i][j] = 0;\n            } else if (j > tj && j > 0 && h[i][j-1] == 0) {\n                policy_action[i][j] = 2;\n            } else {\n                // blocked, choose any possible direction\n                if (i < 19 && v[i][j] == 0) policy_action[i][j] = 1;\n                else if (j < 19 && h[i][j] == 0) policy_action[i][j] = 3;\n                else if (i > 0 && v[i-1][j] == 0) policy_action[i][j] = 0;\n                else if (j > 0 && h[i][j-1] == 0) policy_action[i][j] = 2;\n                else policy_action[i][j] = 1; // default\n            }\n        }\n    }\n}\n\nvoid compute_V(int ti, int tj, double p) {\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            V[0][i][j] = 0.0;\n    for (int t = 1; t <= 200; ++t) {\n        int step_num = 201 - t;\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    V[t][i][j] = 0.0;\n                    continue;\n                }\n                double best = -1e9;\n                for (int a = 0; a < 4; ++a) {\n                    double val = 0.0;\n                    val += p * V[t-1][i][j];\n                    int ni = next_cell[a][i][j][0];\n                    int nj = next_cell[a][i][j][1];\n                    if (ni == ti && nj == tj) {\n                        val += (1-p) * (401 - step_num);\n                    } else {\n                        val += (1-p) * V[t-1][ni][nj];\n                    }\n                    if (val > best) best = val;\n                }\n                V[t][i][j] = best;\n            }\n        }\n    }\n}\n\nvoid compute_W(int ti, int tj, double p) {\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            W[0][i][j] = 0.0;\n    for (int t = 1; t <= 200; ++t) {\n        int step_num = 201 - t;\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    W[t][i][j] = 0.0;\n                    continue;\n                }\n                int a = policy_action[i][j];\n                double val = p * W[t-1][i][j];\n                int ni = next_cell[a][i][j][0];\n                int nj = next_cell[a][i][j][1];\n                if (ni == ti && nj == tj) {\n                    val += (1-p) * (401 - step_num);\n                } else {\n                    val += (1-p) * W[t-1][ni][nj];\n                }\n                W[t][i][j] = val;\n            }\n        }\n    }\n}\n\n// Helper: apply action to distribution and compute immediate reward\nvoid apply_action(const double dist[20][20], int a, int step,\n                  int ti, int tj, double p,\n                  double new_dist[20][20], double& reward) {\n    memset(new_dist, 0, sizeof(double)*20*20);\n    reward = 0.0;\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            double prob = dist[i][j];\n            if (prob < EPS) continue;\n            new_dist[i][j] += prob * p;\n            int ni = next_cell[a][i][j][0];\n            int nj = next_cell[a][i][j][1];\n            if (ni == ti && nj == tj) {\n                reward += prob * (1-p) * (401 - step);\n            } else {\n                new_dist[ni][nj] += prob * (1-p);\n            }\n        }\n    }\n}\n\n// Heuristic functions\nusing HeuristicFunc = double(*)(const double[20][20], int);\n\ndouble heuristic_max(const double dist[20][20], int r) {\n    double val = 0.0;\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            val += dist[i][j] * max(V[r][i][j], W[r][i][j]);\n    return val;\n}\n\ndouble heuristic_V(const double dist[20][20], int r) {\n    double val = 0.0;\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            val += dist[i][j] * V[r][i][j];\n    return val;\n}\n\ndouble heuristic_weighted(const double dist[20][20], int r) {\n    double val = 0.0;\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            val += dist[i][j] * (0.5 * V[r][i][j] + 0.5 * W[r][i][j]);\n    return val;\n}\n\n// Beam search with selectable heuristic\nstring beam_search_sequence(int si, int sj, int ti, int tj, double p, HeuristicFunc heuristic) {\n    struct State {\n        double dist[20][20];\n        string seq;\n        double score;   // expected reward so far\n        double total;   // score + heuristic (for sorting)\n    };\n    vector<State> beam;\n    // initial state\n    State init;\n    memset(init.dist, 0, sizeof(init.dist));\n    init.dist[si][sj] = 1.0;\n    init.seq = \"\";\n    init.score = 0.0;\n    init.total = heuristic(init.dist, 200);\n    beam.push_back(init);\n\n    for (int step = 1; step <= 200; ++step) {\n        vector<State> candidates;\n        for (const State& st : beam) {\n            // compute total probability\n            double total_prob = 0.0;\n            for (int i = 0; i < 20; ++i)\n                for (int j = 0; j < 20; ++j)\n                    total_prob += st.dist[i][j];\n            if (total_prob < EPS) continue;\n\n            for (int a = 0; a < 4; ++a) {\n                double new_dist[20][20];\n                double reward;\n                apply_action(st.dist, a, step, ti, tj, p, new_dist, reward);\n                double new_score = st.score + reward;\n                double h = heuristic(new_dist, 200 - step);\n                State new_state;\n                memcpy(new_state.dist, new_dist, sizeof(new_dist));\n                new_state.seq = st.seq + dir_char[a];\n                new_state.score = new_score;\n                new_state.total = new_score + h;\n                candidates.push_back(new_state);\n            }\n        }\n        // keep top BEAM_WIDTH candidates\n        if (candidates.size() > BEAM_WIDTH) {\n            nth_element(candidates.begin(), candidates.begin() + BEAM_WIDTH, candidates.end(),\n                        [](const State& a, const State& b) { return a.total > b.total; });\n            candidates.resize(BEAM_WIDTH);\n        }\n        beam = move(candidates);\n    }\n    // select best final state\n    State best = *max_element(beam.begin(), beam.end(),\n                              [](const State& a, const State& b) { return a.total > b.total; });\n    return best.seq;\n}\n\n// Lookahead greedy with dynamic depth and pruning (kept for diversity)\nstring lookahead_greedy_sequence(int si, int sj, int ti, int tj, double p) {\n    double prob[20][20] = {};\n    prob[si][sj] = 1.0;\n    string s = \"\";\n    const int MAX_DEPTH = 4;   // lookahead depth (including current)\n    for (int t = 1; t <= 200; ++t) {\n        int remaining_after = 200 - t;\n        int lookahead = min(MAX_DEPTH - 1, remaining_after);\n        int terminal_rem = remaining_after - lookahead;\n        double best_score = -1e9;\n        int best_action = 0;\n\n        for (int first_a = 0; first_a < 4; ++first_a) {\n            double dist1[20][20];\n            double immediate;\n            apply_action(prob, first_a, t, ti, tj, p, dist1, immediate);\n            double best_continuation = -1e9;\n\n            function<void(int, double[20][20], double)> dfs = [&](int depth, double cur_dist[20][20], double cur_reward) {\n                if (depth == lookahead) {\n                    double term = (terminal_rem > 0) ? heuristic_max(cur_dist, terminal_rem) : 0.0;\n                    double total = cur_reward + term;\n                    if (total > best_continuation) best_continuation = total;\n                    return;\n                }\n                // compute total probability\n                double total_prob = 0.0;\n                for (int i = 0; i < 20; ++i)\n                    for (int j = 0; j < 20; ++j)\n                        total_prob += cur_dist[i][j];\n                if (total_prob < EPS) return;\n\n                int next_step = t + 1 + depth;\n                for (int a = 0; a < 4; ++a) {\n                    double new_dist[20][20];\n                    double add_reward;\n                    apply_action(cur_dist, a, next_step, ti, tj, p, new_dist, add_reward);\n                    dfs(depth + 1, new_dist, cur_reward + add_reward);\n                }\n            };\n\n            dfs(0, dist1, 0.0);\n            double total = immediate + best_continuation;\n            if (total > best_score) {\n                best_score = total;\n                best_action = first_a;\n            }\n        }\n        s += dir_char[best_action];\n        double new_prob[20][20];\n        double dummy;\n        apply_action(prob, best_action, t, ti, tj, p, new_prob, dummy);\n        memcpy(prob, new_prob, sizeof(prob));\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    vector<vector<int>> h(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 19; ++j) {\n            h[i][j] = line[j] - '0';\n        }\n    }\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 20; ++j) {\n            v[i][j] = line[j] - '0';\n        }\n    }\n\n    precompute_next(h, v);\n    compute_policy(ti, tj, h, v);\n    compute_V(ti, tj, p);\n    compute_W(ti, tj, p);\n\n    string shortest_path = bfs_path(si, sj, ti, tj, h, v);\n    int k = shortest_path.size();\n\n    vector<string> candidates;\n\n    if (k > 0) {\n        candidates.push_back(shortest_path);\n        int t = 200 / k;\n        int rem = 200 % k;\n        string cand = \"\";\n        for (int i = 0; i < t; ++i) cand += shortest_path;\n        cand += shortest_path.substr(0, rem);\n        candidates.push_back(cand);\n        int m = 200 / k;\n        cand = \"\";\n        for (char c : shortest_path) {\n            for (int i = 0; i < m; ++i) cand += c;\n        }\n        candidates.push_back(cand);\n    }\n\n    candidates.push_back(greedy_nominal(si, sj, ti, tj, h, v));\n    candidates.push_back(alternating_string(si, sj, ti, tj, h, v));\n    candidates.push_back(lookahead_greedy_sequence(si, sj, ti, tj, p));\n    // Beam searches with different heuristics\n    candidates.push_back(beam_search_sequence(si, sj, ti, tj, p, heuristic_max));\n    candidates.push_back(beam_search_sequence(si, sj, ti, tj, p, heuristic_V));\n    candidates.push_back(beam_search_sequence(si, sj, ti, tj, p, heuristic_weighted));\n\n    double best_score = -1.0;\n    string best_str = \"\";\n    for (const string& cand : candidates) {\n        double score = simulate(cand, si, sj, ti, tj, p);\n        if (score > best_score) {\n            best_score = score;\n            best_str = cand;\n        }\n    }\n\n    cout << best_str << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\nconst int GREEDY_PASSES = 7;\nconst int SA_STEPS = 25000;\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};\n\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nint rotate(int t, int r) {\n    for (int i = 0; i < r; i++) {\n        if (t == 0) t = 1;\n        else if (t == 1) t = 2;\n        else if (t == 2) t = 3;\n        else if (t == 3) t = 0;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else if (t == 7) t = 6;\n    }\n    return t;\n}\n\npair<int, int> compute_two_longest(const vector<vector<int>>& tiles) {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\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                if (visited[i][j][d]) continue;\n                \n                int si = i, sj = j, sd = d;\n                int ci = i, cj = j, cd = d;\n                int length = 0;\n                \n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t = tiles[ci][cj];\n                    int d2 = to[t][cd];\n                    if (d2 == -1) break;\n                    \n                    ci += di[d2];\n                    cj += dj[d2];\n                    if (ci < 0 || ci >= N || cj < 0 || cj >= N) break;\n                    \n                    cd = (d2 + 2) % 4;\n                    length++;\n                    \n                    if (ci == si && cj == sj && cd == sd) {\n                        if (length > max1) {\n                            max2 = max1;\n                            max1 = length;\n                        } else if (length > max2) {\n                            max2 = length;\n                        }\n                        break;\n                    }\n                    \n                    if (length > 4 * N * N) break;\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> tiles(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    // Initialize rotations to 0\n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Greedy hill climbing phase\n    vector<pair<int, int>> all_tiles;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            all_tiles.emplace_back(i, j);\n        }\n    }\n    \n    auto [init_max1, init_max2] = compute_two_longest(tiles);\n    long long current_score = (long long)init_max1 * init_max2;\n    \n    for (int pass = 0; pass < GREEDY_PASSES; pass++) {\n        shuffle(all_tiles.begin(), all_tiles.end(), rng);\n        bool improved = false;\n        \n        for (auto [i, j] : all_tiles) {\n            int current_rot = rotations[i][j];\n            int original_type = tiles[i][j];\n            long long best_score_here = current_score;\n            int best_rot_here = current_rot;\n            \n            for (int rot = 0; rot < 4; rot++) {\n                if (rot == current_rot) continue;\n                \n                int diff = (rot - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                \n                auto [max1, max2] = compute_two_longest(tiles);\n                long long new_score = (long long)max1 * max2;\n                \n                if (new_score > best_score_here) {\n                    best_score_here = new_score;\n                    best_rot_here = rot;\n                }\n            }\n            \n            if (best_rot_here != current_rot) {\n                int diff = (best_rot_here - current_rot + 4) % 4;\n                tiles[i][j] = rotate(original_type, diff);\n                rotations[i][j] = best_rot_here;\n                current_score = best_score_here;\n                improved = true;\n            } else {\n                tiles[i][j] = original_type;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Simulated annealing phase\n    vector<vector<int>> best_rotations = rotations;\n    vector<vector<int>> best_tiles = tiles;\n    long long best_score = current_score;\n    \n    double temperature = 1200.0;\n    double cooling_rate = 0.99985;\n    \n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n    \n    for (int step = 0; step < SA_STEPS; step++) {\n        int i = pos_dist(rng);\n        int j = pos_dist(rng);\n        int old_rot = rotations[i][j];\n        int new_rot = rot_dist(rng);\n        \n        if (new_rot == old_rot) continue;\n        \n        int diff = (new_rot - old_rot + 4) % 4;\n        int old_type = tiles[i][j];\n        int new_type = rotate(old_type, diff);\n        \n        tiles[i][j] = new_type;\n        rotations[i][j] = new_rot;\n        \n        auto [new_max1, new_max2] = compute_two_longest(tiles);\n        long long new_score = (long long)new_max1 * new_max2;\n        \n        if (new_score > current_score || \n            rng() % 10000 < 10000 * exp((new_score - current_score) / temperature)) {\n            current_score = new_score;\n            \n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rotations = rotations;\n                best_tiles = tiles;\n            }\n        } else {\n            tiles[i][j] = old_type;\n            rotations[i][j] = old_rot;\n        }\n        \n        temperature *= cooling_rate;\n        \n        // Early termination if we reach a very high score\n        if (best_score > 1000000) break;\n    }\n    \n    // Output the best rotations found\n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += '0' + best_rotations[i][j];\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <utility>\n#include <chrono>\n#include <limits>\n\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opposite[4] = {1, 0, 3, 2};\n\nstruct State {\n    int S;                 // size of the largest tree component\n    int edges_in_largest;  // edges in that component\n};\n\nState compute_state() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_vertices = 0;\n    int max_edges = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            if (visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int vertices = 0;\n            int edges = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                vertices++;\n                int mask = board[x][y];\n                for (int d = 0; d < 4; ++d) {\n                    if (!(mask & (1 << d))) continue;\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    int opp_mask = board[nx][ny];\n                    int opp_bit = 1 << opposite[d];\n                    if (opp_mask & opp_bit) {\n                        if (d == 1 || d == 3) {\n                            edges++;\n                        }\n                        if (!visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            if (edges == vertices - 1) { // tree\n                if (vertices > max_vertices) {\n                    max_vertices = vertices;\n                    max_edges = edges;\n                } else if (vertices == max_vertices && edges > max_edges) {\n                    max_edges = edges;\n                }\n            }\n        }\n    }\n    return {max_vertices, max_edges};\n}\n\nvector<char> get_valid_moves() {\n    vector<char> moves;\n    for (int d = 0; d < 4; ++d) {\n        int ni = empty_i + di[d];\n        int nj = empty_j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            moves.push_back(dir_char[d]);\n        }\n    }\n    return moves;\n}\n\nvoid apply_move(int d) {\n    int ni = empty_i + di[d];\n    int nj = empty_j + dj[d];\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nvoid undo_move(int d) {\n    apply_move(opposite[d]);\n}\n\npair<bool, string> simulated_annealing_run(mt19937& gen, uniform_real_distribution<>& dis, int max_iter) {\n    State current_state = compute_state();\n    int current_score = current_state.S * 1000000 + current_state.edges_in_largest;\n    string current_seq = \"\";\n    bool found_full_tree = false;\n    string full_tree_seq = \"\";\n    int best_S = current_state.S;\n    int best_edges = current_state.edges_in_largest;\n    string best_seq = current_seq;\n\n    double temp = 5.0;\n    double cooling = 0.999;\n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        vector<char> moves = get_valid_moves();\n        if (moves.empty()) break;\n        char move = moves[gen() % moves.size()];\n        int d;\n        for (int i = 0; i < 4; ++i) {\n            if (dir_char[i] == move) {\n                d = i;\n                break;\n            }\n        }\n        apply_move(d);\n        State new_state = compute_state();\n        int new_score = new_state.S * 1000000 + new_state.edges_in_largest;\n        double delta = new_score - current_score;\n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            current_state = new_state;\n            current_score = new_score;\n            current_seq += move;\n            if (new_state.S > best_S || (new_state.S == best_S && new_state.edges_in_largest > best_edges)) {\n                best_S = new_state.S;\n                best_edges = new_state.edges_in_largest;\n                best_seq = current_seq;\n            }\n            if (new_state.S == N * N - 1) {\n                if (!found_full_tree || current_seq.length() < full_tree_seq.length()) {\n                    found_full_tree = true;\n                    full_tree_seq = current_seq;\n                }\n                break;\n            }\n        } else {\n            undo_move(d);\n        }\n        temp *= cooling;\n    }\n\n    if (found_full_tree) {\n        return {true, full_tree_seq};\n    } else {\n        return {false, best_seq};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 2.8;\n    const int MAX_ITER_PER_RUN = 500; // keep runs short to allow many runs\n\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int init_empty_i, init_empty_j;\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            initial_board[i][j] = val;\n            if (val == 0) {\n                init_empty_i = i;\n                init_empty_j = j;\n            }\n        }\n    }\n\n    bool overall_full_tree = false;\n    string overall_best_seq = \"\";\n    int overall_best_S = 0;\n    int overall_best_edges = 0;\n    int overall_full_tree_len = numeric_limits<int>::max();\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed >= time_limit) break;\n\n        board = initial_board;\n        empty_i = init_empty_i;\n        empty_j = init_empty_j;\n\n        // limit iterations per run to min(T, MAX_ITER_PER_RUN)\n        int max_iter = min(T, MAX_ITER_PER_RUN);\n        auto [is_full, seq] = simulated_annealing_run(gen, dis, max_iter);\n\n        if (is_full) {\n            if (seq.length() < overall_full_tree_len) {\n                overall_full_tree = true;\n                overall_full_tree_len = seq.length();\n                overall_best_seq = seq;\n            }\n        } else {\n            // evaluate the sequence's final state\n            vector<vector<int>> temp_board = initial_board;\n            int temp_empty_i = init_empty_i, temp_empty_j = init_empty_j;\n            for (char c : seq) {\n                int d;\n                for (int i = 0; i < 4; ++i) {\n                    if (dir_char[i] == c) {\n                        d = i;\n                        break;\n                    }\n                }\n                int ni = temp_empty_i + di[d];\n                int nj = temp_empty_j + dj[d];\n                swap(temp_board[temp_empty_i][temp_empty_j], temp_board[ni][nj]);\n                temp_empty_i = ni;\n                temp_empty_j = nj;\n            }\n            vector<vector<int>> saved_board = board;\n            int saved_empty_i = empty_i, saved_empty_j = empty_j;\n            board = temp_board;\n            empty_i = temp_empty_i;\n            empty_j = temp_empty_j;\n            State final_state = compute_state();\n            board = saved_board;\n            empty_i = saved_empty_i;\n            empty_j = saved_empty_j;\n\n            if (final_state.S > overall_best_S ||\n                (final_state.S == overall_best_S && final_state.edges_in_largest > overall_best_edges)) {\n                overall_best_S = final_state.S;\n                overall_best_edges = final_state.edges_in_largest;\n                overall_best_seq = seq;\n            }\n        }\n    }\n\n    // ensure the output sequence length does not exceed T\n    if (overall_best_seq.length() > T) {\n        overall_best_seq = overall_best_seq.substr(0, T);\n    }\n    cout << overall_best_seq << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n#include <set>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\n// Global arrays\nint a[11]; // a[1]..a[10]\n\n// Compute the score for given vertical lines V and horizontal lines H\nint compute_score(const vector<int>& V, const vector<int>& H, const vector<pair<int,int>>& points) {\n    int p = V.size();\n    int q = H.size();\n    int total_cells = (p+1)*(q+1);\n    vector<int> cell_counts(total_cells, 0);\n    \n    // Create boundary arrays including cake boundaries (-10000 and 10000)\n    vector<int> V_all(p+2), H_all(q+2);\n    V_all[0] = -10000;\n    for (int i=0; i<p; ++i) V_all[i+1] = V[i];\n    V_all[p+1] = 10000;\n    H_all[0] = -10000;\n    for (int i=0; i<q; ++i) H_all[i+1] = H[i];\n    H_all[q+1] = 10000;\n    \n    // For each point, determine its cell\n    for (const auto& pt : points) {\n        int x = pt.first, y = pt.second;\n        // Find vertical interval index i such that V_all[i] < x < V_all[i+1]\n        auto it_x = upper_bound(V_all.begin(), V_all.end(), x);\n        // Since x is strictly between -10000 and 10000, it_x cannot be begin or end\n        int i = (it_x - V_all.begin()) - 1;\n        // Find horizontal interval index j\n        auto it_y = upper_bound(H_all.begin(), H_all.end(), y);\n        int j = (it_y - H_all.begin()) - 1;\n        int cell_idx = i * (q+1) + j;\n        cell_counts[cell_idx]++;\n    }\n    \n    // Compute b_d for d=1..10\n    vector<int> b(11, 0); // index 1..10\n    for (int cnt : cell_counts) {\n        if (1 <= cnt && cnt <= 10) {\n            b[cnt]++;\n        }\n    }\n    int score = 0;\n    for (int d=1; d<=10; ++d) {\n        score += min(a[d], b[d]);\n    }\n    return score;\n}\n\n// Check if a vertical line at position x is valid (does not pass through any point)\nbool is_valid_vertical(int x, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.first == x) return false;\n    }\n    return true;\n}\n\n// Check if a horizontal line at position y is valid\nbool is_valid_horizontal(int y, const vector<pair<int,int>>& points) {\n    for (const auto& pt : points) {\n        if (pt.second == y) return false;\n    }\n    return true;\n}\n\n// Find a free integer coordinate for a line, starting from a candidate and exploring nearby integers\nint find_free(int cand, const vector<int>& lines, const vector<pair<int,int>>& points, bool is_vertical) {\n    for (int d=0; ; ++d) {\n        for (int sign : {0, 1, -1}) {\n            int pos = cand + sign * d;\n            if (pos < -10000 || pos > 10000) continue;\n            // Check not already used by another line\n            if (find(lines.begin(), lines.end(), pos) != lines.end()) continue;\n            // Check not on any point\n            if (is_vertical) {\n                if (!is_valid_vertical(pos, points)) continue;\n            } else {\n                if (!is_valid_horizontal(pos, points)) continue;\n            }\n            return pos;\n        }\n    }\n}\n\n// Flexible simulated annealing that allows changing orientation and adding/removing lines\npair<vector<int>, vector<int>> sa_optimize_flexible(int initial_p, int initial_q, const vector<pair<int,int>>& points, int max_lines, int iterations=1500) {\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    uniform_int_distribution<int> dist_move(0, 3); // 0: move line, 1: change orientation, 2: add line, 3: remove line\n    uniform_int_distribution<int> dist_offset(-100, 100);\n    \n    int N = points.size();\n    \n    // Initialize vertical lines\n    vector<int> V;\n    for (int i=1; i<=initial_p; ++i) {\n        // Simple initialization: evenly spaced from -10000 to 10000, avoiding points\n        int cand = -10000 + i * 20000 / (initial_p+1);\n        int pos = find_free(cand, V, points, true);\n        V.push_back(pos);\n    }\n    sort(V.begin(), V.end());\n    \n    // Initialize horizontal lines\n    vector<int> H;\n    for (int i=1; i<=initial_q; ++i) {\n        int cand = -10000 + i * 20000 / (initial_q+1);\n        int pos = find_free(cand, H, points, false);\n        H.push_back(pos);\n    }\n    sort(H.begin(), H.end());\n    \n    int cur_score = compute_score(V, H, points);\n    vector<int> bestV = V, bestH = H;\n    int best_score = cur_score;\n    \n    double temp = 1000.0;\n    double cooling = 0.999;\n    \n    for (int iter=0; iter<iterations; ++iter) {\n        int total_lines = V.size() + H.size();\n        int move_type = dist_move(rng);\n        bool vertical = (rng()%2 == 0); // for orientation change, which orientation to target\n        \n        if (move_type == 0 && total_lines > 0) {\n            // Move a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            \n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            int new_pos = cur_pos + dist_offset(rng);\n            if (new_pos < -10000 || new_pos > 10000) continue;\n            if (new_pos == cur_pos) continue;\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                newV[idx] = new_pos;\n                if (!is_valid_vertical(new_pos, points)) continue;\n                sort(newV.begin(), newV.end());\n                if (adjacent_find(newV.begin(), newV.end()) != newV.end()) continue;\n            } else {\n                newH[idx] = new_pos;\n                if (!is_valid_horizontal(new_pos, points)) continue;\n                sort(newH.begin(), newH.end());\n                if (adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 1 && total_lines > 0) {\n            // Change orientation of a line\n            int line_idx = rng() % total_lines;\n            bool is_vertical = (line_idx < V.size());\n            int idx = is_vertical ? line_idx : line_idx - V.size();\n            int cur_pos = is_vertical ? V[idx] : H[idx];\n            \n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (is_vertical) {\n                // Change from vertical to horizontal\n                newV.erase(newV.begin() + idx);\n                // Check if cur_pos is valid as horizontal\n                if (!is_valid_horizontal(cur_pos, points)) continue;\n                // Check not already in H\n                if (find(newH.begin(), newH.end(), cur_pos) != newH.end()) continue;\n                newH.push_back(cur_pos);\n                sort(newH.begin(), newH.end());\n            } else {\n                // Change from horizontal to vertical\n                newH.erase(newH.begin() + idx);\n                if (!is_valid_vertical(cur_pos, points)) continue;\n                if (find(newV.begin(), newV.end(), cur_pos) != newV.end()) continue;\n                newV.push_back(cur_pos);\n                sort(newV.begin(), newV.end());\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 2 && total_lines < max_lines) {\n            // Add a line (randomly vertical or horizontal)\n            bool add_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            // Generate a candidate position\n            int cand = -10000 + rng()%20001;\n            if (add_vertical) {\n                int pos = find_free(cand, newV, points, true);\n                newV.push_back(pos);\n                sort(newV.begin(), newV.end());\n            } else {\n                int pos = find_free(cand, newH, points, false);\n                newH.push_back(pos);\n                sort(newH.begin(), newH.end());\n            }\n            // Check for duplicates\n            if (adjacent_find(newV.begin(), newV.end()) != newV.end() ||\n                adjacent_find(newH.begin(), newH.end()) != newH.end()) continue;\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        } else if (move_type == 3 && total_lines > 1) {\n            // Remove a line\n            bool remove_vertical = (rng()%2 == 0);\n            vector<int> newV = V;\n            vector<int> newH = H;\n            if (remove_vertical && !newV.empty()) {\n                int idx = rng() % newV.size();\n                newV.erase(newV.begin() + idx);\n            } else if (!newH.empty()) {\n                int idx = rng() % newH.size();\n                newH.erase(newH.begin() + idx);\n            } else {\n                continue; // cannot remove\n            }\n            \n            int new_score = compute_score(newV, newH, points);\n            int delta = new_score - cur_score;\n            if (delta > 0 || prob(rng) < exp(delta / temp)) {\n                cur_score = new_score;\n                V = newV;\n                H = newH;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    bestV = V;\n                    bestH = H;\n                }\n            }\n        }\n        temp *= cooling;\n    }\n    return {bestV, bestH};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int N, K;\n    cin >> N >> K;\n    for (int d=1; d<=10; ++d) cin >> a[d];\n    \n    vector<pair<int,int>> points(N);\n    for (int i=0; i<N; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Try a few initial splits and run flexible SA on each\n    vector<pair<int,int>> initial_splits = {{0,0}, {25,25}, {50,0}, {0,50}, {50,50}, {75,25}, {25,75}};\n    int best_total_score = -1;\n    vector<int> bestV, bestH;\n    \n    for (auto [p,q] : initial_splits) {\n        if (p+q > K) continue;\n        auto [V, H] = sa_optimize_flexible(p, q, points, K, 1500);\n        int score = compute_score(V, H, points);\n        if (score > best_total_score) {\n            best_total_score = score;\n            bestV = V;\n            bestH = H;\n        }\n    }\n    \n    // Output\n    cout << bestV.size() + bestH.size() << '\\n';\n    // Vertical lines\n    for (int x : bestV) {\n        cout << x << \" \" << -10000 << \" \" << x << \" \" << 10000 << '\\n';\n    }\n    // Horizontal lines\n    for (int y : bestH) {\n        cout << -10000 << \" \" << y << \" \" << 10000 << \" \" << y << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <ctime>\n#include <array>\n#include <cstring>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\n// Encode a unit segment into a 32-bit integer (canonical order)\nuint32_t encode_seg(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    return (x1 << 18) | (y1 << 12) | (x2 << 6) | y2;\n}\n\n// Check condition 2 for axis-aligned rectangle\nbool check_perimeter_axis(int x1, int y1, int x2, int y2, const vector<vector<bool>>& dot_grid) {\n    for (int y = y1 + 1; y < y2; ++y) {\n        if (dot_grid[x1][y] || dot_grid[x2][y])\n            return false;\n    }\n    for (int x = x1 + 1; x < x2; ++x) {\n        if (dot_grid[x][y1] || dot_grid[x][y2])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for axis-aligned rectangle\nbool check_used_segments_axis(int x1, int y1, int x2, int y2, const unordered_set<uint32_t>& used_segments) {\n    for (int y = y1; y < y2; ++y) {\n        if (used_segments.count(encode_seg(x1, y, x1, y + 1)))\n            return false;\n        if (used_segments.count(encode_seg(x2, y, x2, y + 1)))\n            return false;\n    }\n    for (int x = x1; x < x2; ++x) {\n        if (used_segments.count(encode_seg(x, y1, x + 1, y1)))\n            return false;\n        if (used_segments.count(encode_seg(x, y2, x + 1, y2)))\n            return false;\n    }\n    return true;\n}\n\n// Check condition 2 for 45-degree rectangle\nbool check_perimeter_45(int x, int y, int a, int b, const vector<vector<bool>>& dot_grid) {\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + i][y + i])\n            return false;\n    }\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + a + i][y + a - i])\n            return false;\n    }\n    for (int i = 1; i < a; ++i) {\n        if (dot_grid[x + a + b - i][y + a - b - i])\n            return false;\n    }\n    for (int i = 1; i < b; ++i) {\n        if (dot_grid[x + b - i][y - b + i])\n            return false;\n    }\n    return true;\n}\n\n// Check condition 3 for 45-degree rectangle\nbool check_used_segments_45(int x, int y, int a, int b, const unordered_set<uint32_t>& used_segments) {\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + i, y + i, x + i + 1, y + i + 1)))\n            return false;\n    }\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + a + i, y + a - i, x + a + i + 1, y + a - i - 1)))\n            return false;\n    }\n    for (int i = 0; i < a; ++i) {\n        if (used_segments.count(encode_seg(x + a + b - i, y + a - b - i, x + a + b - i - 1, y + a - b - i - 1)))\n            return false;\n    }\n    for (int i = 0; i < b; ++i) {\n        if (used_segments.count(encode_seg(x + b - i, y - b + i, x + b - i - 1, y - b + i + 1)))\n            return false;\n    }\n    return true;\n}\n\n// Add all unit segments of a rectangle to used_segments\nvoid add_rectangle_segments(const array<int, 8>& op, unordered_set<uint32_t>& used_segments) {\n    for (int k = 0; k < 4; ++k) {\n        int k2 = (k + 1) % 4;\n        int x1 = op[2*k], y1 = op[2*k+1];\n        int x2 = op[2*k2], y2 = op[2*k2+1];\n        \n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        int sx = (dx == 0) ? 0 : (dx > 0 ? 1 : -1);\n        int sy = (dy == 0) ? 0 : (dy > 0 ? 1 : -1);\n        int num_steps = max(abs(dx), abs(dy));\n        \n        for (int step = 0; step < num_steps; ++step) {\n            int cur_x = x1 + step * sx;\n            int cur_y = y1 + step * sy;\n            int next_x = cur_x + sx;\n            int next_y = cur_y + sy;\n            used_segments.insert(encode_seg(cur_x, cur_y, next_x, next_y));\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    vector<Point> initial(M);\n    vector<vector<bool>> dot_grid(N, vector<bool>(N, false));\n    vector<int> row_count(N, 0), col_count(N, 0);\n    \n    for (int i = 0; i < M; ++i) {\n        cin >> initial[i].x >> initial[i].y;\n        dot_grid[initial[i].x][initial[i].y] = true;\n        row_count[initial[i].x]++;\n        col_count[initial[i].y]++;\n    }\n\n    vector<Point> dots = initial;\n    unordered_set<uint32_t> used_segments;\n    vector<array<int, 8>> operations;\n\n    int c = (N - 1) / 2;\n    int max_weight = 2 * c * c + 1;\n    clock_t start_time = clock();\n\n    while (true) {\n        if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.0)\n            break;\n\n        int best_weight = -1;\n        int best_size = 1000000;\n        int best_usage = 1000000;\n        array<int, 8> best_op;\n        bool found = false;\n        bool found_corner = false;\n\n        int Mcurr = dots.size();\n        for (int i = 0; i < Mcurr && !found_corner; ++i) {\n            if ((clock() - start_time) / CLOCKS_PER_SEC >= 4.0)\n                break;\n                \n            for (int j = i + 1; j < Mcurr && !found_corner; ++j) {\n                Point A = dots[i], B = dots[j];\n\n                // ---------- Axis-aligned rectangle ----------\n                int x1 = min(A.x, B.x), x2 = max(A.x, B.x);\n                int y1 = min(A.y, B.y), y2 = max(A.y, B.y);\n                if (x1 < x2 && y1 < y2) {\n                    bool c1 = dot_grid[x1][y1];\n                    bool c2 = dot_grid[x1][y2];\n                    bool c3 = dot_grid[x2][y1];\n                    bool c4 = dot_grid[x2][y2];\n                    int cnt = c1 + c2 + c3 + c4;\n                    if (cnt == 3) {\n                        Point D;\n                        if (!c1) D = {x1, y1};\n                        else if (!c2) D = {x1, y2};\n                        else if (!c3) D = {x2, y1};\n                        else D = {x2, y2};\n\n                        if (check_perimeter_axis(x1, y1, x2, y2, dot_grid) &&\n                            check_used_segments_axis(x1, y1, x2, y2, used_segments)) {\n                            int w = (D.x - c) * (D.x - c) + (D.y - c) * (D.y - c) + 1;\n                            int dx = x2 - x1;\n                            int dy = y2 - y1;\n                            int size = 2 * (dx + dy);\n                            int usage = row_count[D.x] + col_count[D.y];\n                            \n                            if (w == max_weight) {\n                                best_weight = w;\n                                best_size = size;\n                                best_usage = usage;\n                                array<Point, 4> corners;\n                                corners[0] = {x1, y1};\n                                corners[1] = {x1, y2};\n                                corners[2] = {x2, y2};\n                                corners[3] = {x2, y1};\n                                \n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                                found_corner = true;\n                                break;\n                            } else if (w > best_weight || \n                                       (w == best_weight && size < best_size) ||\n                                       (w == best_weight && size == best_size && usage < best_usage)) {\n                                best_weight = w;\n                                best_size = size;\n                                best_usage = usage;\n                                array<Point, 4> corners;\n                                corners[0] = {x1, y1};\n                                corners[1] = {x1, y2};\n                                corners[2] = {x2, y2};\n                                corners[3] = {x2, y1};\n                                \n                                int idx = 0;\n                                for (int k = 0; k < 4; ++k) {\n                                    if (corners[k].x == D.x && corners[k].y == D.y) {\n                                        idx = k;\n                                        break;\n                                    }\n                                }\n                                best_op = {D.x, D.y,\n                                           corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                           corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                           corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                                found = true;\n                            }\n                        }\n                    }\n                }\n\n                // ---------- 45-degree rectangle ----------\n                for (int order = 0; order < 2 && !found_corner; ++order) {\n                    Point start = (order == 0) ? A : B;\n                    Point opposite = (order == 0) ? B : A;\n                    int dx = opposite.x - start.x;\n                    int dy = opposite.y - start.y;\n                    int sum_diff = dx + dy;\n                    int sub_diff = dx - dy;\n                    if (sum_diff % 2 != 0 || sub_diff % 2 != 0) continue;\n                    int a = sum_diff / 2;\n                    int b = sub_diff / 2;\n                    if (a <= 0 || b <= 0) continue;\n\n                    Point C = {start.x + a, start.y + a};\n                    Point D = {start.x + b, start.y - b};\n                    if (C.x < 0 || C.x >= N || C.y < 0 || C.y >= N ||\n                        D.x < 0 || D.x >= N || D.y < 0 || D.y >= N) continue;\n\n                    bool cC = dot_grid[C.x][C.y];\n                    bool cD = dot_grid[D.x][D.y];\n                    if (cC + cD != 1) continue;\n\n                    Point missing = cC ? D : C;\n                    \n                    array<Point, 4> corners;\n                    corners[0] = start;\n                    corners[1] = C;\n                    corners[2] = opposite;\n                    corners[3] = D;\n\n                    if (check_perimeter_45(start.x, start.y, a, b, dot_grid) &&\n                        check_used_segments_45(start.x, start.y, a, b, used_segments)) {\n                        int w = (missing.x - c) * (missing.x - c) + (missing.y - c) * (missing.y - c) + 1;\n                        int size = 2 * (a + b);\n                        int usage = row_count[missing.x] + col_count[missing.y];\n                        \n                        if (w == max_weight) {\n                            best_weight = w;\n                            best_size = size;\n                            best_usage = usage;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                            found_corner = true;\n                            break;\n                        } else if (w > best_weight || \n                                   (w == best_weight && size < best_size) ||\n                                   (w == best_weight && size == best_size && usage < best_usage)) {\n                            best_weight = w;\n                            best_size = size;\n                            best_usage = usage;\n                            int idx = 0;\n                            for (int k = 0; k < 4; ++k) {\n                                if (corners[k].x == missing.x && corners[k].y == missing.y) {\n                                    idx = k;\n                                    break;\n                                }\n                            }\n                            best_op = {missing.x, missing.y,\n                                       corners[(idx+1)%4].x, corners[(idx+1)%4].y,\n                                       corners[(idx+2)%4].x, corners[(idx+2)%4].y,\n                                       corners[(idx+3)%4].x, corners[(idx+3)%4].y};\n                            found = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (!found) break;\n\n        operations.push_back(best_op);\n        Point new_dot = {best_op[0], best_op[1]};\n        dot_grid[new_dot.x][new_dot.y] = true;\n        row_count[new_dot.x]++;\n        col_count[new_dot.y]++;\n        dots.push_back(new_dot);\n        add_rectangle_segments(best_op, used_segments);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            cout << op[i];\n            if (i < 7) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int SIZE = 10;\nusing Grid = vector<vector<int>>; // 1\u2011indexed, 11x11\n\n// Apply a tilt in the given direction and return the new grid.\nGrid apply_tilt(const Grid& grid, char dir) {\n    Grid new_grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n    if (dir == 'L') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][i + 1] = flavors[i];\n        }\n    } else if (dir == 'R') {\n        for (int r = 1; r <= SIZE; ++r) {\n            vector<int> flavors;\n            for (int c = 1; c <= SIZE; ++c)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[r][SIZE - k + 1 + i] = flavors[i];\n        }\n    } else if (dir == 'F') { // forward = up\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[i + 1][c] = flavors[i];\n        }\n    } else { // 'B' \u2013 backward = down\n        for (int c = 1; c <= SIZE; ++c) {\n            vector<int> flavors;\n            for (int r = 1; r <= SIZE; ++r)\n                if (grid[r][c] != 0) flavors.push_back(grid[r][c]);\n            int k = flavors.size();\n            for (int i = 0; i < k; ++i) new_grid[SIZE - k + 1 + i][c] = flavors[i];\n        }\n    }\n    return new_grid;\n}\n\n// Evaluate a grid using a combined heuristic: connectivity + compactness.\ndouble evaluate_state(const Grid& grid) {\n    bool visited[SIZE + 1][SIZE + 1] = {false};\n    long long connectivity = 0;\n    const int dr[] = {1, -1, 0, 0};\n    const int dc[] = {0, 0, 1, -1};\n\n    // Compute connectivity (sum of squares of component sizes).\n    for (int r = 1; r <= SIZE; ++r) {\n        for (int c = 1; c <= SIZE; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                vector<pair<int, int>> queue = {{r, c}};\n                visited[r][c] = true;\n                int idx = 0;\n                while (idx < queue.size()) {\n                    auto [cr, cc] = queue[idx++];\n                    ++size;\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = cr + dr[d];\n                        int nc = cc + dc[d];\n                        if (nr >= 1 && nr <= SIZE && nc >= 1 && nc <= SIZE &&\n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            queue.push_back({nr, nc});\n                        }\n                    }\n                }\n                connectivity += (long long)size * size;\n            }\n        }\n    }\n\n    // Compute compactness (density of each flavor's bounding box).\n    double compactness = 0.0;\n    for (int flavor = 1; flavor <= 3; ++flavor) {\n        int min_r = SIZE + 1, max_r = 0, min_c = SIZE + 1, max_c = 0;\n        int count = 0;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == flavor) {\n                    ++count;\n                    min_r = min(min_r, r);\n                    max_r = max(max_r, r);\n                    min_c = min(min_c, c);\n                    max_c = max(max_c, c);\n                }\n            }\n        }\n        if (count > 0) {\n            int area = (max_r - min_r + 1) * (max_c - min_c + 1);\n            compactness += (double)count / area;\n        }\n    }\n\n    const double beta = 1000.0; // weight for compactness\n    return connectivity + beta * compactness;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) cin >> f[i];\n\n    Grid grid(SIZE + 1, vector<int>(SIZE + 1, 0));\n\n    for (int t = 1; t <= 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Locate the p\u2011th empty cell (front\u2011to\u2011back, left\u2011to\u2011right).\n        int count = 0;\n        int placed_r = -1, placed_c = -1;\n        for (int r = 1; r <= SIZE; ++r) {\n            for (int c = 1; c <= SIZE; ++c) {\n                if (grid[r][c] == 0) {\n                    ++count;\n                    if (count == p) {\n                        placed_r = r;\n                        placed_c = c;\n                        break;\n                    }\n                }\n            }\n            if (placed_r != -1) break;\n        }\n        grid[placed_r][placed_c] = f[t];\n\n        if (t == 100) break; // last candy \u2013 no tilt needed\n\n        // One\u2011step lookahead with combined heuristic.\n        char best_dir = 'F';\n        double best_expected = -1.0;\n\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid grid1 = apply_tilt(grid, dir);\n\n            // Collect empty cells in grid1.\n            vector<pair<int, int>> empties;\n            for (int r = 1; r <= SIZE; ++r)\n                for (int c = 1; c <= SIZE; ++c)\n                    if (grid1[r][c] == 0) empties.emplace_back(r, c);\n\n            double total = 0.0;\n            for (auto [r, c] : empties) {\n                Grid grid2 = grid1;\n                grid2[r][c] = f[t + 1];\n\n                double best_next = 0.0;\n                for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                    Grid grid3 = apply_tilt(grid2, next_dir);\n                    double sc = evaluate_state(grid3);\n                    if (sc > best_next) best_next = sc;\n                }\n                total += best_next;\n            }\n            double expected = total / empties.size();\n            if (expected > best_expected) {\n                best_expected = expected;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        grid = apply_tilt(grid, best_dir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Precompute expected sorted degree lists for each possible a (1..N)\n    vector<vector<double>> exp_sorted(N + 1);\n    for (int a = 1; a <= N; ++a) {\n        vector<double> degs;\n        if (a == N) {\n            double mu = (N - 1) * (1 - epsilon);\n            degs.assign(N, mu);\n        } else {\n            double muA = (a - 1) * (1 - epsilon) + (N - a) * epsilon;\n            double muB = (N - a - 1) * (1 - epsilon) + a * epsilon;\n            for (int i = 0; i < a; ++i) degs.push_back(muA);\n            for (int i = 0; i < N - a; ++i) degs.push_back(muB);\n            sort(degs.begin(), degs.end());\n        }\n        exp_sorted[a] = degs;\n    }\n\n    // Precompute squared distances between any two a\n    vector<vector<double>> dist(N + 1, vector<double>(N + 1, 0.0));\n    for (int a1 = 1; a1 <= N; ++a1) {\n        for (int a2 = a1 + 1; a2 <= N; ++a2) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = exp_sorted[a1][i] - exp_sorted[a2][i];\n                d += diff * diff;\n            }\n            dist[a1][a2] = d;\n            dist[a2][a1] = d;\n        }\n    }\n\n    // Greedy selection of M a values\n    vector<int> selected;\n    selected.push_back(50);  // start with middle\n    vector<bool> used(N + 1, false);\n    used[50] = true;\n    for (int step = 1; step < M; ++step) {\n        int best_a = -1;\n        double best_min_dist = -1.0;\n        for (int a = 1; a <= N; ++a) {\n            if (used[a]) continue;\n            double min_dist = 1e18;\n            for (int b : selected) {\n                min_dist = min(min_dist, dist[a][b]);\n            }\n            if (min_dist > best_min_dist) {\n                best_min_dist = min_dist;\n                best_a = a;\n            }\n        }\n        selected.push_back(best_a);\n        used[best_a] = true;\n    }\n\n    // Sort selected a in increasing order for output order\n    sort(selected.begin(), selected.end());\n\n    // Create mapping from a to index\n    vector<int> index_of_a(N + 1, -1);\n    for (int i = 0; i < M; ++i) {\n        index_of_a[selected[i]] = i;\n    }\n\n    // Output N\n    cout << N << endl;\n\n    // Output M graphs\n    for (int a : selected) {\n        string graph;\n        graph.resize(N * (N - 1) / 2, '0');\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool same_clique = false;\n                if (a == N) {\n                    same_clique = true; // complete graph\n                } else {\n                    if (i < a && j < a) same_clique = true;\n                    else if (i >= a && j >= a) same_clique = true;\n                }\n                if (same_clique) graph[pos] = '1';\n                pos++;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        // Compute degrees\n        vector<int> deg(N, 0);\n        int pos = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[pos] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                pos++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n\n        // Find the a with minimum squared distance\n        int best_idx = -1;\n        double best_dist = 1e18;\n        for (int a : selected) {\n            double d = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = deg[i] - exp_sorted[a][i];\n                d += diff * diff;\n            }\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = index_of_a[a];\n            }\n        }\n\n        cout << best_idx << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll INF = 1e18;\nconst int MAXN = 1000;\nconst int LOCAL_SEARCH_ITER = 10000;\n\nint N, M, D, K;\nvector<vector<pair<int, int>>> adj; // neighbor, edge index\nvector<int> u, v, w;\nvector<double> mid_x, mid_y;\nvector<ll> unique_pairs;\nvector<double> importance;\nvector<vector<char>> removed; // removed[day][edge]\nvector<int> day_assign;\nvector<double> day_sum; // sum of importance per day\nvector<int> day_cnt;\nvector<double> sum_mid_x, sum_mid_y;\nvector<vector<int>> day_edges; // list of edges per day\n\nint vis[MAXN];\nint cur_mark = 0;\n\nbool isConnected(int d) {\n    cur_mark++;\n    queue<int> q;\n    q.push(0);\n    vis[0] = cur_mark;\n    int count = 1;\n    while (!q.empty()) {\n        int node = q.front(); q.pop();\n        for (auto [nbr, eidx] : adj[node]) {\n            if (removed[d][eidx]) continue;\n            if (vis[nbr] != cur_mark) {\n                vis[nbr] = cur_mark;\n                q.push(nbr);\n                count++;\n            }\n        }\n    }\n    return count == N;\n}\n\n// Compute number of ordered pairs (i,j) for which edge lies on the unique shortest path\nvoid computeUniquePairs() {\n    unique_pairs.assign(M, 0);\n    for (int s = 0; s < N; ++s) {\n        vector<ll> dist(N, INF);\n        vector<vector<pair<int, int>>> preds(N); // (predecessor, edge_idx)\n        vector<ll> numPaths(N, 0);\n        \n        dist[s] = 0;\n        numPaths[s] = 1;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.emplace(0, s);\n        \n        while (!pq.empty()) {\n            auto [d, node] = pq.top(); pq.pop();\n            if (d > dist[node]) continue;\n            for (auto [nbr, eidx] : adj[node]) {\n                ll nd = d + w[eidx];\n                if (nd < dist[nbr]) {\n                    dist[nbr] = nd;\n                    preds[nbr].clear();\n                    preds[nbr].emplace_back(node, eidx);\n                    numPaths[nbr] = numPaths[node];\n                    pq.emplace(nd, nbr);\n                } else if (nd == dist[nbr]) {\n                    preds[nbr].emplace_back(node, eidx);\n                    numPaths[nbr] += numPaths[node];\n                }\n            }\n        }\n        \n        // For nodes with unique shortest path from s, trace back and count edges\n        for (int t = 0; t < N; ++t) {\n            if (numPaths[t] == 1 && t != s) {\n                int cur = t;\n                while (cur != s) {\n                    // Since numPaths[t]==1, there is exactly one predecessor\n                    auto [prev, eidx] = preds[cur][0];\n                    unique_pairs[eidx]++;\n                    cur = prev;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> D >> K;\n    u.resize(M); v.resize(M); w.resize(M);\n    adj.resize(N);\n    vector<vector<int>> edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        edge_idx[u[i]][v[i]] = i;\n        edge_idx[v[i]][u[i]] = i;\n        adj[u[i]].emplace_back(v[i], i);\n        adj[v[i]].emplace_back(u[i], i);\n    }\n\n    vector<int> coord_x(N), coord_y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coord_x[i] >> coord_y[i];\n    }\n\n    mid_x.resize(M); mid_y.resize(M);\n    for (int i = 0; i < M; ++i) {\n        mid_x[i] = (coord_x[u[i]] + coord_x[v[i]]) * 0.5;\n        mid_y[i] = (coord_y[u[i]] + coord_y[v[i]]) * 0.5;\n    }\n\n    // Compute criticality based on unique shortest paths\n    computeUniquePairs();\n\n    // Compute importance = unique_pairs * sqrt(weight)\n    importance.resize(M);\n    for (int i = 0; i < M; ++i) {\n        importance[i] = unique_pairs[i] * sqrt(w[i]);\n    }\n\n    // Initialize day structures\n    day_assign.assign(M, -1);\n    day_sum.assign(D, 0.0);\n    day_cnt.assign(D, 0);\n    sum_mid_x.assign(D, 0.0);\n    sum_mid_y.assign(D, 0.0);\n    removed.assign(D, vector<char>(M, 0));\n    day_edges.resize(D);\n\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n    sort(order_edges.begin(), order_edges.end(),\n         [&](int a, int b) { return importance[a] > importance[b]; });\n\n    for (int e : order_edges) {\n        // Collect all days with free slots\n        vector<int> candidates;\n        for (int d = 0; d < D; ++d) {\n            if (day_cnt[d] < K) {\n                candidates.push_back(d);\n            }\n        }\n\n        // Among candidates, find those that keep connectivity\n        vector<int> connected_days;\n        for (int d : candidates) {\n            removed[d][e] = 1;\n            if (isConnected(d)) {\n                connected_days.push_back(d);\n            }\n            removed[d][e] = 0;\n        }\n\n        int best_day = -1;\n        double best_dist2 = -1.0;\n\n        if (!connected_days.empty()) {\n            // Among connected days, choose the one with smallest day_sum, then largest distance\n            double min_sum = 1e100;\n            for (int d : connected_days) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                }\n            }\n            vector<int> best_candidates;\n            for (int d : connected_days) {\n                if (day_sum[d] == min_sum) {\n                    best_candidates.push_back(d);\n                }\n            }\n            if (best_candidates.size() == 1) {\n                best_day = best_candidates[0];\n            } else {\n                // tie-break by distance\n                for (int d : best_candidates) {\n                    double dist2;\n                    if (day_cnt[d] == 0) {\n                        dist2 = 1e18;\n                    } else {\n                        double avg_x = sum_mid_x[d] / day_cnt[d];\n                        double avg_y = sum_mid_y[d] / day_cnt[d];\n                        double dx = mid_x[e] - avg_x;\n                        double dy = mid_y[e] - avg_y;\n                        dist2 = dx*dx + dy*dy;\n                    }\n                    if (best_day == -1 || dist2 > best_dist2) {\n                        best_dist2 = dist2;\n                        best_day = d;\n                    }\n                }\n            }\n        } else {\n            // No day keeps connectivity; fallback to day with smallest day_sum\n            double min_sum = 1e100;\n            for (int d : candidates) {\n                if (day_sum[d] < min_sum) {\n                    min_sum = day_sum[d];\n                    best_day = d;\n                }\n            }\n        }\n\n        // Assign edge to best_day\n        day_assign[e] = best_day;\n        day_sum[best_day] += importance[e];\n        day_cnt[best_day]++;\n        sum_mid_x[best_day] += mid_x[e];\n        sum_mid_y[best_day] += mid_y[e];\n        removed[best_day][e] = 1;\n        day_edges[best_day].push_back(e);\n    }\n\n    // Local search to improve schedule\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> day_dis(0, D-1);\n\n    for (int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        int d1 = day_dis(gen);\n        int d2 = day_dis(gen);\n        if (d1 == d2) continue;\n        if (day_edges[d1].empty() || day_edges[d2].empty()) continue;\n\n        // Pick random edges from each day\n        uniform_int_distribution<> e1_dis(0, day_edges[d1].size()-1);\n        uniform_int_distribution<> e2_dis(0, day_edges[d2].size()-1);\n        int idx1 = e1_dis(gen);\n        int idx2 = e2_dis(gen);\n        int e1 = day_edges[d1][idx1];\n        int e2 = day_edges[d2][idx2];\n\n        // Check if swapping would maintain connectivity\n        // Remove e1 from d1, add e2; remove e2 from d2, add e1\n        bool ok = true;\n\n        // Check d1\n        removed[d1][e1] = 0;\n        removed[d1][e2] = 1;\n        if (!isConnected(d1)) ok = false;\n        removed[d1][e1] = 1;\n        removed[d1][e2] = 0;\n\n        if (ok) {\n            // Check d2\n            removed[d2][e2] = 0;\n            removed[d2][e1] = 1;\n            if (!isConnected(d2)) ok = false;\n            removed[d2][e2] = 1;\n            removed[d2][e1] = 0;\n        }\n\n        if (!ok) continue;\n\n        // Compute new day_sum after swap\n        double new_sum_d1 = day_sum[d1] - importance[e1] + importance[e2];\n        double new_sum_d2 = day_sum[d2] - importance[e2] + importance[e1];\n        double old_max = max(day_sum[d1], day_sum[d2]);\n        double new_max = max(new_sum_d1, new_sum_d2);\n\n        // Accept if new max is smaller, or same max but sum of squares reduced\n        if (new_max < old_max || (new_max == old_max && \n            new_sum_d1*new_sum_d1 + new_sum_d2*new_sum_d2 < \n            day_sum[d1]*day_sum[d1] + day_sum[d2]*day_sum[d2])) {\n            // Perform swap\n            day_sum[d1] = new_sum_d1;\n            day_sum[d2] = new_sum_d2;\n            // Update removed arrays\n            removed[d1][e1] = 0;\n            removed[d1][e2] = 1;\n            removed[d2][e2] = 0;\n            removed[d2][e1] = 1;\n            // Update day_assign\n            day_assign[e1] = d2;\n            day_assign[e2] = d1;\n            // Update day_edges lists\n            day_edges[d1][idx1] = e2;\n            day_edges[d2][idx2] = e1;\n            // Update centroids (approximate)\n            sum_mid_x[d1] = sum_mid_x[d1] - mid_x[e1] + mid_x[e2];\n            sum_mid_y[d1] = sum_mid_y[d1] - mid_y[e1] + mid_y[e2];\n            sum_mid_x[d2] = sum_mid_x[d2] - mid_x[e2] + mid_x[e1];\n            sum_mid_y[d2] = sum_mid_y[d2] - mid_y[e2] + mid_y[e1];\n        }\n    }\n\n    // Output\n    for (int i = 0; i < M; ++i) {\n        cout << day_assign[i] + 1;\n        if (i < M - 1) cout << ' ';\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\n\n// generate minimal object from silhouette pair (simple edge cover)\nvector<array<int,3>> generate_object(const vector<string>& f, const vector<string>& r) {\n    vector<array<int,3>> cubes;\n    for (int z = 0; z < D; ++z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (f[z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (r[z][y] == '1') Y.push_back(y);\n        if (X.empty() || Y.empty()) continue;\n        if (X.size() <= Y.size()) {\n            for (size_t i = 0; i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            for (size_t i = X.size(); i < Y.size(); ++i) {\n                cubes.push_back({X[0], Y[i], z});\n            }\n        } else {\n            for (size_t i = 0; i < Y.size(); ++i) {\n                cubes.push_back({X[i], Y[i], z});\n            }\n            for (size_t i = Y.size(); i < X.size(); ++i) {\n                cubes.push_back({X[i], Y[0], z});\n            }\n        }\n    }\n    return cubes;\n}\n\n// canonical shape for a set of points\nvector<array<int,3>> canonical_shape(const vector<array<int,3>>& pts) {\n    // find min\n    array<int,3> min_pt = {D, D, D};\n    for (auto& p : pts) {\n        for (int i = 0; i < 3; ++i) min_pt[i] = min(min_pt[i], p[i]);\n    }\n    vector<array<int,3>> rel;\n    for (auto& p : pts) {\n        rel.push_back({p[0]-min_pt[0], p[1]-min_pt[1], p[2]-min_pt[2]});\n    }\n    // generate all rotations (24)\n    vector<array<array<int,3>,3>> rotations;\n    vector<int> axes = {0,1,2};\n    do {\n        int inversions = 0;\n        for (int i=0; i<3; ++i) for (int j=i+1; j<3; ++j) if (axes[i]>axes[j]) ++inversions;\n        int perm_sign = (inversions%2==0) ? 1 : -1;\n        for (int s0 : {-1,1}) {\n            for (int s1 : {-1,1}) {\n                int s2 = (perm_sign * s0 * s1 == 1) ? 1 : -1;\n                array<array<int,3>,3> mat{};\n                mat[0][axes[0]] = s0;\n                mat[1][axes[1]] = s1;\n                mat[2][axes[2]] = s2;\n                rotations.push_back(mat);\n            }\n        }\n    } while (next_permutation(axes.begin(), axes.end()));\n\n    vector<array<int,3>> best = rel;\n    sort(best.begin(), best.end());\n    for (const auto& rot : rotations) {\n        vector<array<int,3>> rotated;\n        for (auto& p : rel) {\n            array<int,3> np;\n            for (int i=0; i<3; ++i) {\n                np[i] = 0;\n                for (int j=0; j<3; ++j) np[i] += rot[i][j] * p[j];\n            }\n            rotated.push_back(np);\n        }\n        // normalize after rotation\n        array<int,3> min_rot = {D, D, D};\n        for (auto& p : rotated) {\n            for (int i=0; i<3; ++i) min_rot[i] = min(min_rot[i], p[i]);\n        }\n        vector<array<int,3>> norm;\n        for (auto& p : rotated) {\n            norm.push_back({p[0]-min_rot[0], p[1]-min_rot[1], p[2]-min_rot[2]});\n        }\n        sort(norm.begin(), norm.end());\n        if (norm < best) best = norm;\n    }\n    return best;\n}\n\n// generate all connected sets of given size from a set of cubes\nvector<vector<array<int,3>>> get_connected_sets(const vector<array<int,3>>& cubes, const vector<vector<vector<int>>>& idx, int size) {\n    int n = cubes.size();\n    set<set<array<int,3>>> result_set;\n    for (int i=0; i<n; ++i) {\n        vector<array<int,3>> current = {cubes[i]};\n        function<void(int)> dfs = [&](int depth) {\n            if (current.size() == size) {\n                set<array<int,3>> s(current.begin(), current.end());\n                result_set.insert(s);\n                return;\n            }\n            set<array<int,3>> neighbor_set;\n            for (auto& p : current) {\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                for (int d=0; d<6; ++d) {\n                    int nx = p[0]+dx[d], ny = p[1]+dy[d], nz = p[2]+dz[d];\n                    if (nx<0 || nx>=D || ny<0 || ny>=D || nz<0 || nz>=D) continue;\n                    int idx_n = idx[nx][ny][nz];\n                    if (idx_n == -1) continue;\n                    array<int,3> nb = {nx,ny,nz};\n                    bool in_current = false;\n                    for (auto& q : current) if (q == nb) { in_current = true; break; }\n                    if (!in_current) neighbor_set.insert(nb);\n                }\n            }\n            for (auto& nb : neighbor_set) {\n                current.push_back(nb);\n                dfs(depth+1);\n                current.pop_back();\n            }\n        };\n        dfs(0);\n    }\n    vector<vector<array<int,3>>> result;\n    for (auto& s : result_set) {\n        result.push_back(vector<array<int,3>>(s.begin(), s.end()));\n    }\n    return result;\n}\n\n// maximum matching for dominos using Hopcroft-Karp\nvector<pair<int,int>> max_matching(const vector<array<int,3>>& cubes, const vector<vector<vector<int>>>& idx) {\n    int V = cubes.size();\n    vector<int> L, R;\n    for (int i=0; i<V; ++i) {\n        auto& p = cubes[i];\n        if ((p[0]+p[1]+p[2]) % 2 == 0) L.push_back(i);\n        else R.push_back(i);\n    }\n    vector<int> posL(V, -1), posR(V, -1);\n    for (size_t i=0; i<L.size(); ++i) posL[L[i]] = i;\n    for (size_t i=0; i<R.size(); ++i) posR[R[i]] = i;\n\n    int nL = L.size(), nR = R.size();\n    vector<vector<int>> adj(nL);\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int i=0; i<nL; ++i) {\n        int u = L[i];\n        auto& p = cubes[u];\n        for (int d=0; d<6; ++d) {\n            int nx = p[0]+dx[d], ny = p[1]+dy[d], nz = p[2]+dz[d];\n            if (nx<0 || nx>=D || ny<0 || ny>=D || nz<0 || nz>=D) continue;\n            int v = idx[nx][ny][nz];\n            if (v == -1) continue;\n            if (posR[v] == -1) continue;\n            adj[i].push_back(posR[v]);\n        }\n    }\n\n    vector<int> pairU(nL, -1), pairV(nR, -1), dist(nL);\n    auto bfs = [&]() -> bool {\n        queue<int> q;\n        for (int u=0; u<nL; ++u) {\n            if (pairU[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = -1;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                int u2 = pairV[v];\n                if (u2 != -1 && dist[u2] == -1) {\n                    dist[u2] = dist[u] + 1;\n                    q.push(u2);\n                } else if (u2 == -1) {\n                    found = true;\n                }\n            }\n        }\n        return found;\n    };\n\n    function<bool(int)> dfs = [&](int u) -> bool {\n        for (int v : adj[u]) {\n            int u2 = pairV[v];\n            if (u2 == -1 || (dist[u2] == dist[u] + 1 && dfs(u2))) {\n                pairU[u] = v;\n                pairV[v] = u;\n                return true;\n            }\n        }\n        dist[u] = -1;\n        return false;\n    };\n\n    int matching = 0;\n    while (bfs()) {\n        for (int u=0; u<nL; ++u) {\n            if (pairU[u] == -1 && dfs(u)) ++matching;\n        }\n    }\n\n    vector<pair<int,int>> result;\n    for (int u=0; u<nL; ++u) {\n        if (pairU[u] != -1) {\n            result.push_back({L[u], R[pairU[u]]});\n        }\n    }\n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D;\n\n    // read silhouettes\n    vector<string> f0(D), r0(D), f1(D), r1(D);\n    for (int i = 0; i < D; ++i) cin >> f0[i];\n    for (int i = 0; i < D; ++i) cin >> r0[i];\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n\n    // minimal objects\n    auto cubes0 = generate_object(f0, r0);\n    auto cubes1 = generate_object(f1, r1);\n    int V0 = cubes0.size(), V1 = cubes1.size();\n\n    // map coordinates to indices for quick neighbor lookup\n    vector<vector<vector<int>>> idx0(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    vector<vector<vector<int>>> idx1(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    for (int i = 0; i < V0; ++i) {\n        auto& p = cubes0[i];\n        idx0[p[0]][p[1]][p[2]] = i;\n    }\n    for (int i = 0; i < V1; ++i) {\n        auto& p = cubes1[i];\n        idx1[p[0]][p[1]][p[2]] = i;\n    }\n\n    // used flags\n    vector<bool> used0(V0, false), used1(V1, false);\n\n    // Helper function to rebuild index for remaining cubes\n    auto rebuild_idx = [&](const vector<array<int,3>>& cubes, vector<vector<vector<int>>>& idx) {\n        idx.assign(D, vector<vector<int>>(D, vector<int>(D, -1)));\n        for (size_t i=0; i<cubes.size(); ++i) {\n            auto& p = cubes[i];\n            idx[p[0]][p[1]][p[2]] = i;\n        }\n    };\n\n    // Helper function to collect remaining cubes\n    auto get_remaining = [&](const vector<array<int,3>>& cubes, const vector<bool>& used) {\n        vector<array<int,3>> rem;\n        for (size_t i=0; i<cubes.size(); ++i) {\n            if (!used[i]) rem.push_back(cubes[i]);\n        }\n        return rem;\n    };\n\n    // Process sizes from 7 down to 3\n    vector<pair<vector<array<int,3>>, vector<array<int,3>>>> all_matches;\n    for (int sz = 7; sz >= 3; --sz) {\n        auto rem0 = get_remaining(cubes0, used0);\n        auto rem1 = get_remaining(cubes1, used1);\n        vector<vector<vector<int>>> rem_idx0(D, vector<vector<int>>(D, vector<int>(D, -1)));\n        vector<vector<vector<int>>> rem_idx1(D, vector<vector<int>>(D, vector<int>(D, -1)));\n        rebuild_idx(rem0, rem_idx0);\n        rebuild_idx(rem1, rem_idx1);\n        auto sets0 = get_connected_sets(rem0, rem_idx0, sz);\n        auto sets1 = get_connected_sets(rem1, rem_idx1, sz);\n        vector<vector<array<int,3>>> can0, can1;\n        for (auto& s : sets0) can0.push_back(canonical_shape(s));\n        for (auto& s : sets1) can1.push_back(canonical_shape(s));\n        map<vector<array<int,3>>, vector<int>> shape_to_idx1;\n        for (size_t i=0; i<can1.size(); ++i) {\n            shape_to_idx1[can1[i]].push_back(i);\n        }\n        for (size_t i=0; i<sets0.size(); ++i) {\n            auto& s = sets0[i];\n            bool ok = true;\n            for (auto& p : s) {\n                int orig_idx = idx0[p[0]][p[1]][p[2]];\n                if (used0[orig_idx]) { ok = false; break; }\n            }\n            if (!ok) continue;\n            auto& can = can0[i];\n            auto it = shape_to_idx1.find(can);\n            if (it == shape_to_idx1.end()) continue;\n            bool found = false;\n            for (int& j : it->second) {\n                auto& s1 = sets1[j];\n                bool ok1 = true;\n                for (auto& p : s1) {\n                    int orig_idx = idx1[p[0]][p[1]][p[2]];\n                    if (used1[orig_idx]) { ok1 = false; break; }\n                }\n                if (!ok1) continue;\n                all_matches.push_back({s, s1});\n                for (auto& p : s) used0[idx0[p[0]][p[1]][p[2]]] = true;\n                for (auto& p : s1) used1[idx1[p[0]][p[1]][p[2]]] = true;\n                found = true;\n                break;\n            }\n        }\n    }\n\n    // Dominos (size 2) using maximum matching\n    auto rem0 = get_remaining(cubes0, used0);\n    auto rem1 = get_remaining(cubes1, used1);\n    vector<vector<vector<int>>> rem_idx0(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    vector<vector<vector<int>>> rem_idx1(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    rebuild_idx(rem0, rem_idx0);\n    rebuild_idx(rem1, rem_idx1);\n\n    auto matching0 = max_matching(rem0, rem_idx0);\n    auto matching1 = max_matching(rem1, rem_idx1);\n    for (size_t i=0; i<min(matching0.size(), matching1.size()); ++i) {\n        auto& edge0 = matching0[i];\n        auto& edge1 = matching1[i];\n        vector<array<int,3>> s0 = {rem0[edge0.first], rem0[edge0.second]};\n        vector<array<int,3>> s1 = {rem1[edge1.first], rem1[edge1.second]};\n        all_matches.push_back({s0, s1});\n        for (auto& p : s0) used0[idx0[p[0]][p[1]][p[2]]] = true;\n        for (auto& p : s1) used1[idx1[p[0]][p[1]][p[2]]] = true;\n    }\n\n    // Assign block ids to matches\n    vector<int> block0(V0, 0), block1(V1, 0);\n    int block_counter = 0;\n    for (auto& mt : all_matches) {\n        int id = ++block_counter;\n        for (auto& p : mt.first) {\n            int idx = idx0[p[0]][p[1]][p[2]];\n            block0[idx] = id;\n        }\n        for (auto& p : mt.second) {\n            int idx = idx1[p[0]][p[1]][p[2]];\n            block1[idx] = id;\n        }\n    }\n\n    // Remaining cubes\n    vector<int> rem0_idx, rem1_idx;\n    for (int i=0; i<V0; ++i) if (!block0[i]) rem0_idx.push_back(i);\n    for (int i=0; i<V1; ++i) if (!block1[i]) rem1_idx.push_back(i);\n\n    // Shared unit blocks\n    int U = min(rem0_idx.size(), rem1_idx.size());\n    for (int i=0; i<U; ++i) {\n        int id = ++block_counter;\n        block0[rem0_idx[i]] = block1[rem1_idx[i]] = id;\n    }\n\n    // Single-use unit blocks in object0\n    for (int i=U; i<rem0_idx.size(); ++i) {\n        int id = ++block_counter;\n        block0[rem0_idx[i]] = id;\n    }\n\n    // Single-use unit blocks in object1\n    for (int i=U; i<rem1_idx.size(); ++i) {\n        int id = ++block_counter;\n        block1[rem1_idx[i]] = id;\n    }\n\n    int N = block_counter;\n\n    // build output arrays\n    vector<int> b0(D * D * D, 0), b1(D * D * D, 0);\n    for (int i=0; i<V0; ++i) {\n        auto& p = cubes0[i];\n        b0[p[0] * D * D + p[1] * D + p[2]] = block0[i];\n    }\n    for (int i=0; i<V1; ++i) {\n        auto& p = cubes1[i];\n        b1[p[0] * D * D + p[1] * D + p[2]] = block1[i];\n    }\n\n    // output\n    cout << N << '\\n';\n    for (size_t i=0; i<b0.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b0[i];\n    }\n    cout << '\\n';\n    for (size_t i=0; i<b1.size(); ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <map>\n#include <set>\n#include <random>\n#include <climits>\n#include <functional>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nconst double EPS = 1e-9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<vector<long long>> distV(N, vector<long long>(N, INF));\n    for (int i = 0; i < N; ++i) distV[i][i] = 0;\n\n    vector<tuple<int, int, long long>> edges(M);\n    map<pair<int, int>, int> edgeIndex;\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[j] = {u, v, w};\n        if (u > v) swap(u, v);\n        edgeIndex[{u, v}] = j;\n        distV[u][v] = min(distV[u][v], w);\n        distV[v][u] = min(distV[v][u], w);\n    }\n\n    vector<vector<int>> next(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (i != j && distV[i][j] < INF) {\n                next[i][j] = j;\n            }\n        }\n    }\n\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][k] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[k][j] == INF) continue;\n                if (distV[i][j] > distV[i][k] + distV[k][j]) {\n                    distV[i][j] = distV[i][k] + distV[k][j];\n                    next[i][j] = next[i][k];\n                }\n            }\n        }\n    }\n\n    vector<double> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    vector<vector<double>> distVtoR(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            distVtoR[i][k] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Precompute candidate vertices for each resident (60 nearest by Euclidean distance)\n    vector<vector<int>> candidateVertices(K);\n    for (int k = 0; k < K; ++k) {\n        vector<pair<double, int>> distances;\n        for (int i = 0; i < N; ++i) {\n            distances.push_back({distVtoR[i][k], i});\n        }\n        sort(distances.begin(), distances.end());\n        for (int t = 0; t < min(60, N); ++t) {\n            candidateVertices[k].push_back(distances[t].second);\n        }\n        // Ensure root is included\n        if (find(candidateVertices[k].begin(), candidateVertices[k].end(), 0) == candidateVertices[k].end()) {\n            candidateVertices[k].push_back(0);\n        }\n        // Remove duplicates\n        sort(candidateVertices[k].begin(), candidateVertices[k].end());\n        candidateVertices[k].erase(unique(candidateVertices[k].begin(), candidateVertices[k].end()), candidateVertices[k].end());\n    }\n\n    vector<multiset<double>> distSets(N);\n    vector<vector<int>> residentList(N);\n    vector<int> assign(K);\n    vector<int> P(N, 0);\n    long long sumSq = 0;\n\n    // Initial assignment to nearest vertex\n    for (int k = 0; k < K; ++k) {\n        int best = 0;\n        for (int i = 1; i < N; ++i) {\n            if (distVtoR[i][k] < distVtoR[best][k] - EPS) {\n                best = i;\n            }\n        }\n        assign[k] = best;\n        distSets[best].insert(distVtoR[best][k]);\n        residentList[best].push_back(k);\n    }\n\n    // Compute initial P[i]\n    for (int i = 0; i < N; ++i) {\n        if (!distSets[i].empty()) {\n            double maxDist = *distSets[i].rbegin();\n            P[i] = (int)ceil(maxDist);\n            if (P[i] > 5000) P[i] = 5000;\n        } else {\n            P[i] = 0;\n        }\n        sumSq += (long long)P[i] * P[i];\n    }\n\n    // Cache for actual connection cost\n    map<vector<int>, long long> costCache;\n\n    // Lambda to compute actual connection cost (sum of edge weights of Steiner tree)\n    auto computeActualConnectionCost = [&](const vector<int>& T) -> long long {\n        if (T.size() <= 1) return 0;\n        // Use sorted vector as cache key\n        vector<int> sortedT = T;\n        sort(sortedT.begin(), sortedT.end());\n        auto it = costCache.find(sortedT);\n        if (it != costCache.end()) return it->second;\n        \n        // Step 1: MST on metric closure\n        int n = sortedT.size();\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[sortedT[u]][sortedT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        // Step 2: Collect unique edges from paths of MST edges\n        set<pair<int, int>> edgeSet;\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u == -1) continue;\n            int from = sortedT[u], to = sortedT[v];\n            int cur = from;\n            while (cur != to) {\n                int nxt = next[cur][to];\n                int a = cur, b = nxt;\n                if (a > b) swap(a, b);\n                edgeSet.insert({a, b});\n                cur = nxt;\n            }\n        }\n        // Step 3: Sum weights of these edges\n        long long total = 0;\n        for (auto& e : edgeSet) {\n            int idx = edgeIndex[e];\n            total += get<2>(edges[idx]);\n        }\n        costCache[sortedT] = total;\n        return total;\n    };\n\n    // Build initial T (root + vertices with P>0)\n    vector<int> currentT;\n    currentT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            currentT.push_back(i);\n        }\n    }\n    long long currentActualCost = computeActualConnectionCost(currentT);\n    long long currentCost = sumSq + currentActualCost;\n\n    // Phase 1: General local search (25000 iterations)\n    int maxIter1 = 25000;\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> residentDist(0, K-1);\n\n    for (int iter = 0; iter < maxIter1; ++iter) {\n        int k = residentDist(gen);\n        int i = assign[k];\n        bool improved = false;\n\n        for (int j : candidateVertices[k]) {\n            if (j == i) continue;\n\n            int oldP_i = P[i], oldP_j = P[j];\n            double d_ik = distVtoR[i][k];\n            double d_jk = distVtoR[j][k];\n\n            // Update data structures\n            distSets[i].erase(distSets[i].find(d_ik));\n            distSets[j].insert(d_jk);\n            residentList[i].erase(remove(residentList[i].begin(), residentList[i].end(), k), residentList[i].end());\n            residentList[j].push_back(k);\n\n            // Compute new P values\n            int newP_i = 0, newP_j = 0;\n            if (!distSets[i].empty()) {\n                double maxDist = *distSets[i].rbegin();\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!distSets[j].empty()) {\n                double maxDist = *distSets[j].rbegin();\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n\n            // Feasibility check\n            if (newP_i > 5000 || newP_j > 5000) {\n                // Revert\n                distSets[i].insert(d_ik);\n                distSets[j].erase(distSets[j].find(d_jk));\n                residentList[i].push_back(k);\n                residentList[j].pop_back();\n                continue;\n            }\n\n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n\n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n\n            long long newActualCost;\n            long long newCost;\n            if (newT == currentT) {\n                newActualCost = currentActualCost;\n                newCost = newSumSq + newActualCost;\n            } else {\n                newActualCost = computeActualConnectionCost(newT);\n                newCost = newSumSq + newActualCost;\n            }\n\n            if (newCost < currentCost - EPS) {\n                // Accept move\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                assign[k] = j;\n                currentT = newT;\n                currentActualCost = newActualCost;\n                currentCost = newCost;\n                improved = true;\n                break;\n            } else {\n                // Revert\n                distSets[i].insert(d_ik);\n                distSets[j].erase(distSets[j].find(d_jk));\n                residentList[i].push_back(k);\n                residentList[j].pop_back();\n            }\n        }\n    }\n\n    // Phase 2: Focused on merging stations (15000 iterations)\n    int maxIter2 = 15000;\n    uniform_int_distribution<int> vertexDist(1, N-1);\n    uniform_real_distribution<double> tempDist(0.0, 1.0);\n    double temperature = 2000.0;\n    double coolingRate = 0.9997;\n\n    for (int iter = 0; iter < maxIter2; ++iter) {\n        temperature *= coolingRate;\n        \n        // Pick a random non-root vertex with residents\n        vector<int> candidates;\n        for (int i = 1; i < N; ++i) {\n            if (!residentList[i].empty()) {\n                candidates.push_back(i);\n            }\n        }\n        if (candidates.empty()) continue;\n        \n        int i = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(gen)];\n        \n        // Find all vertices j that can cover ALL residents of i within 5000 distance\n        vector<int> targetCandidates;\n        for (int j = 0; j < N; ++j) {\n            if (j == i) continue;\n            double maxDist = 0;\n            bool canCover = true;\n            for (int k : residentList[i]) {\n                double d = distVtoR[j][k];\n                if (d > 5000.0) {\n                    canCover = false;\n                    break;\n                }\n                if (d > maxDist) maxDist = d;\n            }\n            if (canCover) {\n                targetCandidates.push_back(j);\n            }\n        }\n        \n        if (targetCandidates.empty()) continue;\n        \n        // Try each candidate, starting with the one that minimizes newP_j\n        sort(targetCandidates.begin(), targetCandidates.end(), [&](int j1, int j2) {\n            double maxDist1 = 0, maxDist2 = 0;\n            for (int k : residentList[i]) {\n                double d1 = distVtoR[j1][k];\n                double d2 = distVtoR[j2][k];\n                if (d1 > maxDist1) maxDist1 = d1;\n                if (d2 > maxDist2) maxDist2 = d2;\n            }\n            return maxDist1 < maxDist2;\n        });\n        \n        for (int j : targetCandidates) {\n            int oldP_i = P[i], oldP_j = P[j];\n            \n            // Calculate new radii if we move all residents from i to j\n            double maxDist_j = distSets[j].empty() ? 0 : *distSets[j].rbegin();\n            for (int k : residentList[i]) {\n                double d = distVtoR[j][k];\n                if (d > maxDist_j) maxDist_j = d;\n            }\n            int newP_i = 0;\n            int newP_j = (int)ceil(maxDist_j);\n            if (newP_j > 5000) continue; // Should not happen due to canCover check\n            \n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n            \n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n            \n            long long newActualCost = computeActualConnectionCost(newT);\n            long long newCost = newSumSq + newActualCost;\n            \n            // Simulated annealing acceptance\n            bool accept = false;\n            if (newCost < currentCost - EPS) {\n                accept = true;\n            } else if (temperature > 0.1) {\n                double delta = newCost - currentCost;\n                double prob = exp(-delta / temperature);\n                if (tempDist(gen) < prob) {\n                    accept = true;\n                }\n            }\n            \n            if (accept) {\n                // Execute the merge\n                for (int k : residentList[i]) {\n                    distSets[i].erase(distSets[i].find(distVtoR[i][k]));\n                    distSets[j].insert(distVtoR[j][k]);\n                    assign[k] = j;\n                }\n                residentList[j].insert(residentList[j].end(), residentList[i].begin(), residentList[i].end());\n                residentList[i].clear();\n                \n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                currentT = newT;\n                currentActualCost = newActualCost;\n                currentCost = newCost;\n                break;\n            }\n        }\n    }\n\n    // Phase 3: Final cleanup - try to merge vertices with few residents (8000 iterations)\n    int maxIter3 = 8000;\n    for (int iter = 0; iter < maxIter3; ++iter) {\n        // Find vertex with fewest residents (excluding root)\n        int minResidents = INT_MAX;\n        int bestI = -1;\n        for (int i = 1; i < N; ++i) {\n            if (!residentList[i].empty() && residentList[i].size() < minResidents) {\n                minResidents = residentList[i].size();\n                bestI = i;\n            }\n        }\n        if (bestI == -1) break;\n        \n        // Find best target for this vertex (can cover all residents, minimizes increase in cost)\n        int bestJ = -1;\n        long long bestDeltaCost = LLONG_MAX;\n        \n        for (int j = 0; j < N; ++j) {\n            if (j == bestI) continue;\n            // Check if j can cover all residents of bestI within 5000\n            bool canCover = true;\n            double maxDist = 0;\n            for (int k : residentList[bestI]) {\n                double d = distVtoR[j][k];\n                if (d > 5000.0) {\n                    canCover = false;\n                    break;\n                }\n                if (d > maxDist) maxDist = d;\n            }\n            if (!canCover) continue;\n            \n            int oldP_bestI = P[bestI], oldP_j = P[j];\n            double maxDist_j = distSets[j].empty() ? 0 : *distSets[j].rbegin();\n            if (maxDist > maxDist_j) maxDist_j = maxDist;\n            int newP_bestI = 0;\n            int newP_j = (int)ceil(maxDist_j);\n            if (newP_j > 5000) continue;\n            \n            long long newSumSq = sumSq - (long long)oldP_bestI*oldP_bestI - (long long)oldP_j*oldP_j\n                               + (long long)newP_bestI*newP_bestI + (long long)newP_j*newP_j;\n            \n            vector<int> newT = currentT;\n            if (bestI != 0 && oldP_bestI > 0 && newP_bestI == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), bestI), newT.end());\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n            \n            long long newActualCost = computeActualConnectionCost(newT);\n            long long newCost = newSumSq + newActualCost;\n            long long deltaCost = newCost - currentCost;\n            \n            if (deltaCost < bestDeltaCost) {\n                bestDeltaCost = deltaCost;\n                bestJ = j;\n            }\n        }\n        \n        if (bestJ != -1 && bestDeltaCost < 0) {\n            // Execute the merge\n            int oldP_bestI = P[bestI], oldP_j = P[bestJ];\n            double maxDist_j = distSets[bestJ].empty() ? 0 : *distSets[bestJ].rbegin();\n            for (int k : residentList[bestI]) {\n                double d = distVtoR[bestJ][k];\n                if (d > maxDist_j) maxDist_j = d;\n            }\n            int newP_bestI = 0;\n            int newP_j = (int)ceil(maxDist_j);\n            \n            for (int k : residentList[bestI]) {\n                distSets[bestI].erase(distSets[bestI].find(distVtoR[bestI][k]));\n                distSets[bestJ].insert(distVtoR[bestJ][k]);\n                assign[k] = bestJ;\n            }\n            residentList[bestJ].insert(residentList[bestJ].end(), residentList[bestI].begin(), residentList[bestI].end());\n            residentList[bestI].clear();\n            \n            long long newSumSq = sumSq - (long long)oldP_bestI*oldP_bestI - (long long)oldP_j*oldP_j\n                               + (long long)newP_bestI*newP_bestI + (long long)newP_j*newP_j;\n            \n            vector<int> newT = currentT;\n            if (bestI != 0 && oldP_bestI > 0 && newP_bestI == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), bestI), newT.end());\n            }\n            if (bestJ != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(bestJ);\n            }\n            \n            sumSq = newSumSq;\n            P[bestI] = newP_bestI;\n            P[bestJ] = newP_j;\n            currentT = newT;\n            currentActualCost = computeActualConnectionCost(currentT);\n            currentCost = sumSq + currentActualCost;\n        }\n    }\n\n    // Phase 4: Safe resident swaps (3000 iterations)\n    int maxIter4 = 3000;\n    uniform_int_distribution<int> residentDist2(0, K-1);\n    for (int iter = 0; iter < maxIter4; ++iter) {\n        int k = residentDist2(gen);\n        int i = assign[k];\n        \n        // Try swapping with another resident in a different vertex\n        for (int j : candidateVertices[k]) {\n            if (j == i || residentList[j].empty()) continue;\n            \n            // Pick a random resident from j\n            int l = residentList[j][uniform_int_distribution<int>(0, residentList[j].size()-1)(gen)];\n            \n            // Check if swap is feasible: both vertices can cover the swapped residents\n            if (distVtoR[j][k] > 5000.0 || distVtoR[i][l] > 5000.0) continue;\n            \n            // Try swapping k and l\n            int oldP_i = P[i], oldP_j = P[j];\n            \n            // Remove k from i, l from j\n            distSets[i].erase(distSets[i].find(distVtoR[i][k]));\n            distSets[j].erase(distSets[j].find(distVtoR[j][l]));\n            residentList[i].erase(remove(residentList[i].begin(), residentList[i].end(), k), residentList[i].end());\n            residentList[j].erase(remove(residentList[j].begin(), residentList[j].end(), l), residentList[j].end());\n            \n            // Add k to j, l to i\n            distSets[j].insert(distVtoR[j][k]);\n            distSets[i].insert(distVtoR[i][l]);\n            residentList[j].push_back(k);\n            residentList[i].push_back(l);\n            \n            // Compute new P values\n            int newP_i = 0, newP_j = 0;\n            if (!distSets[i].empty()) {\n                double maxDist = *distSets[i].rbegin();\n                newP_i = (int)ceil(maxDist);\n                if (newP_i > 5000) newP_i = 5000;\n            }\n            if (!distSets[j].empty()) {\n                double maxDist = *distSets[j].rbegin();\n                newP_j = (int)ceil(maxDist);\n                if (newP_j > 5000) newP_j = 5000;\n            }\n            \n            // Feasibility check\n            if (newP_i > 5000 || newP_j > 5000) {\n                // Revert\n                distSets[i].erase(distSets[i].find(distVtoR[i][l]));\n                distSets[j].erase(distSets[j].find(distVtoR[j][k]));\n                residentList[i].pop_back();\n                residentList[j].pop_back();\n                distSets[i].insert(distVtoR[i][k]);\n                distSets[j].insert(distVtoR[j][l]);\n                residentList[i].push_back(k);\n                residentList[j].push_back(l);\n                continue;\n            }\n            \n            // Additional coverage check: ensure swapped residents are covered\n            if (distVtoR[j][k] > newP_j || distVtoR[i][l] > newP_i) {\n                // Revert\n                distSets[i].erase(distSets[i].find(distVtoR[i][l]));\n                distSets[j].erase(distSets[j].find(distVtoR[j][k]));\n                residentList[i].pop_back();\n                residentList[j].pop_back();\n                distSets[i].insert(distVtoR[i][k]);\n                distSets[j].insert(distVtoR[j][l]);\n                residentList[i].push_back(k);\n                residentList[j].push_back(l);\n                continue;\n            }\n            \n            long long newSumSq = sumSq - (long long)oldP_i*oldP_i - (long long)oldP_j*oldP_j\n                               + (long long)newP_i*newP_i + (long long)newP_j*newP_j;\n            \n            vector<int> newT = currentT;\n            if (i != 0 && oldP_i > 0 && newP_i == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), i), newT.end());\n            }\n            if (j != 0 && oldP_j > 0 && newP_j == 0) {\n                newT.erase(remove(newT.begin(), newT.end(), j), newT.end());\n            }\n            if (i != 0 && oldP_i == 0 && newP_i > 0) {\n                newT.push_back(i);\n            }\n            if (j != 0 && oldP_j == 0 && newP_j > 0) {\n                newT.push_back(j);\n            }\n            \n            long long newActualCost;\n            long long newCost;\n            if (newT == currentT) {\n                newActualCost = currentActualCost;\n                newCost = newSumSq + newActualCost;\n            } else {\n                newActualCost = computeActualConnectionCost(newT);\n                newCost = newSumSq + newActualCost;\n            }\n            \n            if (newCost < currentCost - EPS) {\n                // Accept swap\n                sumSq = newSumSq;\n                P[i] = newP_i;\n                P[j] = newP_j;\n                assign[k] = j;\n                assign[l] = i;\n                currentT = newT;\n                currentActualCost = newActualCost;\n                currentCost = newCost;\n                break;\n            } else {\n                // Revert\n                distSets[i].erase(distSets[i].find(distVtoR[i][l]));\n                distSets[j].erase(distSets[j].find(distVtoR[j][k]));\n                residentList[i].pop_back();\n                residentList[j].pop_back();\n                distSets[i].insert(distVtoR[i][k]);\n                distSets[j].insert(distVtoR[j][l]);\n                residentList[i].push_back(k);\n                residentList[j].push_back(l);\n            }\n        }\n    }\n\n    vector<int> finalT;\n    finalT.push_back(0);\n    for (int i = 1; i < N; ++i) {\n        if (P[i] > 0) {\n            finalT.push_back(i);\n        }\n    }\n\n    // Build final edge set\n    set<int> onEdges;\n    auto addPath = [&](int u, int v) {\n        while (u != v) {\n            int nxt = next[u][v];\n            int a = u, b = nxt;\n            if (a > b) swap(a, b);\n            onEdges.insert(edgeIndex[{a, b}]);\n            u = nxt;\n        }\n    };\n\n    int n = finalT.size();\n    if (n > 1) {\n        // Compute MST on metric closure of finalT\n        vector<bool> inMST(n, false);\n        vector<long long> minDist(n, INF);\n        vector<int> parent(n, -1);\n        minDist[0] = 0;\n        for (int iter = 0; iter < n; ++iter) {\n            int u = -1;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v] && (u == -1 || minDist[v] < minDist[u])) {\n                    u = v;\n                }\n            }\n            inMST[u] = true;\n            for (int v = 0; v < n; ++v) {\n                if (!inMST[v]) {\n                    long long d = distV[finalT[u]][finalT[v]];\n                    if (d < minDist[v]) {\n                        minDist[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        for (int v = 1; v < n; ++v) {\n            int u = parent[v];\n            if (u != -1) {\n                addPath(finalT[u], finalT[v]);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << P[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    for (int j = 0; j < M; ++j) {\n        cout << (onEdges.count(j) ? 1 : 0);\n        if (j < M-1) cout << \" \";\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint to_index(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\npair<int, int> to_coord(int idx) {\n    int x = 0;\n    while (idx >= x + 1) {\n        idx -= (x + 1);\n        x++;\n    }\n    return {x, idx};\n}\n\nint main() {\n    // Read input\n    vector<vector<int>> ball(N);\n    for (int x = 0; x < N; ++x) {\n        ball[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) {\n            cin >> ball[x][y];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n\n    // Process nodes from bottom to top (decreasing x)\n    for (int x = N - 1; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cur_x = x;\n            int cur_y = y;\n            int cur_val = ball[cur_x][cur_y];\n\n            // Sift down until heap property satisfied\n            while (cur_x < N - 1) {\n                int left = ball[cur_x + 1][cur_y];\n                int right = ball[cur_x + 1][cur_y + 1];\n                int smaller_child = min(left, right);\n                if (cur_val <= smaller_child) break;\n\n                // Determine which child to swap with\n                int swap_y;\n                if (left < right) {\n                    swap_y = cur_y;\n                } else {\n                    swap_y = cur_y + 1;\n                }\n\n                // Perform the swap\n                swaps.emplace_back(cur_x, cur_y, cur_x + 1, swap_y);\n                swap(ball[cur_x][cur_y], ball[cur_x + 1][swap_y]);\n\n                // Move down to the swapped child position\n                cur_x = cur_x + 1;\n                cur_y = swap_y;\n                cur_val = ball[cur_x][cur_y];\n            }\n        }\n    }\n\n    // Output\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cstring>\n#include <climits>\nusing namespace std;\n\nint main() {\n    int temp_D, N;\n    cin >> temp_D >> N;\n    const int D = 9;\n    const int entrance_i = 0, entrance_j = 4;\n\n    bool obstacle[D][D] = {false};\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n\n    bool occupied[D][D] = {false};\n    vector<pair<int, int>> placement_order;\n\n    for (int d = 0; d < M; ++d) {\n        int t;\n        cin >> t; // label not used in this placement strategy\n\n        // BFS to find distances from entrance through empty squares\n        int dist[D][D];\n        memset(dist, -1, sizeof(dist));\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            const int di[4] = {1, -1, 0, 0};\n            const int dj[4] = {0, 0, 1, -1};\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D &&\n                    !obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n\n        // Choose the empty square with maximum distance (farthest from entrance)\n        int best_dist = -1, best_i = -1, best_j = -1;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == entrance_i && j == entrance_j) continue;\n                if (dist[i][j] != -1) {\n                    if (dist[i][j] > best_dist || \n                        (dist[i][j] == best_dist && (i < best_i || (i == best_i && j < best_j)))) {\n                        best_dist = dist[i][j];\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n\n        // According to problem, there must be at least one reachable empty square\n        if (best_i == -1) {\n            // Fallback: choose any non-occupied, non-obstacle square (should not happen)\n            for (int i = 0; i < D; ++i) {\n                for (int j = 0; j < D; ++j) {\n                    if (i == entrance_i && j == entrance_j) continue;\n                    if (!obstacle[i][j] && !occupied[i][j]) {\n                        best_i = i;\n                        best_j = j;\n                        break;\n                    }\n                }\n                if (best_i != -1) break;\n            }\n        }\n\n        cout << best_i << \" \" << best_j << endl;\n\n        occupied[best_i][best_j] = true;\n        placement_order.push_back({best_i, best_j});\n    }\n\n    // Removal phase: remove in reverse order of placement (closest first)\n    for (int i = placement_order.size() - 1; i >= 0; --i) {\n        auto [ri, rj] = placement_order[i];\n        cout << ri << \" \" << rj << endl;\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    cin >> n >> m;\n    \n    vector<vector<int>> grid(n, vector<int>(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    // Output the original grid unchanged\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << grid[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string s;\n    cin >> s;\n    queries_used++;\n    return s[0];\n}\n\nchar compare(int i, int j) {\n    return query({i}, {j});\n}\n\n// Greedy bucket assignment using direct comparisons of bucket sums\nvoid greedy_bucket(vector<int>& ans) {\n    vector<vector<int>> buckets(D);\n    for (int i = 0; i < N; ++i) {\n        // Find a bucket to put this item\n        int best = -1;\n        // First, check if there is any empty bucket\n        for (int j = 0; j < D; ++j) {\n            if (buckets[j].empty()) {\n                best = j;\n                break;\n            }\n        }\n        if (best == -1) {\n            // All buckets are non-empty, find the lightest by comparing\n            best = 0;\n            for (int j = 1; j < D; ++j) {\n                if (queries_used >= Q) break; // cannot compare further\n                vector<int> L = buckets[best];\n                vector<int> R = buckets[j];\n                char res = query(L, R);\n                if (res == '>') {\n                    best = j;\n                }\n                // if '=', keep current best\n            }\n        }\n        buckets[best].push_back(i);\n        ans[i] = best;\n    }\n}\n\n// Sorting and snake assignment\nvoid sorting_snake(vector<int>& ans) {\n    vector<int> items;  // sorted order as much as we know\n    // Insert items one by one using binary search\n    for (int i = 0; i < N; ++i) {\n        if (queries_used >= Q) {\n            items.push_back(i);\n            continue;\n        }\n        int left = 0, right = items.size();\n        while (left < right && queries_used < Q) {\n            int mid = (left + right) / 2;\n            char res = compare(i, items[mid]);\n            if (res == '<') {\n                right = mid;\n            } else {\n                left = mid + 1;\n            }\n        }\n        items.insert(items.begin() + left, i);\n    }\n\n    // Bubble sort to improve order with remaining queries\n    bool swapped = true;\n    while (queries_used < Q && swapped) {\n        swapped = false;\n        for (size_t i = 0; i + 1 < items.size(); ++i) {\n            if (queries_used >= Q) break;\n            char res = compare(items[i], items[i+1]);\n            if (res == '>') {\n                swap(items[i], items[i+1]);\n                swapped = true;\n            }\n        }\n    }\n\n    // Snake assignment\n    for (int i = 0; i < N; ++i) {\n        int item = items[i];\n        int bucket = i % D;\n        if ((i / D) % 2 == 1) {\n            bucket = D - 1 - bucket;\n        }\n        ans[item] = bucket;\n    }\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    vector<int> ans(N, -1);\n\n    // Decide which strategy to use based on available queries\n    int max_comparisons_needed = N * (D - 1);\n    if (Q >= max_comparisons_needed) {\n        greedy_bucket(ans);\n    } else {\n        sorting_snake(ans);\n    }\n\n    // Use any remaining queries as dummy comparisons\n    while (queries_used < Q) {\n        compare(0, 1);  // always valid as N >= 2\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    int h = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    // greedy policy: returns total cost from start_v to n using the heuristic:\n    // move suffix above the next box to the empty stack if top > max_top, else to stack with largest top.\n    auto greedy_policy = [&](vector<vector<int>> st, int start_v) -> int {\n        int cost = 0;\n        for (int v = start_v; v <= n; ++v) {\n            // locate v\n            int s = -1, pos = -1;\n            for (int i = 0; i < m; ++i) {\n                for (int j = 0; j < (int)st[i].size(); ++j) {\n                    if (st[i][j] == v) {\n                        s = i;\n                        pos = j;\n                        break;\n                    }\n                }\n                if (s != -1) break;\n            }\n\n            if (pos == (int)st[s].size() - 1) {   // already on top\n                st[s].pop_back();\n                continue;\n            }\n\n            int k = (int)st[s].size() - pos - 1;  // boxes above v\n            cost += k + 1;\n\n            int T = st[s].back();                 // top of the group to be moved\n            int best_d = -1;\n            bool found_empty = false;\n            int empty_d = -1;\n            int best_top = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if (st[i].empty()) {\n                    found_empty = true;\n                    if (empty_d == -1) empty_d = i;\n                } else {\n                    int top = st[i].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        best_d = i;\n                    }\n                }\n            }\n\n            if (found_empty) {\n                if (best_d == -1 || T > best_top) {\n                    best_d = empty_d;\n                }\n            } // else best_d already holds the stack with largest top\n\n            // move the suffix\n            vector<int> suffix(st[s].begin() + pos + 1, st[s].end());\n            st[s].erase(st[s].begin() + pos + 1, st[s].end());\n            st[best_d].insert(st[best_d].end(), suffix.begin(), suffix.end());\n\n            // remove v (now on top)\n            st[s].pop_back();\n        }\n        return cost;\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        // locate v\n        int s = -1, pos = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == v) {\n                    s = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (pos == (int)stacks[s].size() - 1) {\n            cout << v << \" 0\\n\";\n            stacks[s].pop_back();\n            continue;\n        }\n\n        int k_above = (int)stacks[s].size() - pos - 1;\n        int base_cost = k_above + 1;\n\n        int best_d = -1;\n        int best_total = 1e9;\n\n        for (int d = 0; d < m; ++d) {\n            if (d == s) continue;\n\n            auto st2 = stacks;\n            // move suffix from s to d\n            vector<int> suffix(st2[s].begin() + pos + 1, st2[s].end());\n            st2[s].erase(st2[s].begin() + pos + 1, st2[s].end());\n            st2[d].insert(st2[d].end(), suffix.begin(), suffix.end());\n            // remove v\n            st2[s].pop_back();\n\n            int future = greedy_policy(st2, v + 1);\n            int total = base_cost + future;\n\n            if (total < best_total) {\n                best_total = total;\n                best_d = d;\n            }\n        }\n\n        // execute the chosen move\n        int w = stacks[s][pos + 1];\n        cout << w << \" \" << best_d + 1 << \"\\n\";\n\n        vector<int> suffix(stacks[s].begin() + pos + 1, stacks[s].end());\n        stacks[s].erase(stacks[s].begin() + pos + 1, stacks[s].end());\n        stacks[best_d].insert(stacks[best_d].end(), suffix.begin(), suffix.end());\n\n        // now v is on top, remove it\n        cout << v << \" 0\\n\";\n        stacks[s].pop_back();\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ---------- Dinic max flow ----------\nstruct EdgeFlow {\n    int to, rev, cap, flow;\n};\n\nclass Dinic {\npublic:\n    vector<vector<EdgeFlow>> g;\n    vector<int> level, iter;\n    Dinic(int n) : g(n), level(n), iter(n) {}\n    void add_edge(int from, int to, int cap) {\n        g[from].push_back({to, (int)g[to].size(), cap, 0});\n        g[to].push_back({from, (int)g[from].size()-1, 0, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto &e : g[v]) {\n                if (e.cap > e.flow && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    int dfs(int v, int t, int f) {\n        if (v == t) return f;\n        for (int &i = iter[v]; i < (int)g[v].size(); ++i) {\n            EdgeFlow &e = g[v][i];\n            if (e.cap > e.flow && level[v] < level[e.to]) {\n                int d = dfs(e.to, t, min(f, e.cap - e.flow));\n                if (d > 0) {\n                    e.flow += d;\n                    g[e.to][e.rev].flow -= d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    int max_flow(int s, int t) {\n        int flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            int f;\n            while ((f = dfs(s, t, 1e9)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\n// ---------- Global variables ----------\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\n\nconst int dx[] = {1, -1, 0, 0};\nconst int dy[] = {0, 0, 1, -1};\nconst char dir_char[] = {'D', 'U', 'R', 'L'};\nconst char opp_char[] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int i1, int j1, int i2, int j2) {\n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    if (i1 == i2) {\n        if (j2 > j1) return v[i1][j1] == '0';\n        else return v[i1][j2] == '0';\n    } else {\n        if (i2 > i1) return h[i1][j1] == '0';\n        else return h[i2][j1] == '0';\n    }\n}\n\n// ---------- DFS for base route ----------\nvector<vector<bool>> visited;\nstring dfs_route;\nvoid dfs(int i, int j) {\n    for (int dir = 0; dir < 4; ++dir) {\n        int ni = i + dx[dir], nj = j + dy[dir];\n        if (can_move(i, j, ni, nj) && !visited[ni][nj]) {\n            visited[ni][nj] = true;\n            dfs_route += dir_char[dir];\n            dfs(ni, nj);\n            dfs_route += opp_char[dir];\n        }\n    }\n}\n\nstring reverse_str(const string& s) {\n    string r = s;\n    reverse(r.begin(), r.end());\n    for (char& c : r) {\n        if (c == 'D') c = 'U';\n        else if (c == 'U') c = 'D';\n        else if (c == 'R') c = 'L';\n        else c = 'R';\n    }\n    return r;\n}\n\n// ---------- Shortest paths from root (BFS) ----------\nvoid bfs_root(vector<int>& dist, vector<int>& next_step) {\n    dist.assign(N * N, -1);\n    next_step.assign(N * N, -1);\n    queue<int> q;\n    q.push(0);\n    dist[0] = 0;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        int ui = u / N, uj = u % N;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vi = ui + dx[dir], vj = uj + dy[dir];\n            if (can_move(ui, uj, vi, vj)) {\n                int v = vi * N + vj;\n                if (dist[v] == -1) {\n                    dist[v] = dist[u] + 1;\n                    next_step[v] = u;\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\n// ---------- Simulate a route and return last_clean array and final position ----------\npair<vector<int>, int> simulate(const string& route) {\n    vector<int> last_clean(N * N, -1);\n    int cur = 0;\n    last_clean[0] = 0; // start at root at time 0\n    int time = 0;\n    for (char c : route) {\n        int dir;\n        if (c == 'D') dir = 0;\n        else if (c == 'U') dir = 1;\n        else if (c == 'R') dir = 2;\n        else dir = 3;\n        int ni = cur / N + dx[dir];\n        int nj = cur % N + dy[dir];\n        int nxt = ni * N + nj;\n        time++;\n        last_clean[nxt] = time;\n        cur = nxt;\n    }\n    return {last_clean, cur};\n}\n\n// ---------- Greedy simulation solution ----------\nstring greedy_simulation_solution() {\n    // Precompute distances to root and next step on shortest path\n    vector<int> dist_root, next_step_to_root;\n    bfs_root(dist_root, next_step_to_root);\n\n    // Generate base DFS route that visits all cells and returns to root\n    visited.assign(N, vector<bool>(N, false));\n    visited[0][0] = true;\n    dfs_route.clear();\n    dfs(0, 0);\n    string route = dfs_route;\n    int base_len = route.length();\n\n    // Simulate the base route to get last_clean and current position\n    auto [last_clean, cur] = simulate(route);\n    int time = base_len; // number of moves done so far\n\n    int remaining = 100000 - base_len;\n    const int total_D = accumulate(d.begin(), d.end(), 0, [](int sum, const vector<int>& row) {\n        return sum + accumulate(row.begin(), row.end(), 0);\n    });\n\n    // Continue with greedy moves until we run out of moves\n    while (remaining > 0) {\n        // If we must return to root now (remaining moves equal distance to root)\n        if (remaining == dist_root[cur]) {\n            // Move along shortest path to root\n            int nxt = next_step_to_root[cur];\n            int ui = cur / N, uj = cur % N;\n            int vi = nxt / N, vj = nxt % N;\n            char move;\n            if (vi == ui + 1) move = 'D';\n            else if (vi == ui - 1) move = 'U';\n            else if (vj == uj + 1) move = 'R';\n            else move = 'L';\n            route += move;\n            time++;\n            last_clean[nxt] = time;\n            cur = nxt;\n            remaining--;\n            continue;\n        }\n\n        // Otherwise, choose the neighbor that maximizes (a + d)\n        int ui = cur / N, uj = cur % N;\n        int best_nb = -1;\n        double best_val = -1e18;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vi = ui + dx[dir], vj = uj + dy[dir];\n            if (!can_move(ui, uj, vi, vj)) continue;\n            int nb = vi * N + vj;\n            double val;\n            if (last_clean[nb] == -1) {\n                // never cleaned: a = d[nb] * time, so a+d = d[nb]*(time+1)\n                val = d[vi][vj] * (time + 1);\n            } else {\n                val = d[vi][vj] * (time - last_clean[nb] + 1);\n            }\n            if (val > best_val) {\n                best_val = val;\n                best_nb = nb;\n            }\n        }\n        // Move to best_nb\n        int vi = best_nb / N, vj = best_nb % N;\n        char move;\n        if (vi == ui + 1) move = 'D';\n        else if (vi == ui - 1) move = 'U';\n        else if (vj == uj + 1) move = 'R';\n        else move = 'L';\n        route += move;\n        time++;\n        last_clean[best_nb] = time;\n        cur = best_nb;\n        remaining--;\n    }\n\n    return route;\n}\n\n// ---------- Flow\u2011based Eulerian solution ----------\nstring flow_solution() {\n    int V = N * N;\n    vector<double> sqrt_d(V);\n    double total_sqrt = 0.0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            sqrt_d[id] = sqrt(d[i][j]);\n            total_sqrt += sqrt_d[id];\n        }\n\n    // Build adjacency list for the grid graph\n    vector<vector<pair<int, char>>> graph(V);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (can_move(i, j, ni, nj)) {\n                    int v = ni * N + nj;\n                    graph[u].emplace_back(v, dir_char[dir]);\n                }\n            }\n        }\n    }\n\n    // BFS to get a spanning tree (rooted at 0)\n    vector<int> parent(V, -1);\n    vector<char> pdir(V);\n    queue<int> q;\n    q.push(0);\n    parent[0] = -2;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (auto [v, dir] : graph[u]) {\n            if (parent[v] == -1) {\n                parent[v] = u;\n                pdir[v] = dir;\n                q.push(v);\n            }\n        }\n    }\n\n    // Tree edges (undirected) and tree degree per vertex\n    set<pair<int, int>> tree_edges;\n    vector<int> tree_degree(V, 0);\n    for (int v = 1; v < V; ++v) {\n        int u = parent[v];\n        if (u >= 0) {\n            tree_edges.insert({min(u, v), max(u, v)});\n            tree_degree[u]++;\n            tree_degree[v]++;\n        }\n    }\n\n    // Determine bipartition (black = (i+j)%2 == 0)\n    vector<int> color(V);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            color[i * N + j] = (i + j) & 1;\n\n    vector<int> black, white;\n    vector<int> black_idx(V, -1), white_idx(V, -1);\n    for (int i = 0; i < V; ++i) {\n        if (color[i] == 0) {\n            black_idx[i] = black.size();\n            black.push_back(i);\n        } else {\n            white_idx[i] = white.size();\n            white.push_back(i);\n        }\n    }\n    int B = black.size(), W = white.size();\n    int S = B + W, T = B + W + 1;\n\n    // Adjust target frequencies n_target to satisfy tree_degree constraints and total moves limit\n    vector<int> n_target(V);\n    double scale = 1.0;\n    int total;\n    const int MAX_MOVES = 100000;\n    for (int iter = 0; iter < 20; ++iter) {\n        for (int i = 0; i < V; ++i)\n            n_target[i] = max(1, (int)round(sqrt_d[i] * scale));\n        // ensure each vertex's degree (2*n_target) is at least tree_degree\n        for (int i = 0; i < V; ++i) {\n            while (2 * n_target[i] < tree_degree[i])\n                n_target[i]++;\n        }\n        total = accumulate(n_target.begin(), n_target.end(), 0);\n        if (total <= MAX_MOVES) break;\n        scale *= 0.9; // reduce scale\n    }\n    if (total > MAX_MOVES) return \"\"; // still too large, fallback\n\n    // Compute lower bounds (1 on tree edges) and per-vertex sum of lower bounds\n    vector<int> L(V, 0);\n    for (auto [u, v] : tree_edges) {\n        L[u] += 1;\n        L[v] += 1;\n    }\n\n    // Supplies (black) and demands (white) after subtracting lower bounds\n    vector<int> supply(B, 0), demand(W, 0);\n    int total_supply = 0;\n    for (int i = 0; i < B; ++i) {\n        int v = black[i];\n        supply[i] = 2 * n_target[v] - L[v];\n        if (supply[i] < 0) return \"\";\n        total_supply += supply[i];\n    }\n    for (int i = 0; i < W; ++i) {\n        int v = white[i];\n        demand[i] = 2 * n_target[v] - L[v];\n        if (demand[i] < 0) return \"\";\n    }\n\n    Dinic dinic(B + W + 2);\n    // source -> black\n    for (int i = 0; i < B; ++i) {\n        dinic.add_edge(S, i, supply[i]);\n    }\n    // white -> sink\n    for (int i = 0; i < W; ++i) {\n        dinic.add_edge(B + i, T, demand[i]);\n    }\n\n    // Edges between black and white (original adjacency)\n    struct OrigEdge {\n        int u, v; // u black, v white\n        int flow_edge_idx;\n    };\n    vector<OrigEdge> orig_edges;\n    for (int u : black) {\n        int ui = black_idx[u];\n        for (auto [v, dir] : graph[u]) {\n            if (color[v] == 1) { // v is white\n                int vi = white_idx[v];\n                int idx = dinic.g[ui].size();\n                dinic.add_edge(ui, B + vi, 1000000); // large capacity\n                orig_edges.push_back({u, v, idx});\n            }\n        }\n    }\n\n    // Compute max flow\n    int flow = dinic.max_flow(S, T);\n    if (flow != total_supply) return \"\";\n\n    // Retrieve multiplicities x_e = flow + lower_bound\n    vector<vector<pair<int, int>>> multigraph(V);\n    for (auto& e : orig_edges) {\n        int u = e.u, v = e.v;\n        int f = dinic.g[u][e.flow_edge_idx].flow;\n        int l = (tree_edges.count({min(u, v), max(u, v)})) ? 1 : 0;\n        int x = f + l;\n        if (x > 0) {\n            multigraph[u].emplace_back(v, x);\n            multigraph[v].emplace_back(u, x);\n        }\n    }\n\n    // Check connectivity (should be connected because tree edges have at least 1)\n    vector<bool> vis(V, false);\n    queue<int> qc;\n    qc.push(0);\n    vis[0] = true;\n    while (!qc.empty()) {\n        int u = qc.front(); qc.pop();\n        for (auto [v, mult] : multigraph[u]) {\n            if (mult > 0 && !vis[v]) {\n                vis[v] = true;\n                qc.push(v);\n            }\n        }\n    }\n    for (int i = 0; i < V; ++i) {\n        if (n_target[i] > 0 && !vis[i]) return \"\";\n    }\n\n    // Hierholzer to find Eulerian circuit starting at root (0)\n    vector<int> circuit;\n    stack<int> stk;\n    stk.push(0);\n    while (!stk.empty()) {\n        int u = stk.top();\n        if (!multigraph[u].empty()) {\n            auto [v, mult] = multigraph[u].back();\n            if (mult > 0) {\n                multigraph[u].back().second--;\n                // remove reverse edge copy\n                for (auto &rev : multigraph[v]) {\n                    if (rev.first == u && rev.second > 0) {\n                        rev.second--;\n                        break;\n                    }\n                }\n                stk.push(v);\n            } else {\n                multigraph[u].pop_back();\n            }\n        } else {\n            circuit.push_back(u);\n            stk.pop();\n        }\n    }\n    reverse(circuit.begin(), circuit.end());\n\n    // Convert circuit to moves\n    string moves;\n    for (size_t i = 0; i + 1 < circuit.size(); ++i) {\n        int u = circuit[i], v = circuit[i+1];\n        int ui = u / N, uj = u % N;\n        int vi = v / N, vj = v % N;\n        if (vi == ui + 1) moves += 'D';\n        else if (vi == ui - 1) moves += 'U';\n        else if (vj == uj + 1) moves += 'R';\n        else if (vj == uj - 1) moves += 'L';\n        else return \"\";\n    }\n    return moves;\n}\n\n// ---------- Main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(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    string result = flow_solution();\n    if (result.empty()) {\n        result = greedy_simulation_solution();\n    }\n    cout << result << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nstruct Candidate {\n    vector<pii> pos;      // 5 positions\n    int internal_cost;    // cost to type this occurrence from scratch\n    vector<int> tail_cost; // tail_cost[k]: cost from position k to end (including letter at k)\n};\n\nint manhattan(const pii& a, const pii& b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\n// Transition cost from candidate A to candidate B given valid overlaps\nint transition_cost(const Candidate& A, const Candidate& B, const vector<int>& valid) {\n    int best = 1e9;\n    for (int k : valid) {\n        int cost = manhattan(A.pos[4], B.pos[k]) + B.tail_cost[k];\n        if (cost < best) best = cost;\n    }\n    return best;\n}\n\nint compute_cost(const vector<int>& order_targets, \n                 const vector<int>& order_candidate_idx,\n                 const vector<vector<Candidate>>& candidates,\n                 const vector<vector<vector<int>>>& valid,\n                 const pii& start) {\n    int total = 0;\n    pii cur_pos = start;\n    int cur_target = -1;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& cand = candidates[j][order_candidate_idx[i]];\n        if (cur_target == -1) {\n            total += manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n        } else {\n            total += transition_cost(candidates[cur_target][order_candidate_idx[i-1]], cand, valid[cur_target][j]);\n        }\n        cur_target = j;\n    }\n    return total;\n}\n\n// Function to run one instance of the algorithm and return the cost and moves\npair<int, vector<pii>> solve_one(mt19937& rng, const int N, const int M, const pii& start,\n                                 const vector<vector<pii>>& pos_list, const vector<string>& targets,\n                                 const vector<vector<vector<int>>>& valid) {\n    const int RANDOM_CANDIDATES = 4000;\n    const int GREEDY_CANDIDATES = 400;\n    const int KEEP = 50;\n\n    vector<vector<Candidate>> candidates(M);\n\n    // Generate candidate occurrences for each target\n    for (int idx = 0; idx < M; ++idx) {\n        const string& t = targets[idx];\n        vector<Candidate> cands;\n        \n        // Random candidates\n        for (int iter = 0; iter < RANDOM_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            for (int k = 0; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                uniform_int_distribution<int> d(0, (int)lst.size() - 1);\n                pos[k] = lst[d(rng)];\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n        \n        // Greedy candidates: start from random position for first letter,\n        // then for each next letter choose closest position to current\n        for (int iter = 0; iter < GREEDY_CANDIDATES; ++iter) {\n            vector<pii> pos(5);\n            // Choose random starting position for first letter\n            const auto& lst0 = pos_list[t[0] - 'A'];\n            uniform_int_distribution<int> d0(0, (int)lst0.size() - 1);\n            pos[0] = lst0[d0(rng)];\n            \n            for (int k = 1; k < 5; ++k) {\n                char ch = t[k];\n                const auto& lst = pos_list[ch - 'A'];\n                // Find closest position to current position\n                int best_dist = 1e9;\n                pii best_pos = lst[0];\n                for (const pii& p : lst) {\n                    int d = manhattan(pos[k-1], p);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_pos = p;\n                    }\n                }\n                pos[k] = best_pos;\n            }\n\n            // Compute internal cost\n            int internal = 5;\n            for (int k = 0; k < 4; ++k) {\n                internal += manhattan(pos[k], pos[k + 1]);\n            }\n\n            // Compute tail costs\n            vector<int> tail(5);\n            tail[4] = 1;\n            for (int k = 3; k >= 0; --k) {\n                tail[k] = 1 + manhattan(pos[k], pos[k + 1]) + tail[k + 1];\n            }\n\n            cands.push_back({pos, internal, tail});\n        }\n\n        // Keep the best KEEP candidates by internal cost\n        sort(cands.begin(), cands.end(),\n             [](const Candidate& a, const Candidate& b) { return a.internal_cost < b.internal_cost; });\n        if (cands.size() > KEEP) cands.resize(KEEP);\n        candidates[idx] = cands;\n    }\n\n    // Greedy construction of the path\n    vector<int> order_targets;\n    vector<int> order_candidate_idx;\n    vector<bool> covered(M, false);\n\n    pii cur_pos = start;\n    int cur_target = -1;\n\n    for (int step = 0; step < M; ++step) {\n        int best_add = 1e9;\n        int best_j = -1, best_c = -1;\n\n        for (int j = 0; j < M; ++j) {\n            if (covered[j]) continue;\n            for (size_t c = 0; c < candidates[j].size(); ++c) {\n                const Candidate& cand = candidates[j][c];\n                if (cur_target == -1) {\n                    int add = manhattan(cur_pos, cand.pos[0]) + cand.internal_cost;\n                    if (add < best_add) {\n                        best_add = add;\n                        best_j = j;\n                        best_c = c;\n                    }\n                } else {\n                    for (int k : valid[cur_target][j]) {\n                        int add = manhattan(cur_pos, cand.pos[k]) + cand.tail_cost[k];\n                        if (add < best_add) {\n                            best_add = add;\n                            best_j = j;\n                            best_c = c;\n                        }\n                    }\n                }\n            }\n        }\n\n        covered[best_j] = true;\n        order_targets.push_back(best_j);\n        order_candidate_idx.push_back(best_c);\n\n        cur_target = best_j;\n        cur_pos = candidates[best_j][best_c].pos[4];\n    }\n\n    // First 2-opt pass\n    int current_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < M - 1; ++i) {\n            for (int j = i + 1; j < M; ++j) {\n                // Try swapping i and j\n                swap(order_targets[i], order_targets[j]);\n                swap(order_candidate_idx[i], order_candidate_idx[j]);\n                int new_cost = compute_cost(order_targets, order_candidate_idx, candidates, valid, start);\n                if (new_cost < current_cost) {\n                    current_cost = new_cost;\n                    improved = true;\n                } else {\n                    // Swap back\n                    swap(order_targets[i], order_targets[j]);\n                    swap(order_candidate_idx[i], order_candidate_idx[j]);\n                }\n            }\n        }\n    }\n\n    // Dynamic programming to re-select candidates for fixed order\n    vector<int> final_candidate_idx(M);\n    int final_cost = 0;\n    {\n        int n = M;\n        vector<vector<int>> dp(n, vector<int>(candidates[order_targets[0]].size(), 1e9));\n        vector<vector<int>> prev(n, vector<int>(candidates[order_targets[0]].size(), -1));\n        \n        // Initialize for first target\n        for (size_t c = 0; c < candidates[order_targets[0]].size(); ++c) {\n            const Candidate& cand = candidates[order_targets[0]][c];\n            dp[0][c] = manhattan(start, cand.pos[0]) + cand.internal_cost;\n        }\n\n        for (int i = 1; i < n; ++i) {\n            int cur_target = order_targets[i];\n            int prev_target = order_targets[i-1];\n            for (size_t c = 0; c < candidates[cur_target].size(); ++c) {\n                const Candidate& cand_cur = candidates[cur_target][c];\n                for (size_t d = 0; d < candidates[prev_target].size(); ++d) {\n                    const Candidate& cand_prev = candidates[prev_target][d];\n                    int add = transition_cost(cand_prev, cand_cur, valid[prev_target][cur_target]);\n                    int total = dp[i-1][d] + add;\n                    if (total < dp[i][c]) {\n                        dp[i][c] = total;\n                        prev[i][c] = d;\n                    }\n                }\n            }\n        }\n\n        // Find best final candidate\n        int best_c = -1;\n        int best_total = 1e9;\n        for (size_t c = 0; c < dp[n-1].size(); ++c) {\n            if (dp[n-1][c] < best_total) {\n                best_total = dp[n-1][c];\n                best_c = c;\n            }\n        }\n\n        // Backtrack\n        final_cost = best_total;\n        int cur_c = best_c;\n        for (int i = n-1; i >= 0; --i) {\n            final_candidate_idx[i] = cur_c;\n            if (i > 0) cur_c = prev[i][cur_c];\n        }\n    }\n\n    // Candidate improvement (first pass)\n    {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M; ++i) {\n                int target = order_targets[i];\n                int old_idx = final_candidate_idx[i];\n                for (size_t new_idx = 0; new_idx < candidates[target].size(); ++new_idx) {\n                    if (new_idx == old_idx) continue;\n                    \n                    // Compute delta cost if we change candidate for target i\n                    int delta = 0;\n                    const Candidate& old_cand = candidates[target][old_idx];\n                    const Candidate& new_cand = candidates[target][new_idx];\n                    \n                    // Replace internal cost\n                    delta += new_cand.internal_cost - old_cand.internal_cost;\n                    \n                    // Replace transition from previous target if exists\n                    if (i > 0) {\n                        int prev_target = order_targets[i-1];\n                        const Candidate& prev_cand = candidates[prev_target][final_candidate_idx[i-1]];\n                        delta += transition_cost(prev_cand, new_cand, valid[prev_target][target]) \n                                - transition_cost(prev_cand, old_cand, valid[prev_target][target]);\n                    }\n                    \n                    // Replace transition to next target if exists\n                    if (i < M-1) {\n                        int next_target = order_targets[i+1];\n                        const Candidate& next_cand = candidates[next_target][final_candidate_idx[i+1]];\n                        delta += transition_cost(new_cand, next_cand, valid[target][next_target]) \n                                - transition_cost(old_cand, next_cand, valid[target][next_target]);\n                    }\n                    \n                    if (delta < 0) {\n                        final_candidate_idx[i] = new_idx;\n                        final_cost += delta;\n                        improved = true;\n                        break; // restart loop\n                    }\n                }\n            }\n        }\n    }\n\n    // Second 2-opt pass\n    {\n        current_cost = compute_cost(order_targets, final_candidate_idx, candidates, valid, start);\n        improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M - 1; ++i) {\n                for (int j = i + 1; j < M; ++j) {\n                    // Try swapping i and j\n                    swap(order_targets[i], order_targets[j]);\n                    swap(final_candidate_idx[i], final_candidate_idx[j]);\n                    int new_cost = compute_cost(order_targets, final_candidate_idx, candidates, valid, start);\n                    if (new_cost < current_cost) {\n                        current_cost = new_cost;\n                        improved = true;\n                    } else {\n                        // Swap back\n                        swap(order_targets[i], order_targets[j]);\n                        swap(final_candidate_idx[i], final_candidate_idx[j]);\n                    }\n                }\n            }\n        }\n    }\n\n    // Candidate improvement again after second 2-opt\n    {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M; ++i) {\n                int target = order_targets[i];\n                int old_idx = final_candidate_idx[i];\n                for (size_t new_idx = 0; new_idx < candidates[target].size(); ++new_idx) {\n                    if (new_idx == old_idx) continue;\n                    \n                    // Compute delta cost if we change candidate for target i\n                    int delta = 0;\n                    const Candidate& old_cand = candidates[target][old_idx];\n                    const Candidate& new_cand = candidates[target][new_idx];\n                    \n                    // Replace internal cost\n                    delta += new_cand.internal_cost - old_cand.internal_cost;\n                    \n                    // Replace transition from previous target if exists\n                    if (i > 0) {\n                        int prev_target = order_targets[i-1];\n                        const Candidate& prev_cand = candidates[prev_target][final_candidate_idx[i-1]];\n                        delta += transition_cost(prev_cand, new_cand, valid[prev_target][target]) \n                                - transition_cost(prev_cand, old_cand, valid[prev_target][target]);\n                    }\n                    \n                    // Replace transition to next target if exists\n                    if (i < M-1) {\n                        int next_target = order_targets[i+1];\n                        const Candidate& next_cand = candidates[next_target][final_candidate_idx[i+1]];\n                        delta += transition_cost(new_cand, next_cand, valid[target][next_target]) \n                                - transition_cost(old_cand, next_cand, valid[target][next_target]);\n                    }\n                    \n                    if (delta < 0) {\n                        final_candidate_idx[i] = new_idx;\n                        final_cost += delta;\n                        improved = true;\n                        break; // restart loop\n                    }\n                }\n            }\n        }\n    }\n\n    // Build the output sequence of moves using final candidates\n    vector<pii> moves;\n    int cur_target_move = -1;\n    pii cur_pos_move = start;\n    for (size_t i = 0; i < order_targets.size(); ++i) {\n        int j = order_targets[i];\n        const Candidate& occ = candidates[j][final_candidate_idx[i]];\n        if (cur_target_move == -1) {\n            for (int k = 0; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        } else {\n            int best_k = 0;\n            int best_add = 1e9;\n            for (int k : valid[cur_target_move][j]) {\n                int add = manhattan(cur_pos_move, occ.pos[k]) + occ.tail_cost[k];\n                if (add < best_add) {\n                    best_add = add;\n                    best_k = k;\n                }\n            }\n            for (int k = best_k; k < 5; ++k) {\n                moves.push_back(occ.pos[k]);\n            }\n        }\n        cur_target_move = j;\n        cur_pos_move = occ.pos[4];\n    }\n\n    return {final_cost, moves};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n    pii start;\n    cin >> start.first >> start.second;\n\n    vector<vector<char>> A(N, vector<char>(N));\n    vector<vector<pii>> pos_list(26); // positions for each letter\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            pos_list[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n\n    vector<string> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i];\n    }\n\n    // Precompute valid overlaps between targets\n    vector<vector<vector<int>>> valid(M, vector<vector<int>>(M));\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            const string& si = targets[i];\n            const string& sj = targets[j];\n            vector<int> v;\n            for (int k = 1; k <= 4; ++k) {\n                if (si.substr(5 - k) == sj.substr(0, k)) {\n                    v.push_back(k);\n                }\n            }\n            v.push_back(0); // k=0 always allowed\n            valid[i][j] = v;\n        }\n    }\n\n    // Multi-start: run 4 times with different random seeds\n    const int NUM_STARTS = 4;\n    int best_cost = 1e9;\n    vector<pii> best_moves;\n\n    random_device rd;\n    for (int start_idx = 0; start_idx < NUM_STARTS; ++start_idx) {\n        mt19937 rng(rd() + start_idx); // different seed each start\n        auto [cost, moves] = solve_one(rng, N, M, start, pos_list, targets, valid);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_moves = moves;\n        }\n    }\n\n    // Output the best moves\n    for (const pii& p : best_moves) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <cstdio>\n#include <vector>\nusing namespace std;\n\nint query(const vector<pair<int, int>>& cells) {\n    int k = cells.size();\n    printf(\"q %d\", k);\n    for (auto& p : cells) {\n        printf(\" %d %d\", p.first, p.second);\n    }\n    printf(\"\\n\");\n    fflush(stdout);\n    int val;\n    scanf(\"%d\", &val);\n    return val;\n}\n\nint drill(int i, int j) {\n    printf(\"q 1 %d %d\\n\", i, j);\n    fflush(stdout);\n    int val;\n    scanf(\"%d\", &val);\n    return val;\n}\n\nint main() {\n    int N, M;\n    double eps;\n    scanf(\"%d %d %lf\", &N, &M, &eps);\n\n    // read shapes (unused)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        scanf(\"%d\", &d);\n        for (int i = 0; i < d; ++i) {\n            int x, y;\n            scanf(\"%d %d\", &x, &y);\n        }\n    }\n\n    const int B = 5; // block size\n    vector<pair<int, int>> oil;\n\n    auto block_strategy = [&]() {\n        oil.clear();\n        for (int i0 = 0; i0 < N; i0 += B) {\n            int i1 = min(i0 + B, N);\n            for (int j0 = 0; j0 < N; j0 += B) {\n                int j1 = min(j0 + B, N);\n                vector<pair<int, int>> block;\n                for (int i = i0; i < i1; ++i)\n                    for (int j = j0; j < j1; ++j)\n                        block.emplace_back(i, j);\n                int res = query(block);\n                if (res > 0) {\n                    for (int i = i0; i < i1; ++i)\n                        for (int j = j0; j < j1; ++j) {\n                            int val = drill(i, j);\n                            if (val > 0)\n                                oil.emplace_back(i, j);\n                        }\n                }\n            }\n        }\n        printf(\"a %d\", (int)oil.size());\n        for (auto& p : oil)\n            printf(\" %d %d\", p.first, p.second);\n        printf(\"\\n\");\n        fflush(stdout);\n        int resp;\n        scanf(\"%d\", &resp);\n        return resp;\n    };\n\n    int resp = block_strategy();\n    if (resp == 0) {   // fallback: drill every square\n        oil.clear();\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int val = drill(i, j);\n                if (val > 0)\n                    oil.emplace_back(i, j);\n            }\n        printf(\"a %d\", (int)oil.size());\n        for (auto& p : oil)\n            printf(\" %d %d\", p.first, p.second);\n        printf(\"\\n\");\n        fflush(stdout);\n        scanf(\"%d\", &resp);\n    }\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <climits>\n#include <cassert>\nusing namespace std;\n\nconst int W_MAX = 1000; // grid size\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    int area() const { return (x2 - x1) * (y2 - y1); }\n};\n\n// Recursive partition of the grid into rectangles with areas as close as possible to B\nvoid partition(Rect r, vector<int> indices, const vector<long long>& B, vector<Rect>& rects) {\n    int m = indices.size();\n    if (m == 1) {\n        rects[indices[0]] = r;\n        return;\n    }\n    long long total_target = 0;\n    for (int i : indices) total_target += B[i];\n    long long total_area = (long long)(r.x2 - r.x1) * (r.y2 - r.y1);\n    // sort indices by B to make contiguous groups\n    sort(indices.begin(), indices.end(), [&](int i, int j) { return B[i] < B[j]; });\n    long long best_waste = LLONG_MAX;\n    int best_split = -1;\n    int best_orient = 0; // 0 = horizontal, 1 = vertical\n    int best_cut = 0;\n    int width = r.x2 - r.x1;\n    int height = r.y2 - r.y1;\n    for (int i = 1; i < m; ++i) {\n        long long sum_left = 0;\n        for (int j = 0; j < i; ++j) sum_left += B[indices[j]];\n        long long sum_right = total_target - sum_left;\n        // horizontal split\n        double target_y = (double)sum_left / width;\n        int cut_y = (int)round(target_y);\n        if (cut_y < 1) cut_y = 1;\n        if (cut_y > height-1) cut_y = height-1;\n        long long top_area = (long long)width * cut_y;\n        long long bottom_area = (long long)width * (height - cut_y);\n        long long waste = llabs(top_area - sum_left) + llabs(bottom_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 0;\n            best_cut = cut_y;\n        }\n        // vertical split\n        double target_x = (double)sum_left / height;\n        int cut_x = (int)round(target_x);\n        if (cut_x < 1) cut_x = 1;\n        if (cut_x > width-1) cut_x = width-1;\n        long long left_area = (long long)cut_x * height;\n        long long right_area = (long long)(width - cut_x) * height;\n        waste = llabs(left_area - sum_left) + llabs(right_area - sum_right);\n        if (waste < best_waste) {\n            best_waste = waste;\n            best_split = i;\n            best_orient = 1;\n            best_cut = cut_x;\n        }\n    }\n    // Now split\n    if (best_orient == 0) {\n        // horizontal\n        Rect top(r.x1, r.y1, r.x2, r.y1 + best_cut);\n        Rect bottom(r.x1, r.y1 + best_cut, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(top, left_indices, B, rects);\n        partition(bottom, right_indices, B, rects);\n    } else {\n        // vertical\n        Rect left(r.x1, r.y1, r.x1 + best_cut, r.y2);\n        Rect right(r.x1 + best_cut, r.y1, r.x2, r.y2);\n        vector<int> left_indices(indices.begin(), indices.begin() + best_split);\n        vector<int> right_indices(indices.begin() + best_split, indices.end());\n        partition(left, left_indices, B, rects);\n        partition(right, right_indices, B, rects);\n    }\n}\n\nvector<Rect> packRectangles(const vector<long long>& B) {\n    int N = B.size();\n    vector<Rect> rects(N);\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    // Recursive partition covering the whole grid\n    partition(Rect{0, 0, W_MAX, W_MAX}, indices, B, rects);\n    return rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    // W_input should be 1000; we ignore it and use W_MAX.\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) {\n            cin >> A[d][k];\n        }\n    }\n\n    // For each day, pack rectangles according to that day's desires\n    for (int d = 0; d < D; ++d) {\n        vector<long long> B(N);\n        for (int k = 0; k < N; ++k) B[k] = A[d][k];\n        vector<Rect> rects = packRectangles(B);\n        // rects are in ascending order of B (since packRectangles sorts indices)\n        // We need to output for each reservation k the rectangle with matching desire.\n        // Compute order of reservations by desire ascending\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[d][i] < A[d][j];\n        });\n        // Create output mapping: for each reservation k, store the rectangle\n        vector<Rect> out(N);\n        for (int rank = 0; rank < N; ++rank) {\n            int k = order[rank]; // reservation with rank-th smallest desire\n            out[k] = rects[rank]; // rects[rank] has area at least B[order[rank]]\n        }\n        // Output in reservation order (0..N-1)\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = out[k];\n            cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\nstruct Move {\n    int m, p, q;\n    vector<pair<int, int>> cells; // (index, value)\n};\n\nstruct State {\n    array<int, N*N> board;\n    long long score;\n    State* parent;\n    int m, p, q; // move that led to this state, or -1 for initial\n};\n\nlong long compute_gain(const array<int, N*N>& board, const Move& move) {\n    long long gain = 0;\n    for (auto [idx, val] : move.cells) {\n        int old_rem = board[idx];\n        int new_rem = (old_rem + val) % MOD;\n        gain += new_rem - old_rem;\n    }\n    return gain;\n}\n\nvoid apply_move(array<int, N*N>& board, const Move& move) {\n    for (auto [idx, val] : move.cells) {\n        board[idx] = (board[idx] + val) % MOD;\n    }\n}\n\nlong long compute_score(const array<int, N*N>& board) {\n    return accumulate(board.begin(), board.end(), 0LL);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    vector<int> a(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i*N + j];\n        }\n    }\n\n    vector<array<array<int, 3>, 3>> 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][i][j];\n            }\n        }\n    }\n\n    // Precompute all possible moves\n    vector<Move> moves_list;\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                Move move;\n                move.m = m;\n                move.p = p;\n                move.q = q;\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        int idx = (p+i)*N + (q+j);\n                        int val = stamps[m][i][j] % MOD;\n                        move.cells.emplace_back(idx, val);\n                    }\n                }\n                moves_list.push_back(move);\n            }\n        }\n    }\n\n    // Create index mapping for quick lookup\n    array<array<array<int, N-2>, N-2>, M> move_index;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < N-2; ++j) {\n            for (int k = 0; k < N-2; ++k) {\n                move_index[i][j][k] = -1;\n            }\n        }\n    }\n    for (int idx = 0; idx < moves_list.size(); ++idx) {\n        const Move& move = moves_list[idx];\n        move_index[move.m][move.p][move.q] = idx;\n    }\n\n    // Beam search\n    const int beam_width = 25;\n    vector<State*> all_states;\n    State* initial = new State;\n    initial->parent = nullptr;\n    initial->m = initial->p = initial->q = -1;\n    copy(a.begin(), a.end(), initial->board.begin());\n    initial->score = accumulate(a.begin(), a.end(), 0LL);\n    all_states.push_back(initial);\n\n    State* global_best = initial;\n    long long global_best_score = initial->score;\n\n    vector<State*> current_beam;\n    current_beam.push_back(initial);\n\n    for (int step = 0; step < K; ++step) {\n        vector<State*> candidates;\n\n        for (State* s : current_beam) {\n            // Option: do nothing\n            candidates.push_back(s);\n\n            // Try every move\n            for (const Move& move : moves_list) {\n                array<int, N*N> new_board = s->board;\n                long long gain = compute_gain(new_board, move);\n                long long new_score = s->score + gain;\n\n                State* new_state = new State;\n                new_state->board = new_board;\n                apply_move(new_state->board, move);\n                new_state->score = new_score;\n                new_state->parent = s;\n                new_state->m = move.m;\n                new_state->p = move.p;\n                new_state->q = move.q;\n\n                candidates.push_back(new_state);\n                all_states.push_back(new_state);\n\n                if (new_score > global_best_score) {\n                    global_best = new_state;\n                    global_best_score = new_score;\n                }\n            }\n        }\n\n        // Select top beam_width states\n        sort(candidates.begin(), candidates.end(),\n             [](State* a, State* b) { return a->score > b->score; });\n\n        if (!candidates.empty() && candidates[0]->score > global_best_score) {\n            global_best = candidates[0];\n            global_best_score = candidates[0]->score;\n        }\n\n        current_beam.clear();\n        for (int i = 0; i < beam_width && i < candidates.size(); ++i) {\n            current_beam.push_back(candidates[i]);\n        }\n    }\n\n    // Reconstruct the sequence of moves from global_best\n    vector<tuple<int, int, int>> sequence;\n    State* cur = global_best;\n    while (cur->parent != nullptr) {\n        sequence.emplace_back(cur->m, cur->p, cur->q);\n        cur = cur->parent;\n    }\n    reverse(sequence.begin(), sequence.end());\n\n    // Greedy extension: add more moves if they improve score and we haven't reached K\n    array<int, N*N> current_board = global_best->board;\n    long long current_score = global_best->score;\n\n    while (sequence.size() < K) {\n        long long best_gain = -1e18;\n        Move best_move;\n        for (const Move& move : moves_list) {\n            long long gain = compute_gain(current_board, move);\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_move = move;\n            }\n        }\n        if (best_gain <= 0) break;\n        apply_move(current_board, best_move);\n        current_score += best_gain;\n        sequence.emplace_back(best_move.m, best_move.p, best_move.q);\n    }\n\n    // Local search: try to improve sequence by replacing one move at a time\n    vector<array<int, N*N>> prefix_boards(sequence.size() + 1);\n    prefix_boards[0] = array<int, N*N>();\n    copy(a.begin(), a.end(), prefix_boards[0].begin());\n    for (int i = 0; i < sequence.size(); ++i) {\n        prefix_boards[i+1] = prefix_boards[i];\n        auto [m, p, q] = sequence[i];\n        const Move& move = moves_list[move_index[m][p][q]];\n        for (auto [idx, val] : move.cells) {\n            prefix_boards[i+1][idx] = (prefix_boards[i+1][idx] + val) % MOD;\n        }\n    }\n    current_score = compute_score(prefix_boards.back());\n\n    auto simulate_from = [&](const array<int, N*N>& start_board, int start_idx) -> long long {\n        array<int, N*N> board = start_board;\n        for (int j = start_idx; j < sequence.size(); ++j) {\n            auto [m, p, q] = sequence[j];\n            const Move& move = moves_list[move_index[m][p][q]];\n            for (auto [idx, val] : move.cells) {\n                board[idx] = (board[idx] + val) % MOD;\n            }\n        }\n        return compute_score(board);\n    };\n\n    bool improved = true;\n    int max_passes = 2; // Reduced from 3 to avoid over-optimization\n    for (int pass = 0; pass < max_passes && improved; ++pass) {\n        improved = false;\n        for (int i = 0; i < sequence.size(); ++i) {\n            array<int, N*N> prefix_board = prefix_boards[i];\n            tuple<int,int,int> original_move = sequence[i];\n            long long best_score = current_score;\n            tuple<int,int,int> best_move = original_move;\n            // Try all candidate moves\n            for (const Move& cand : moves_list) {\n                // apply cand to prefix_board\n                array<int, N*N> new_board = prefix_board;\n                for (auto [idx, val] : cand.cells) {\n                    new_board[idx] = (new_board[idx] + val) % MOD;\n                }\n                // simulate remaining moves from i+1\n                long long final_score = simulate_from(new_board, i+1);\n                if (final_score > best_score) {\n                    best_score = final_score;\n                    best_move = make_tuple(cand.m, cand.p, cand.q);\n                }\n            }\n            if (best_score > current_score) {\n                // update sequence and prefix_boards\n                sequence[i] = best_move;\n                // recompute prefix_boards from i onward\n                for (int j = i; j < sequence.size(); ++j) {\n                    prefix_boards[j+1] = prefix_boards[j];\n                    auto [m, p, q] = sequence[j];\n                    const Move& move = moves_list[move_index[m][p][q]];\n                    for (auto [idx, val] : move.cells) {\n                        prefix_boards[j+1][idx] = (prefix_boards[j+1][idx] + val) % MOD;\n                    }\n                }\n                current_score = best_score;\n                improved = true;\n                break; // restart the inner for loop\n            }\n        }\n    }\n\n    // Output\n    cout << sequence.size() << \"\\n\";\n    for (auto [m, p, q] : sequence) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    // Clean up\n    for (State* s : all_states) {\n        delete s;\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nint grid[N][N];\nint gate_next_idx[N];\nvector<int> gate_queues[N];\nint dispatch_next_needed[N];\nbool container_dispatched[N*N] = {false};\n\n// Crane state\nstruct Crane {\n    int r, c;\n    int holding = -1;\n    enum State { IDLE, MOVING_TO_POSITION, MOVING_TO_PICKUP, PICKING_UP, MOVING_TO_DROPOFF, DROPPING_OFF };\n    State state = IDLE;\n    int target_r = -1, target_c = -1;\n    int dest_row = -1;\n};\n\nCrane cranes[N];\n\nbool in_bounds(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\nbool has_container(int r, int c) {\n    return grid[r][c] != -1;\n}\n\nbool occupied_by_other_crane(int r, int c, int self) {\n    for (int i = 0; i < N; ++i) {\n        if (i != self && cranes[i].r == r && cranes[i].c == c) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Simple BFS to find next move direction\npair<int,int> find_next_move(int sr, int sc, int tr, int tc, int self) {\n    if (sr == tr && sc == tc) return {0, 0};\n    \n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    visited[sr][sc] = true;\n    \n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (in_bounds(nr, nc) && !visited[nr][nc] && !occupied_by_other_crane(nr, nc, self)) {\n                visited[nr][nc] = true;\n                prev[nr][nc] = {r, c};\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    if (!visited[tr][tc]) return {0, 0}; // No path found\n    \n    // Trace back to find first step\n    int r = tr, c = tc;\n    while (prev[r][c] != make_pair(sr, sc)) {\n        auto [pr, pc] = prev[r][c];\n        r = pr; c = pc;\n    }\n    return {r - sr, c - sc};\n}\n\nvoid simulate(vector<string>& actions) {\n    // Initialize\n    memset(grid, -1, sizeof(grid));\n    fill(gate_next_idx, gate_next_idx + N, 0);\n    for (int i = 0; i < N; ++i) {\n        dispatch_next_needed[i] = i * N;\n        cranes[i] = Crane();\n        cranes[i].r = i;\n        cranes[i].c = 0;\n    }\n    \n    actions.resize(N);\n    for (int t = 0; t < MAX_TURNS; ++t) {\n        // Step 1: Place containers at left gates\n        for (int i = 0; i < N; ++i) {\n            if (gate_next_idx[i] >= N) continue;\n            bool crane_holding_here = false;\n            for (int k = 0; k < N; ++k) {\n                if (cranes[k].r == i && cranes[k].c == 0 && cranes[k].holding != -1) {\n                    crane_holding_here = true;\n                    break;\n                }\n            }\n            bool can_place = !has_container(i, 0) && !crane_holding_here;\n            if (can_place) {\n                grid[i][0] = gate_queues[i][gate_next_idx[i]++];\n            }\n        }\n        \n        // Step 2: Crane actions\n        vector<char> turn_actions(N, '.');\n        \n        // Process large crane (index 0)\n        auto& lc = cranes[0];\n        switch (lc.state) {\n            case Crane::IDLE: {\n                // First, move to a safe position if at a left gate (0,0)\n                if (lc.r == 0 && lc.c == 0) {\n                    // Move to (0,1) to get out of the way\n                    lc.target_r = 0;\n                    lc.target_c = 1;\n                    lc.state = Crane::MOVING_TO_POSITION;\n                    break;\n                }\n                \n                // Look for a container that is the next needed for its destination row\n                for (int row = 0; row < N; ++row) {\n                    int need = dispatch_next_needed[row];\n                    if (need >= row*N && need < (row+1)*N && !container_dispatched[need]) {\n                        // Check if this container is at a left gate\n                        for (int gate = 0; gate < N; ++gate) {\n                            if (has_container(gate, 0) && grid[gate][0] == need) {\n                                lc.target_r = gate;\n                                lc.target_c = 0;\n                                lc.dest_row = row;\n                                lc.state = Crane::MOVING_TO_PICKUP;\n                                break;\n                            }\n                        }\n                        if (lc.state != Crane::IDLE) break;\n                    }\n                }\n                break;\n            }\n            case Crane::MOVING_TO_POSITION: {\n                if (lc.r == lc.target_r && lc.c == lc.target_c) {\n                    lc.state = Crane::IDLE;\n                } else {\n                    auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0);\n                    if (dr != 0 || dc != 0) {\n                        lc.r += dr;\n                        lc.c += dc;\n                        if (dr == -1) turn_actions[0] = 'U';\n                        else if (dr == 1) turn_actions[0] = 'D';\n                        else if (dc == -1) turn_actions[0] = 'L';\n                        else if (dc == 1) turn_actions[0] = 'R';\n                    }\n                }\n                break;\n            }\n            case Crane::MOVING_TO_PICKUP: {\n                if (lc.r == lc.target_r && lc.c == lc.target_c) {\n                    // At pickup location\n                    turn_actions[0] = 'P';\n                    lc.holding = grid[lc.r][lc.c];\n                    grid[lc.r][lc.c] = -1;\n                    lc.state = Crane::PICKING_UP;\n                } else {\n                    auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0);\n                    if (dr != 0 || dc != 0) {\n                        lc.r += dr;\n                        lc.c += dc;\n                        if (dr == -1) turn_actions[0] = 'U';\n                        else if (dr == 1) turn_actions[0] = 'D';\n                        else if (dc == -1) turn_actions[0] = 'L';\n                        else if (dc == 1) turn_actions[0] = 'R';\n                    }\n                }\n                break;\n            }\n            case Crane::PICKING_UP: {\n                // Go to dispatch gate of destination row\n                lc.target_r = lc.dest_row;\n                lc.target_c = N - 1;\n                lc.state = Crane::MOVING_TO_DROPOFF;\n                break;\n            }\n            case Crane::MOVING_TO_DROPOFF: {\n                if (lc.r == lc.target_r && lc.c == lc.target_c) {\n                    // At dispatch gate\n                    if (!has_container(lc.r, lc.c)) {\n                        turn_actions[0] = 'Q';\n                        grid[lc.r][lc.c] = lc.holding;\n                        lc.holding = -1;\n                        lc.state = Crane::DROPPING_OFF;\n                    }\n                } else {\n                    auto [dr, dc] = find_next_move(lc.r, lc.c, lc.target_r, lc.target_c, 0);\n                    if (dr != 0 || dc != 0) {\n                        lc.r += dr;\n                        lc.c += dc;\n                        if (dr == -1) turn_actions[0] = 'U';\n                        else if (dr == 1) turn_actions[0] = 'D';\n                        else if (dc == -1) turn_actions[0] = 'L';\n                        else if (dc == 1) turn_actions[0] = 'R';\n                    }\n                }\n                break;\n            }\n            case Crane::DROPPING_OFF: {\n                lc.state = Crane::IDLE;\n                break;\n            }\n        }\n        \n        // Small cranes: move to safe positions to avoid blocking\n        for (int i = 1; i < N; ++i) {\n            auto& sc = cranes[i];\n            if (sc.state == Crane::IDLE) {\n                // If at left gate, move to column 1\n                if (sc.c == 0) {\n                    sc.target_r = sc.r;\n                    sc.target_c = 1;\n                    sc.state = Crane::MOVING_TO_POSITION;\n                }\n            }\n            \n            switch (sc.state) {\n                case Crane::MOVING_TO_POSITION: {\n                    if (sc.r == sc.target_r && sc.c == sc.target_c) {\n                        sc.state = Crane::IDLE;\n                    } else {\n                        auto [dr, dc] = find_next_move(sc.r, sc.c, sc.target_r, sc.target_c, i);\n                        if (dr != 0 || dc != 0) {\n                            sc.r += dr;\n                            sc.c += dc;\n                            if (dr == -1) turn_actions[i] = 'U';\n                            else if (dr == 1) turn_actions[i] = 'D';\n                            else if (dc == -1) turn_actions[i] = 'L';\n                            else if (dc == 1) turn_actions[i] = 'R';\n                        }\n                    }\n                    break;\n                }\n                default: {\n                    // For other states, do nothing for now\n                    break;\n                }\n            }\n        }\n        \n        // Step 3: Dispatch containers from right gates\n        for (int i = 0; i < N; ++i) {\n            if (has_container(i, N-1)) {\n                int container_id = grid[i][N-1];\n                container_dispatched[container_id] = true;\n                grid[i][N-1] = -1;\n                while (dispatch_next_needed[i] < (i+1)*N && container_dispatched[dispatch_next_needed[i]]) {\n                    dispatch_next_needed[i]++;\n                }\n            }\n        }\n        \n        // Record actions\n        for (int i = 0; i < N; ++i) {\n            actions[i] += turn_actions[i];\n        }\n        \n        // Check completion\n        bool all_done = true;\n        for (int id = 0; id < N*N; ++id) {\n            if (!container_dispatched[id]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_input;\n    cin >> N_input;\n    \n    for (int i = 0; i < N_input; ++i) {\n        gate_queues[i].resize(N_input);\n        for (int j = 0; j < N_input; ++j) {\n            cin >> gate_queues[i][j];\n        }\n    }\n    \n    vector<string> actions;\n    simulate(actions);\n    \n    // Pad shorter strings with '.'\n    size_t max_len = 0;\n    for (const string& s : actions) {\n        max_len = max(max_len, s.size());\n    }\n    for (string& s : actions) {\n        if (s.size() < max_len) {\n            s.append(max_len - s.size(), '.');\n        }\n    }\n    \n    for (const string& s : actions) {\n        cout << s << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 20;\nconst int TOTAL_CELLS = N * N;\n\n// Generate snake path by rows\nvector<pair<int, int>> generate_path_rows() {\n    vector<pair<int, int>> path;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) path.emplace_back(i, j);\n        } else {\n            for (int j = N - 1; j >= 0; --j) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate snake path by columns\nvector<pair<int, int>> generate_path_cols() {\n    vector<pair<int, int>> path;\n    for (int j = 0; j < N; ++j) {\n        if (j % 2 == 0) {\n            for (int i = 0; i < N; ++i) path.emplace_back(i, j);\n        } else {\n            for (int i = N - 1; i >= 0; --i) path.emplace_back(i, j);\n        }\n    }\n    return path;\n}\n\n// Generate clockwise spiral\nvector<pair<int, int>> generate_spiral_cw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) path.emplace_back(top, j);\n        top++;\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, right);\n        right--;\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(bottom, j);\n            bottom--;\n        }\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, left);\n            left++;\n        }\n    }\n    return path;\n}\n\n// Generate counterclockwise spiral\nvector<pair<int, int>> generate_spiral_ccw() {\n    vector<pair<int, int>> path;\n    int top = 0, bottom = N - 1, left = 0, right = N - 1;\n    while (top <= bottom && left <= right) {\n        for (int i = top; i <= bottom; ++i) path.emplace_back(i, left);\n        left++;\n        for (int j = left; j <= right; ++j) path.emplace_back(bottom, j);\n        bottom--;\n        if (left <= right) {\n            for (int i = bottom; i >= top; --i) path.emplace_back(i, right);\n            right--;\n        }\n        if (top <= bottom) {\n            for (int j = right; j >= left; --j) path.emplace_back(top, j);\n            top++;\n        }\n    }\n    return path;\n}\n\n// Compute load-distance for a single tour (interleaved loading/unloading)\nint compute_load_distance(const vector<pair<int, int>>& path, const vector<vector<int>>& h) {\n    int load = 0;\n    int total_ld = 0;\n    for (int idx = 0; idx < (int)path.size(); ++idx) {\n        int i = path[idx].first, j = path[idx].second;\n        if (h[i][j] > 0) {\n            load += h[i][j];\n        } else if (h[i][j] < 0) {\n            int unload = min(load, -h[i][j]);\n            load -= unload;\n        }\n        if (idx < (int)path.size() - 1) {\n            total_ld += load;\n        }\n    }\n    return total_ld;\n}\n\n// Determine move direction\nstring get_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return \"U\";\n    if (ni == i + 1) return \"D\";\n    if (nj == j - 1) return \"L\";\n    if (nj == j + 1) return \"R\";\n    return \"\"; // should not happen\n}\n\nint main() {\n    // Read input\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    // Generate candidate paths\n    vector<vector<pair<int, int>>> candidates;\n    candidates.push_back(generate_path_rows());\n    candidates.push_back(generate_path_cols());\n    candidates.push_back(generate_spiral_cw());\n    candidates.push_back(generate_spiral_ccw());\n\n    // Choose path with minimal load-distance for single tour\n    int best_ld = INT_MAX;\n    vector<pair<int, int>> best_path;\n    for (const auto& path : candidates) {\n        int ld = compute_load_distance(path, h);\n        if (ld < best_ld) {\n            best_ld = ld;\n            best_path = path;\n        }\n    }\n\n    // Simulate operations for the chosen path (single tour)\n    vector<string> ops;\n    vector<vector<int>> cur_h = h;\n    int load = 0;\n    int cur_i = best_path[0].first, cur_j = best_path[0].second;\n\n    for (int idx = 0; idx < (int)best_path.size(); ++idx) {\n        int i = best_path[idx].first, j = best_path[idx].second;\n        // Process cell\n        if (cur_h[i][j] > 0) {\n            int d = cur_h[i][j];\n            ops.push_back(\"+\" + to_string(d));\n            load += d;\n            cur_h[i][j] = 0;\n        } else if (cur_h[i][j] < 0) {\n            int unload = min(load, -cur_h[i][j]);\n            if (unload > 0) {\n                ops.push_back(\"-\" + to_string(unload));\n                load -= unload;\n                cur_h[i][j] += unload;\n            }\n        }\n        // Move to next cell if not last\n        if (idx < (int)best_path.size() - 1) {\n            int ni = best_path[idx+1].first, nj = best_path[idx+1].second;\n            ops.push_back(get_move(cur_i, cur_j, ni, nj));\n            cur_i = ni; cur_j = nj;\n        }\n    }\n\n    // Output operations\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <utility>\n#include <set>\n#include <cstdlib>\n#include <ctime>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int T = 10;\nconst int K = 2 * N * (N - 1); // 60\nconst int MAX_ITER = 70000;    // iterations per SA run\nconst double INIT_TEMP = 100.0;\nconst double COOLING = 0.99999;\nconst int SA_RUNS = 8;         // number of independent SA runs\n\n// Global seeds for current turn\nvector<vector<int>> seeds(K, vector<int>(M));\n\n// Compute potential max sum for a pair of seeds (indices)\nint potential_max(int a, int b) {\n    int sum = 0;\n    for (int l = 0; l < M; ++l) {\n        sum += max(seeds[a][l], seeds[b][l]);\n    }\n    return sum;\n}\n\n// Precompute adjacency list for the grid cells (0..35)\nvector<vector<int>> grid_adj() {\n    vector<vector<int>> adj(N*N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int idx = i * N + j;\n            if (i + 1 < N) adj[idx].push_back((i+1)*N + j);\n            if (i - 1 >= 0) adj[idx].push_back((i-1)*N + j);\n            if (j + 1 < N) adj[idx].push_back(i*N + (j+1));\n            if (j - 1 >= 0) adj[idx].push_back(i*N + (j-1));\n        }\n    }\n    return adj;\n}\n\n// Simulated annealing on a given initial assignment, returns best assignment and its score\npair<vector<int>, int> run_sa(const vector<int>& init_assign,\n                               const vector<vector<int>>& pot,\n                               const vector<vector<int>>& adj,\n                               mt19937& rng) {\n    int num_cells = N*N;\n    vector<int> assign = init_assign;\n    // Compute initial total score\n    int total = 0;\n    for (int i = 0; i < num_cells; ++i) {\n        for (int j : adj[i]) {\n            if (i < j) { // each edge once\n                total += pot[assign[i]][assign[j]];\n            }\n        }\n    }\n    int best_total = total;\n    vector<int> best_assign = assign;\n\n    double temp = INIT_TEMP;\n    uniform_int_distribution<int> cell_dist(0, num_cells-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        int a = cell_dist(rng), b = cell_dist(rng);\n        while (a == b) b = cell_dist(rng);\n\n        // Collect edges incident to a or b (each edge once)\n        set<pair<int, int>> edge_set;\n        for (int nb : adj[a]) {\n            int u = a, v = nb;\n            if (u > v) swap(u, v);\n            edge_set.insert({u, v});\n        }\n        for (int nb : adj[b]) {\n            int u = b, v = nb;\n            if (u > v) swap(u, v);\n            edge_set.insert({u, v});\n        }\n\n        // Compute old contribution of these edges\n        int old_contrib = 0;\n        for (auto& e : edge_set) {\n            old_contrib += pot[assign[e.first]][assign[e.second]];\n        }\n\n        // Swap assignments\n        swap(assign[a], assign[b]);\n\n        // Compute new contribution\n        int new_contrib = 0;\n        for (auto& e : edge_set) {\n            new_contrib += pot[assign[e.first]][assign[e.second]];\n        }\n\n        int delta = new_contrib - old_contrib;\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            double prob = exp(delta / temp);\n            if (prob_dist(rng) < prob) accept = true;\n        }\n\n        if (accept) {\n            total += delta;\n            if (total > best_total) {\n                best_total = total;\n                best_assign = assign;\n            }\n        } else {\n            // revert swap\n            swap(assign[a], assign[b]);\n        }\n\n        temp *= COOLING;\n    }\n\n    return {best_assign, best_total};\n}\n\nint main() {\n    srand(time(0));\n    mt19937 rng(time(0));\n\n    // Read initial seeds\n    for (int i = 0; i < K; ++i) {\n        for (int l = 0; l < M; ++l) {\n            cin >> seeds[i][l];\n        }\n    }\n\n    // Precompute grid adjacency (once)\n    auto adj = grid_adj();\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Compute total sums\n        vector<int> sums(K, 0);\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                sums[i] += seeds[i][l];\n            }\n        }\n\n        // Greedy selection of 36 seeds to maximize pairwise potential\n        vector<int> selected;\n        vector<bool> used(K, false);\n        // Start with the seed with highest sum\n        int first = max_element(sums.begin(), sums.end()) - sums.begin();\n        selected.push_back(first);\n        used[first] = true;\n\n        // Iteratively select next seed that maximizes total potential with already selected seeds\n        for (int step = 1; step < 36; ++step) {\n            int best_candidate = -1;\n            long long best_score = -1;\n            for (int i = 0; i < K; ++i) {\n                if (used[i]) continue;\n                long long score = 0;\n                for (int j : selected) {\n                    score += potential_max(i, j);\n                }\n                if (score > best_score) {\n                    best_score = score;\n                    best_candidate = i;\n                }\n            }\n            selected.push_back(best_candidate);\n            used[best_candidate] = true;\n        }\n\n        // Map original index to local index (0..35)\n        vector<int> local_idx(K, -1);\n        for (int i = 0; i < 36; ++i) {\n            local_idx[selected[i]] = i;\n        }\n\n        // Precompute potential matrix for the selected seeds\n        vector<vector<int>> pot(36, vector<int>(36));\n        for (int i = 0; i < 36; ++i) {\n            for (int j = 0; j < 36; ++j) {\n                pot[i][j] = potential_max(selected[i], selected[j]);\n            }\n        }\n\n        // Generate an initial assignment: place seeds in row-major order\n        vector<int> init_assign(N*N);\n        for (int cell = 0; cell < N*N; ++cell) {\n            init_assign[cell] = local_idx[selected[cell % 36]];\n        }\n\n        // Run multiple SA runs and keep the best assignment\n        vector<int> best_assign;\n        int best_score_sa = -1;\n\n        for (int run = 0; run < SA_RUNS; ++run) {\n            // Randomly shuffle the assignment\n            vector<int> shuffled_assign = init_assign;\n            shuffle(shuffled_assign.begin(), shuffled_assign.end(), rng);\n            auto [assign, score] = run_sa(shuffled_assign, pot, adj, rng);\n            if (score > best_score_sa) {\n                best_score_sa = score;\n                best_assign = assign;\n            }\n        }\n\n        // Convert local indices back to original seed indices for output\n        vector<vector<int>> grid(N, vector<int>(N));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                int cell = i * N + j;\n                int local = best_assign[cell];\n                grid[i][j] = selected[local];\n            }\n        }\n\n        // Output the grid\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j > 0) cout << \" \";\n                cout << grid[i][j];\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read the next set of seeds (for the next turn)\n        for (int i = 0; i < K; ++i) {\n            for (int l = 0; l < M; ++l) {\n                cin >> seeds[i][l];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <limits>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\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<Point> src_no_target;\n    vector<Point> tgt_no_source;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0')\n                src_no_target.emplace_back(i, j);\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0')\n                tgt_no_source.emplace_back(i, j);\n        }\n    }\n\n    // Initial pairing by sorting coordinates\n    sort(src_no_target.begin(), src_no_target.end(), [](const Point& a, const Point& b) {\n        return a.x < b.x || (a.x == b.x && a.y < b.y);\n    });\n    sort(tgt_no_source.begin(), tgt_no_source.end(), [](const Point& a, const Point& b) {\n        return a.x < b.x || (a.x == b.x && a.y < b.y);\n    });\n\n    vector<pair<Point, Point>> pairs;\n    for (size_t i = 0; i < src_no_target.size(); ++i) {\n        pairs.emplace_back(src_no_target[i], tgt_no_source[i]);\n    }\n\n    int V_prime = 2;\n    cout << V_prime << '\\n';\n    int L = N / 2; // edge length\n    cout << 0 << ' ' << L << '\\n';\n\n    int init_x = N / 2, init_y = N / 2;\n    cout << init_x << ' ' << init_y << '\\n';\n\n    int rx = init_x, ry = init_y;\n    int leaf_dir = 0;\n    bool leaf_holding = false;\n\n    vector<vector<bool>> occupied(N, vector<bool>(N, false));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') occupied[i][j] = true;\n        }\n    }\n\n    vector<string> ops;\n\n    auto add_turn = [&](char move, int rot_vertex, char rot, int grab_vertex, char grab) {\n        string s(2 * V_prime, '.');\n        s[0] = move;\n        if (rot_vertex != -1) {\n            s[rot_vertex] = rot;\n        }\n        if (grab_vertex != -1) {\n            s[V_prime + grab_vertex] = grab;\n        }\n        ops.push_back(s);\n    };\n\n    auto move_to = [&](int tx, int ty) {\n        while (rx != tx) {\n            if (rx > tx) {\n                add_turn('U', -1, '.', -1, '.');\n                --rx;\n            } else {\n                add_turn('D', -1, '.', -1, '.');\n                ++rx;\n            }\n        }\n        while (ry != ty) {\n            if (ry > ty) {\n                add_turn('L', -1, '.', -1, '.');\n                --ry;\n            } else {\n                add_turn('R', -1, '.', -1, '.');\n                ++ry;\n            }\n        }\n    };\n\n    auto rotate_to = [&](int target_dir) {\n        int steps = (target_dir - leaf_dir + 4) % 4;\n        if (steps == 0) return;\n        if (steps == 1) {\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = target_dir;\n        } else if (steps == 3) {\n            add_turn('.', 1, 'L', -1, '.');\n            leaf_dir = target_dir;\n        } else {\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = (leaf_dir + 1) % 4;\n            add_turn('.', 1, 'R', -1, '.');\n            leaf_dir = target_dir;\n        }\n    };\n\n    // Precompute neighbors for each point (at distance L) with direction\n    vector<vector<pair<Point, int>>> src_neighbors(pairs.size());\n    vector<vector<pair<Point, int>>> dst_neighbors(pairs.size());\n    for (size_t i = 0; i < pairs.size(); ++i) {\n        const Point& src = pairs[i].first;\n        const Point& dst = pairs[i].second;\n\n        // For source: root positions such that leaf points to source\n        // right (0): root at (src.x, src.y - L)\n        if (src.y - L >= 0) src_neighbors[i].emplace_back(Point(src.x, src.y - L), 0);\n        // left (2): root at (src.x, src.y + L)\n        if (src.y + L < N) src_neighbors[i].emplace_back(Point(src.x, src.y + L), 2);\n        // down (1): root at (src.x - L, src.y)\n        if (src.x - L >= 0) src_neighbors[i].emplace_back(Point(src.x - L, src.y), 1);\n        // up (3): root at (src.x + L, src.y)\n        if (src.x + L < N) src_neighbors[i].emplace_back(Point(src.x + L, src.y), 3);\n\n        // For target: root positions such that leaf points to target\n        // right (0): root at (dst.x, dst.y - L)\n        if (dst.y - L >= 0) dst_neighbors[i].emplace_back(Point(dst.x, dst.y - L), 0);\n        // left (2): root at (dst.x, dst.y + L)\n        if (dst.y + L < N) dst_neighbors[i].emplace_back(Point(dst.x, dst.y + L), 2);\n        // down (1): root at (dst.x - L, dst.y)\n        if (dst.x - L >= 0) dst_neighbors[i].emplace_back(Point(dst.x - L, dst.y), 1);\n        // up (3): root at (dst.x + L, dst.y)\n        if (dst.x + L < N) dst_neighbors[i].emplace_back(Point(dst.x + L, dst.y), 3);\n    }\n\n    vector<bool> used(pairs.size(), false);\n    int remaining = pairs.size();\n\n    while (remaining > 0) {\n        if (!leaf_holding) {\n            // Find best pair to pickup\n            int best_idx = -1;\n            int best_cost = numeric_limits<int>::max();\n            Point best_pickup_root, best_dropoff_root;\n            int best_pickup_dir = -1, best_dropoff_dir = -1;\n\n            for (size_t i = 0; i < pairs.size(); ++i) {\n                if (used[i]) continue;\n                const Point& src = pairs[i].first;\n                const Point& dst = pairs[i].second;\n\n                // Try all combinations of pickup and dropoff neighbors\n                for (const auto& p_info : src_neighbors[i]) {\n                    const Point& p = p_info.first;\n                    int p_dir = p_info.second;\n                    for (const auto& d_info : dst_neighbors[i]) {\n                        const Point& d = d_info.first;\n                        int d_dir = d_info.second;\n                        int cost = manhattan(Point(rx, ry), p) + manhattan(p, d);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_idx = i;\n                            best_pickup_root = p;\n                            best_dropoff_root = d;\n                            best_pickup_dir = p_dir;\n                            best_dropoff_dir = d_dir;\n                        }\n                    }\n                }\n            }\n\n            if (best_idx == -1) break;\n\n            // Move to pickup root and grab\n            move_to(best_pickup_root.x, best_pickup_root.y);\n            rotate_to(best_pickup_dir);\n            if (!leaf_holding && occupied[pairs[best_idx].first.x][pairs[best_idx].first.y]) {\n                add_turn('.', 1, '.', 1, 'P');\n                leaf_holding = true;\n                occupied[pairs[best_idx].first.x][pairs[best_idx].first.y] = false;\n            }\n\n            // Move to dropoff root and release\n            move_to(best_dropoff_root.x, best_dropoff_root.y);\n            rotate_to(best_dropoff_dir);\n            if (leaf_holding && !occupied[pairs[best_idx].second.x][pairs[best_idx].second.y]) {\n                add_turn('.', 1, '.', 1, 'P');\n                leaf_holding = false;\n                occupied[pairs[best_idx].second.x][pairs[best_idx].second.y] = true;\n            }\n\n            used[best_idx] = true;\n            --remaining;\n        } else {\n            // Should not happen, but break if stuck\n            break;\n        }\n    }\n\n    for (const string& s : ops) {\n        cout << s << '\\n';\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_PERIMETER = 400000;\nconst vector<int> GRID_SIZES = {500, 250, 125};  // add finer grid\n\nstruct Rectangle {\n    int left, right, top, bottom;\n    int net;\n    int x_min, x_max, y_min, y_max;\n\n    Rectangle() : net(0) {}\n    Rectangle(int l, int r, int t, int b, int net_val,\n              const vector<int>& x_start, const vector<int>& x_end,\n              const vector<int>& y_start, const vector<int>& y_end)\n        : left(l), right(r), top(t), bottom(b), net(net_val) {\n        x_min = x_start[left];\n        x_max = x_end[right];\n        y_min = y_start[top];\n        y_max = y_end[bottom];\n    }\n\n    int perimeter() const {\n        int width = x_max - x_min + 1;\n        int height = y_max - y_min + 1;\n        return 2 * (width + height);\n    }\n};\n\nRectangle find_best_rectangle(const vector<vector<int>>& net, int G) {\n    int rows = net.size();\n    int cols = net[0].size();\n\n    vector<int> x_start(cols), x_end(cols);\n    for (int j = 0; j < cols; ++j) {\n        x_start[j] = j * G;\n        x_end[j] = (j == cols - 1) ? MAX_COORD : (j + 1) * G - 1;\n    }\n    vector<int> y_start(rows), y_end(rows);\n    for (int i = 0; i < rows; ++i) {\n        y_start[i] = i * G;\n        y_end[i] = (i == rows - 1) ? MAX_COORD : (i + 1) * G - 1;\n    }\n\n    Rectangle best;\n    best.net = 0;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (net[i][j] == 0) {\n                best = Rectangle(j, j, i, i, 0, x_start, x_end, y_start, y_end);\n                break;\n            }\n        }\n        if (best.net == 0) break;\n    }\n\n    for (int top = 0; top < rows; ++top) {\n        vector<int> col_sum(cols, 0);\n        for (int bottom = top; bottom < rows; ++bottom) {\n            for (int c = 0; c < cols; ++c) {\n                col_sum[c] += net[bottom][c];\n            }\n            int cur = 0, best_cur = 0;\n            int start = 0, best_start = 0, best_end = -1;\n            for (int c = 0; c < cols; ++c) {\n                if (cur <= 0) {\n                    cur = col_sum[c];\n                    start = c;\n                } else {\n                    cur += col_sum[c];\n                }\n                if (cur > best_cur) {\n                    best_cur = cur;\n                    best_start = start;\n                    best_end = c;\n                }\n            }\n            if (best_end == -1) continue;\n\n            Rectangle candidate(best_start, best_end, top, bottom, best_cur,\n                                x_start, x_end, y_start, y_end);\n            if (candidate.perimeter() <= MAX_PERIMETER && candidate.net > best.net) {\n                best = candidate;\n            }\n        }\n    }\n    return best;\n}\n\nstruct RegionGrower {\n    int G, rows, cols;\n    const vector<vector<int>>& net;\n    vector<vector<bool>> in_region;\n    int perimeter, total_net;\n    vector<pair<int, int>> region_cells;\n\n    static const int dx[4];\n    static const int dy[4];\n\n    RegionGrower(int G, const vector<vector<int>>& net)\n        : G(G), net(net), rows(net.size()), cols(net[0].size()) {\n        in_region.assign(rows, vector<bool>(cols, false));\n        perimeter = 0;\n        total_net = 0;\n    }\n\n    void add_cell(int i, int j) {\n        in_region[i][j] = true;\n        region_cells.emplace_back(i, j);\n        total_net += net[i][j];\n        int neighbors = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                ++neighbors;\n        }\n        perimeter += 4 - 2 * neighbors;\n    }\n\n    void grow() {\n        // Find seed with maximum net\n        int best_i = -1, best_j = -1, best_val = -1e9;\n        for (int i = 0; i < rows; ++i) {\n            for (int j = 0; j < cols; ++j) {\n                if (net[i][j] > best_val) {\n                    best_val = net[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        if (best_val <= 0) return;\n        add_cell(best_i, best_j);\n\n        set<pair<int, int>> candidates;\n        for (int d = 0; d < 4; ++d) {\n            int ni = best_i + dx[d], nj = best_j + dy[d];\n            if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                candidates.insert({ni, nj});\n        }\n\n        while (!candidates.empty() && perimeter <= MAX_PERIMETER) {\n            double best_priority = -1e18;\n            pair<int, int> best_cand;\n            for (const auto& cand : candidates) {\n                int i = cand.first, j = cand.second;\n                // Only consider cells with non-negative net\n                if (net[i][j] < 0) continue;\n                int delta_net = net[i][j];\n                int neighbors = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                        ++neighbors;\n                }\n                int delta_perim = 4 - 2 * neighbors;\n                double priority;\n                if (delta_perim > 0)\n                    priority = delta_net / (double)delta_perim;\n                else\n                    priority = delta_net * 1000.0;  // strongly favor perimeter reduction\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_cand = cand;\n                }\n            }\n            if (best_priority <= 0) break;\n\n            int i = best_cand.first, j = best_cand.second;\n            candidates.erase(best_cand);\n\n            int neighbors = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && in_region[ni][nj])\n                    ++neighbors;\n            }\n            int delta_perim = 4 - 2 * neighbors;\n            if (perimeter + delta_perim > MAX_PERIMETER)\n                continue;\n\n            add_cell(i, j);\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < rows && nj >= 0 && nj < cols && !in_region[ni][nj])\n                    candidates.insert({ni, nj});\n            }\n        }\n    }\n};\n\nconst int RegionGrower::dx[4] = {1, -1, 0, 0};\nconst int RegionGrower::dy[4] = {0, 0, 1, -1};\n\nvector<pair<int, int>> trace_boundary(const vector<vector<bool>>& in_region, int G, int rows, int cols) {\n    map<pair<int, int>, vector<pair<int, int>>> graph;\n    for (int i = 0; i < rows; ++i) {\n        for (int j = 0; j < cols; ++j) {\n            if (!in_region[i][j]) continue;\n            if (j == 0 || !in_region[i][j - 1]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, j * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (j == cols - 1 || !in_region[i][j + 1]) {\n                pair<int, int> p1 = {i * G, (j + 1) * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == 0 || !in_region[i - 1][j]) {\n                pair<int, int> p1 = {i * G, j * G};\n                pair<int, int> p2 = {i * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n            if (i == rows - 1 || !in_region[i + 1][j]) {\n                pair<int, int> p1 = {(i + 1) * G, j * G};\n                pair<int, int> p2 = {(i + 1) * G, (j + 1) * G};\n                graph[p1].push_back(p2);\n                graph[p2].push_back(p1);\n            }\n        }\n    }\n    if (graph.empty()) return {};\n\n    auto start = graph.begin()->first;\n    vector<pair<int, int>> cycle;\n    pair<int, int> cur = start;\n    pair<int, int> prev = {-1, -1};\n    do {\n        cycle.push_back(cur);\n        const auto& neighbors = graph[cur];\n        pair<int, int> next;\n        for (const auto& nb : neighbors) {\n            if (nb != prev) {\n                next = nb;\n                break;\n            }\n        }\n        prev = cur;\n        cur = next;\n    } while (cur != start);\n\n    // Simplify collinear points\n    vector<pair<int, int>> simplified;\n    int n = cycle.size();\n    for (int i = 0; i < n; ++i) {\n        auto prev = cycle[(i - 1 + n) % n];\n        auto cur = cycle[i];\n        auto next = cycle[(i + 1) % n];\n        if (prev.first == cur.first && cur.first == next.first) continue;\n        if (prev.second == cur.second && cur.second == next.second) continue;\n        simplified.push_back(cur);\n    }\n    return simplified;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) cin >> mackerels[i].first >> mackerels[i].second;\n    for (int i = 0; i < N; ++i) cin >> sardines[i].first >> sardines[i].second;\n\n    int best_net = 0;\n    vector<pair<int, int>> best_polygon;\n    bool found_nonempty = false;\n\n    for (int G : GRID_SIZES) {\n        int rows = (MAX_COORD + G) / G;\n        int cols = rows;\n\n        vector<vector<int>> count_m(rows, vector<int>(cols, 0));\n        vector<vector<int>> count_s(rows, vector<int>(cols, 0));\n\n        for (auto& p : mackerels) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_m[i][j];\n        }\n        for (auto& p : sardines) {\n            int i = p.first / G, j = p.second / G;\n            if (i < rows && j < cols) ++count_s[i][j];\n        }\n\n        vector<vector<int>> net(rows, vector<int>(cols));\n        for (int i = 0; i < rows; ++i)\n            for (int j = 0; j < cols; ++j)\n                net[i][j] = count_m[i][j] - count_s[i][j];\n\n        // Rectangle search\n        Rectangle rect = find_best_rectangle(net, G);\n        if (rect.net > best_net) {\n            best_net = rect.net;\n            best_polygon = {\n                {rect.x_min, rect.y_min},\n                {rect.x_max, rect.y_min},\n                {rect.x_max, rect.y_max},\n                {rect.x_min, rect.y_max}\n            };\n            found_nonempty = (best_net > 0);\n        }\n\n        // Region growing\n        RegionGrower grower(G, net);\n        grower.grow();\n        if (grower.total_net > best_net) {\n            best_net = grower.total_net;\n            best_polygon = trace_boundary(grower.in_region, G, rows, cols);\n            found_nonempty = (best_net > 0);\n        }\n    }\n\n    if (!found_nonempty) {\n        best_polygon = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};\n    }\n\n    cout << best_polygon.size() << \"\\n\";\n    for (auto& p : best_polygon) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <map>\n#include <set>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Structure for a placement instruction\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference index or -1\n};\n\n// Simulation state: bounding boxes of placed rectangles\nstruct Rect {\n    double x1, y1, x2, y2;\n};\n\n// Check if two rectangles overlap (allowing touching)\nbool overlap(const Rect& a, const Rect& b) {\n    return (a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1);\n}\n\n// Simulate the placement sequence using estimated dimensions.\n// Returns true if valid (no overlap, all coordinates non-negative).\n// Also returns the bounding box (W, H).\nbool simulate(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est,\n              double& W, double& H, map<int, Rect>& boxes) {\n    boxes.clear();\n    W = 0.0;\n    H = 0.0;\n    set<int> placed;\n    for (const Placement& pl : seq) {\n        int id = pl.p;\n        double w, h;\n        if (pl.r == 0) {\n            w = w_est[id];\n            h = h_est[id];\n        } else {\n            w = h_est[id];\n            h = w_est[id];\n        }\n        Rect r;\n        if (pl.d == 'U') {\n            if (pl.b == -1) {\n                r.x1 = 0.0;\n                r.y1 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x1 = ref.x2;\n                r.y1 = ref.y2;\n            }\n            r.x2 = r.x1 + w;\n            r.y2 = r.y1 + h;\n        } else if (pl.d == 'L') {\n            if (pl.b == -1) {\n                r.x2 = 0.0;\n                r.y2 = 0.0;\n            } else {\n                if (boxes.find(pl.b) == boxes.end()) return false;\n                const Rect& ref = boxes[pl.b];\n                r.x2 = ref.x1;\n                r.y2 = ref.y1;\n            }\n            r.x1 = r.x2 - w;\n            r.y1 = r.y2 - h;\n        } else {\n            return false; // invalid direction\n        }\n        // Check bounds\n        if (r.x1 < 0.0 || r.y1 < 0.0) return false;\n        // Check overlap with existing rectangles\n        for (const auto& kv : boxes) {\n            if (overlap(r, kv.second)) return false;\n        }\n        boxes[id] = r;\n        placed.insert(id);\n        W = max(W, r.x2);\n        H = max(H, r.y2);\n    }\n    return true;\n}\n\n// Compute estimated score for a sequence\ndouble estimated_score(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est) {\n    map<int, Rect> boxes;\n    double W, H;\n    if (!simulate(seq, w_est, h_est, W, H, boxes)) {\n        return 1e30; // invalid\n    }\n    set<int> placed;\n    for (const Placement& pl : seq) placed.insert(pl.p);\n    double penalty = 0.0;\n    for (size_t i = 0; i < w_est.size(); ++i) {\n        if (placed.count(i) == 0) {\n            penalty += w_est[i] + h_est[i];\n        }\n    }\n    return W + H + penalty;\n}\n\n// Local improvement: try flipping rotation of each rectangle in sequence\nvector<Placement> improve_sequence(vector<Placement> seq, const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    double best_score = estimated_score(seq, w_est, h_est);\n    for (size_t i = 0; i < seq.size(); ++i) {\n        // Flip rotation\n        seq[i].r = 1 - seq[i].r;\n        double new_score = estimated_score(seq, w_est, h_est);\n        if (new_score < best_score) {\n            best_score = new_score;\n        } else {\n            // revert\n            seq[i].r = 1 - seq[i].r;\n        }\n    }\n    return seq;\n}\n\n// Local search: try to change each placement (rotation, direction, reference)\nvector<Placement> local_search(vector<Placement> seq, const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, int max_passes = 3) {\n    double best_score = estimated_score(seq, w_est, h_est);\n    for (int pass = 0; pass < max_passes; ++pass) {\n        bool improved = false;\n        for (size_t i = 0; i < seq.size(); ++i) {\n            int idx = seq[i].p;\n            vector<Placement> candidates;\n            // current\n            candidates.push_back(seq[i]);\n            // flip rotation\n            Placement pl = seq[i];\n            pl.r = 1 - pl.r;\n            candidates.push_back(pl);\n            // change direction\n            pl = seq[i];\n            pl.d = (pl.d == 'U') ? 'L' : 'U';\n            if (pl.d == 'L' && pl.b == -1) {\n                // need a reference if L\n                vector<int> earlier;\n                for (int j = 0; j < i; ++j) earlier.push_back(seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                    candidates.push_back(pl);\n                }\n            } else {\n                candidates.push_back(pl);\n            }\n            // change reference to -1 (if allowed)\n            if (seq[i].d != 'L' || seq[i].b != -1) {\n                Placement pl2 = seq[i];\n                pl2.b = -1;\n                if (!(pl2.d == 'L' && pl2.b == -1)) {\n                    candidates.push_back(pl2);\n                }\n            }\n            // change reference to another earlier rectangle\n            vector<int> earlier;\n            for (int j = 0; j < i; ++j) earlier.push_back(seq[j].p);\n            for (int b : earlier) {\n                if (b == seq[i].b) continue;\n                Placement pl2 = seq[i];\n                pl2.b = b;\n                candidates.push_back(pl2);\n            }\n            // try each candidate\n            for (const Placement& cand : candidates) {\n                vector<Placement> new_seq = seq;\n                new_seq[i] = cand;\n                double score = estimated_score(new_seq, w_est, h_est);\n                if (score < best_score) {\n                    best_score = score;\n                    seq = new_seq;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break; // restart pass\n        }\n        if (!improved) break;\n    }\n    return seq;\n}\n\n// Beam search packing (without balance term)\nvector<Placement> beam_search(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng, int beam_width = 20) {\n    int N = w_est.size();\n    double total_sum_est = 0.0;\n    for (int i = 0; i < N; ++i) total_sum_est += w_est[i] + h_est[i];\n\n    struct State {\n        vector<Placement> seq;\n        double curW, curH;\n        set<int> placed;\n        double placed_sum; // sum of (w+h) for placed rectangles\n        double heuristic; // curW+curH + (total_sum_est - placed_sum)\n    };\n\n    vector<State> beam;\n    beam.push_back({{}, 0.0, 0.0, {}, 0.0, total_sum_est});\n\n    for (int i = 0; i < N; ++i) {\n        vector<State> candidates;\n        for (const State& st : beam) {\n            // Option: skip rectangle i\n            State skip_st = st;\n            skip_st.heuristic = st.curW + st.curH + (total_sum_est - st.placed_sum);\n            candidates.push_back(skip_st);\n\n            // Option: place rectangle i with all valid placements\n            for (int rot = 0; rot < 2; ++rot) {\n                for (char dir : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (int idx : st.placed) refs.push_back(idx);\n                    for (int b : refs) {\n                        if (dir == 'L' && b == -1) continue;\n                        Placement pl{i, rot, dir, b};\n                        vector<Placement> test_seq = st.seq;\n                        test_seq.push_back(pl);\n                        map<int, Rect> test_boxes;\n                        double newW, newH;\n                        if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                            double new_placed_sum = st.placed_sum + w_est[i] + h_est[i];\n                            double new_heuristic = newW + newH + (total_sum_est - new_placed_sum);\n                            State new_st = {test_seq, newW, newH, st.placed, new_placed_sum, new_heuristic};\n                            new_st.placed.insert(i);\n                            candidates.push_back(new_st);\n                        }\n                    }\n                }\n            }\n        }\n        // sort candidates by heuristic\n        sort(candidates.begin(), candidates.end(),\n             [](const State& a, const State& b) { return a.heuristic < b.heuristic; });\n        // keep top beam_width, with tie-breaking by randomness\n        beam.clear();\n        if (candidates.size() <= beam_width) {\n            beam = candidates;\n        } else {\n            // take first beam_width, but if there are ties at the boundary, randomize\n            double threshold = candidates[beam_width-1].heuristic;\n            vector<State> top;\n            for (const State& st : candidates) {\n                if (st.heuristic < threshold) top.push_back(st);\n            }\n            // add remaining with heuristic == threshold until we have beam_width\n            for (const State& st : candidates) {\n                if (top.size() >= beam_width) break;\n                if (st.heuristic == threshold) top.push_back(st);\n            }\n            // shuffle top to randomize ties\n            shuffle(top.begin(), top.end(), rng);\n            beam.assign(top.begin(), top.begin() + beam_width);\n        }\n    }\n    // among final beam, pick the one with smallest heuristic (which is estimated score)\n    State best = beam[0];\n    for (const State& st : beam) {\n        if (st.heuristic < best.heuristic) best = st;\n    }\n    return best.seq;\n}\n\n// Generate a random valid sequence\nvector<Placement> random_valid_sequence(const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> seq;\n    map<int, Rect> current_boxes;\n    double curW = 0.0, curH = 0.0;\n    set<int> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Decide whether to place this rectangle (probability 0.9)\n        if (uniform_real_distribution<double>(0,1)(rng) > 0.9) continue;\n        // Try to place with random parameters\n        for (int attempt = 0; attempt < 10; ++attempt) {\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_real_distribution<double>(0,1)(rng) < 0.5) ? 'U' : 'L';\n            vector<int> refs = {-1};\n            for (int idx : placed) refs.push_back(idx);\n            int b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n            if (dir == 'L' && b == -1) continue; // invalid\n            Placement pl{i, rot, dir, b};\n            vector<Placement> test_seq = seq;\n            test_seq.push_back(pl);\n            map<int, Rect> test_boxes;\n            double newW, newH;\n            if (simulate(test_seq, w_est, h_est, newW, newH, test_boxes)) {\n                // Valid\n                seq.push_back(pl);\n                current_boxes = test_boxes;\n                curW = newW;\n                curH = newH;\n                placed.insert(i);\n                break;\n            }\n        }\n        // if not placed after attempts, skip\n    }\n    return seq;\n}\n\n// Mutation of a sequence (only modify or add, no removal)\nvector<Placement> mutate_sequence(const vector<Placement>& seq, const vector<double>& w_est, const vector<double>& h_est, mt19937& rng) {\n    int N = w_est.size();\n    vector<Placement> new_seq = seq;\n    if (new_seq.empty() || uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n        // Try to add a rectangle not yet placed\n        set<int> placed_ids;\n        for (const auto& pl : new_seq) placed_ids.insert(pl.p);\n        vector<int> not_placed;\n        for (int i = 0; i < N; ++i) if (placed_ids.count(i) == 0) not_placed.push_back(i);\n        if (!not_placed.empty()) {\n            int id = not_placed[uniform_int_distribution<int>(0, not_placed.size()-1)(rng)];\n            int rot = uniform_int_distribution<int>(0,1)(rng);\n            char dir = (uniform_int_distribution<int>(0,1)(rng) == 0) ? 'U' : 'L';\n            int b = -1;\n            if (dir == 'L') {\n                if (!new_seq.empty()) {\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n                if (b == -1) return new_seq; // cannot add L with b=-1\n            } else {\n                if (!new_seq.empty() && uniform_int_distribution<int>(0,1)(rng) == 0) {\n                    vector<int> refs;\n                    for (const auto& pl : new_seq) refs.push_back(pl.p);\n                    b = refs[uniform_int_distribution<int>(0, refs.size()-1)(rng)];\n                }\n            }\n            Placement pl{id, rot, dir, b};\n            auto it = lower_bound(new_seq.begin(), new_seq.end(), pl,\n                [](const Placement& a, const Placement& b) { return a.p < b.p; });\n            new_seq.insert(it, pl);\n        }\n    } else {\n        // Modify a random placement\n        int idx = uniform_int_distribution<int>(0, new_seq.size()-1)(rng);\n        Placement& pl = new_seq[idx];\n        int choice = uniform_int_distribution<int>(0,2)(rng);\n        if (choice == 0) {\n            // flip rotation\n            pl.r = 1 - pl.r;\n        } else if (choice == 1) {\n            // change direction\n            pl.d = (pl.d == 'U') ? 'L' : 'U';\n            // if direction becomes L and b == -1, set b to some earlier reference\n            if (pl.d == 'L' && pl.b == -1) {\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                } else {\n                    // no earlier reference, revert direction\n                    pl.d = 'U';\n                }\n            }\n        } else {\n            // change reference\n            if (pl.b == -1) {\n                // try to set to some earlier placed rectangle\n                vector<int> earlier;\n                for (int j = 0; j < idx; ++j) earlier.push_back(new_seq[j].p);\n                if (!earlier.empty()) {\n                    pl.b = earlier[uniform_int_distribution<int>(0, earlier.size()-1)(rng)];\n                }\n            } else {\n                // change to another reference or -1\n                vector<int> candidates = {-1};\n                for (int j = 0; j < idx; ++j) candidates.push_back(new_seq[j].p);\n                pl.b = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(rng)];\n            }\n        }\n    }\n    return new_seq;\n}\n\nstruct Candidate {\n    vector<Placement> seq;\n    double best_actual_score; // best observed actual score\n    double est_score; // estimated score (based on current estimates)\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    vector<int> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Initialize measurement accumulators with the initial observations as one measurement each\n    vector<double> w_meas_sum(N), h_meas_sum(N);\n    vector<int> cnt_w(N, 1), cnt_h(N, 1);\n    for (int i = 0; i < N; ++i) {\n        w_meas_sum[i] = w_obs[i];\n        h_meas_sum[i] = h_obs[i];\n    }\n    // Current estimates\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = w_meas_sum[i] / cnt_w[i];\n        h_est[i] = h_meas_sum[i] / cnt_h[i];\n    }\n\n    // Measurement attempts: measure each rectangle twice (once r=0, once r=1) if possible\n    int M = min(2 * N, T - 10); // ensure at least 10 packing attempts\n    if (M < 0) M = 0;\n    vector<int> meas_cnt(N, 0); // number of measurements done per rectangle (0,1,2)\n    int measurement_done = 0;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Placement> best_actual_seq;\n    double best_actual_score = 1e30;\n\n    // Evolutionary pool\n    vector<Candidate> pool;\n    int pool_limit = 30;\n\n    for (int t = 0; t < T; ++t) {\n        // Measurement phase\n        if (measurement_done < M) {\n            // Choose a rectangle that hasn't been measured twice\n            vector<int> candidates;\n            for (int i = 0; i < N; ++i) if (meas_cnt[i] < 2) candidates.push_back(i);\n            if (!candidates.empty()) {\n                int i = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(rng)];\n                // Choose rotation based on measurement count: first r=0, then r=1\n                int r = (meas_cnt[i] == 0) ? 0 : 1;\n                // Output single rectangle placement\n                cout << 1 << '\\n';\n                cout << i << ' ' << r << ' ' << 'U' << ' ' << -1 << '\\n';\n                cout.flush();\n\n                int W_meas, H_meas;\n                cin >> W_meas >> H_meas;\n\n                // Update measurements\n                if (r == 0) {\n                    w_meas_sum[i] += W_meas;\n                    h_meas_sum[i] += H_meas;\n                } else {\n                    w_meas_sum[i] += H_meas;\n                    h_meas_sum[i] += W_meas;\n                }\n                cnt_w[i]++;\n                cnt_h[i]++;\n                w_est[i] = w_meas_sum[i] / cnt_w[i];\n                h_est[i] = h_meas_sum[i] / cnt_h[i];\n                meas_cnt[i]++;\n                measurement_done++;\n                continue;\n            }\n        }\n\n        // Evolution phase\n        if (pool.empty()) {\n            // Initialize pool with beam search and random sequences\n            vector<Placement> bs_seq = beam_search(w_est, h_est, rng, 20);\n            double bs_est = estimated_score(bs_seq, w_est, h_est);\n            if (bs_est < 1e30) {\n                bs_seq = improve_sequence(bs_seq, w_est, h_est, rng);\n                bs_seq = local_search(bs_seq, w_est, h_est, rng, 2);\n                bs_est = estimated_score(bs_seq, w_est, h_est);\n                pool.push_back({bs_seq, 1e30, bs_est});\n            }\n            for (int i = 0; i < 3; ++i) {\n                vector<Placement> rand_seq = random_valid_sequence(w_est, h_est, rng);\n                double rand_est = estimated_score(rand_seq, w_est, h_est);\n                if (rand_est < 1e30) {\n                    rand_seq = improve_sequence(rand_seq, w_est, h_est, rng);\n                    rand_seq = local_search(rand_seq, w_est, h_est, rng, 2);\n                    rand_est = estimated_score(rand_seq, w_est, h_est);\n                    pool.push_back({rand_seq, 1e30, rand_est});\n                }\n            }\n            // If pool still empty, add beam search again\n            if (pool.empty()) {\n                pool.push_back({bs_seq, 1e30, bs_est});\n            }\n        }\n\n        // Select a candidate to evaluate\n        int chosen_idx = 0;\n        if (uniform_real_distribution<double>(0,1)(rng) < 0.2) {\n            // Random exploration\n            chosen_idx = uniform_int_distribution<int>(0, pool.size()-1)(rng);\n        } else {\n            // Choose the one with best actual score (if any) or best estimated score\n            double best_score = 1e30;\n            for (size_t i = 0; i < pool.size(); ++i) {\n                double score = pool[i].best_actual_score;\n                if (score > 1e20) score = pool[i].est_score;\n                if (score < best_score) {\n                    best_score = score;\n                    chosen_idx = i;\n                }\n            }\n        }\n\n        Candidate& cand = pool[chosen_idx];\n        vector<Placement> output_seq = cand.seq;\n\n        // Ensure the sequence is valid before output\n        {\n            map<int, Rect> dummy_boxes;\n            double dummyW, dummyH;\n            if (!simulate(output_seq, w_est, h_est, dummyW, dummyH, dummy_boxes)) {\n                // fallback to beam search\n                output_seq = beam_search(w_est, h_est, rng, 20);\n                output_seq = improve_sequence(output_seq, w_est, h_est, rng);\n                output_seq = local_search(output_seq, w_est, h_est, rng, 2);\n            }\n        }\n\n        // Output the sequence\n        cout << output_seq.size() << '\\n';\n        for (const Placement& pl : output_seq) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout.flush();\n\n        // Read measurement\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n\n        // Compute actual score\n        set<int> placed_ids;\n        for (const Placement& pl : output_seq) placed_ids.insert(pl.p);\n        double penalty = 0.0;\n        for (int i = 0; i < N; ++i) {\n            if (placed_ids.count(i) == 0) {\n                penalty += w_est[i] + h_est[i];\n            }\n        }\n        double score = W_meas + H_meas + penalty;\n\n        // Update candidate's best actual score\n        if (score < cand.best_actual_score) {\n            cand.best_actual_score = score;\n            // Also update best overall\n            if (score < best_actual_score) {\n                best_actual_score = score;\n                best_actual_seq = output_seq;\n            }\n        }\n\n        // Generate mutated candidate and add to pool if valid\n        if (pool.size() < pool_limit) {\n            vector<Placement> mutated = mutate_sequence(output_seq, w_est, h_est, rng);\n            double mut_est = estimated_score(mutated, w_est, h_est);\n            if (mut_est < 1e30) { // only add if valid\n                mutated = improve_sequence(mutated, w_est, h_est, rng);\n                mutated = local_search(mutated, w_est, h_est, rng, 1);\n                mut_est = estimated_score(mutated, w_est, h_est);\n                pool.push_back({mutated, 1e30, mut_est});\n            }\n        } else if (uniform_real_distribution<double>(0,1)(rng) < 0.3) {\n            // Replace a random candidate with mutated version if valid\n            int replace_idx = uniform_int_distribution<int>(0, pool.size()-1)(rng);\n            vector<Placement> mutated = mutate_sequence(output_seq, w_est, h_est, rng);\n            double mut_est = estimated_score(mutated, w_est, h_est);\n            if (mut_est < 1e30) {\n                mutated = improve_sequence(mutated, w_est, h_est, rng);\n                mutated = local_search(mutated, w_est, h_est, rng, 1);\n                mut_est = estimated_score(mutated, w_est, h_est);\n                pool[replace_idx] = {mutated, 1e30, mut_est};\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int INF = 1000; // larger than any possible distance\n\n// Perform weighted set cover with given cost function\nvector<int> set_cover(const vector<bitset<MAXN>>& cover,\n                      const vector<int>& A, int N,\n                      function<double(int)> cost_func) {\n    bitset<MAXN> uncovered;\n    uncovered.set();\n    vector<int> roots;\n    while (uncovered.any()) {\n        int best = -1;\n        double best_ratio = 1e18;\n        for (int v = 0; v < N; ++v) {\n            bitset<MAXN> cur = cover[v] & uncovered;\n            if (cur.none()) continue;\n            int gain = cur.count();\n            double ratio = cost_func(v) / gain;\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best = v;\n            }\n        }\n        if (best == -1) break;\n        roots.push_back(best);\n        uncovered &= ~cover[best];\n    }\n    return roots;\n}\n\n// Greedy root selection that maximizes increase in sum depth*A\nvector<int> greedy_root_selection(const vector<vector<short>>& dist,\n                                 const vector<int>& A, int N, int H) {\n    vector<short> cur_dist(N, INF);\n    vector<bool> is_root(N, false);\n    vector<int> roots;\n    int covered = 0;\n    while (covered < N) {\n        int best_r = -1;\n        long long best_gain = -1;\n        for (int r = 0; r < N; ++r) {\n            if (is_root[r]) continue;\n            long long gain = 0;\n            for (int v = 0; v < N; ++v) {\n                short d = dist[r][v];\n                if (d > H) continue;\n                if (d < cur_dist[v]) {\n                    int old = (cur_dist[v] == INF) ? H : cur_dist[v];\n                    gain += (old - d) * 1LL * A[v];\n                }\n            }\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break; // should not happen\n        is_root[best_r] = true;\n        roots.push_back(best_r);\n        for (int v = 0; v < N; ++v) {\n            short d = dist[best_r][v];\n            if (d <= H && d < cur_dist[v]) {\n                cur_dist[v] = d;\n            }\n        }\n        covered = 0;\n        for (int v = 0; v < N; ++v) if (cur_dist[v] <= H) covered++;\n    }\n    return roots;\n}\n\n// Build forest from roots: assign each vertex to nearest root, then BFS tree\nvoid build_forest(const vector<int>& roots,\n                  const vector<vector<short>>& dist,\n                  const vector<vector<int>>& adj,\n                  vector<int>& parent,\n                  vector<int>& depth,\n                  vector<int>& root_of,\n                  int N, int H) {\n    // assign nearest root and distance\n    for (int v = 0; v < N; ++v) {\n        int best_r = -1, best_d = INF;\n        for (int r : roots) {\n            int d = dist[v][r];\n            if (d < best_d) {\n                best_d = d;\n                best_r = r;\n            }\n        }\n        root_of[v] = best_r;\n        depth[v] = best_d;\n    }\n\n    // build parent pointers (choose one neighbor closer to root)\n    for (int v = 0; v < N; ++v) {\n        if (root_of[v] == v) {\n            parent[v] = -1;\n            continue;\n        }\n        int r = root_of[v];\n        int d = depth[v];\n        bool found = false;\n        for (int u : adj[v]) {\n            if (root_of[u] == r && dist[u][r] == d - 1) {\n                parent[v] = u;\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            // fallback: any neighbor with same root and smaller distance\n            for (int u : adj[v]) {\n                if (root_of[u] == r && dist[u][r] < d) {\n                    parent[v] = u;\n                    break;\n                }\n            }\n        }\n    }\n}\n\n// Local improvement: try to increase depth of vertices with high A\nvoid local_improvement(vector<int>& parent,\n                       vector<int>& depth,\n                       vector<int>& root_of,\n                       const vector<vector<int>>& adj,\n                       const vector<int>& A,\n                       int N, int H) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // Create order based on potential gain: A[v] * (H - depth[v])\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return A[a] * (H - depth[a]) > A[b] * (H - depth[b]);\n        });\n\n        for (int v : order) {\n            if (parent[v] == -1) continue; // root\n            if (depth[v] >= H) continue; // cannot go deeper\n\n            // Collect subtree of v (descendants)\n            vector<int> subtree;\n            stack<int> stk;\n            stk.push(v);\n            while (!stk.empty()) {\n                int x = stk.top(); stk.pop();\n                subtree.push_back(x);\n                for (int y : adj[x]) {\n                    if (parent[y] == x && root_of[y] == root_of[v]) {\n                        stk.push(y);\n                    }\n                }\n            }\n\n            // Try each neighbor u as potential new parent\n            for (int u : adj[v]) {\n                if (root_of[u] != root_of[v]) continue;\n                if (u == parent[v]) continue; // same parent\n                // u must not be in the subtree of v\n                bool in_subtree = false;\n                for (int x : subtree) {\n                    if (x == u) {\n                        in_subtree = true;\n                        break;\n                    }\n                }\n                if (in_subtree) continue;\n\n                // Only consider if depth[u] >= depth[v] to potentially increase depth\n                if (depth[u] < depth[v]) continue;\n\n                int new_depth_v = depth[u] + 1;\n                if (new_depth_v <= depth[v]) continue; // not increasing\n                if (new_depth_v > H) continue; // would exceed H for v\n\n                int delta = new_depth_v - depth[v];\n                // Check that after increasing, all vertices in subtree have depth <= H\n                bool ok = true;\n                for (int x : subtree) {\n                    if (depth[x] + delta > H) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (!ok) continue;\n\n                // Perform the change\n                parent[v] = u;\n                // Increase depth of all vertices in subtree by delta\n                for (int x : subtree) {\n                    depth[x] += delta;\n                }\n                improved = true;\n                break; // move to next vertex after change\n            }\n        }\n    }\n}\n\n// Greedy attachment forest construction\npair<long long, vector<int>> greedy_forest(const vector<vector<int>>& adj,\n                                           const vector<int>& A, int N, int H) {\n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> assigned(N, false);\n\n    // Priority queue: (gain, v, u) where u is already assigned, v unassigned\n    using State = tuple<long long, int, int>;\n    priority_queue<State> pq;\n\n    auto try_attach = [&](int u, int v) {\n        int d = depth[u];\n        if (d + 1 > H) return;\n        long long gain = (d + 2) * 1LL * A[v]; // contribution after attachment\n        pq.emplace(gain, v, u);\n    };\n\n    // Start with vertex of minimum A as first root\n    int start = min_element(A.begin(), A.end()) - A.begin();\n    assigned[start] = true;\n    depth[start] = 0;\n    parent[start] = -1;\n\n    for (int u : adj[start]) {\n        if (!assigned[u]) try_attach(start, u);\n    }\n\n    int assigned_cnt = 1;\n    while (assigned_cnt < N) {\n        if (pq.empty()) {\n            // Need a new root: pick unassigned vertex with minimum A\n            int best = -1;\n            for (int i = 0; i < N; ++i) {\n                if (!assigned[i]) {\n                    if (best == -1 || A[i] < A[best]) best = i;\n                }\n            }\n            // Make it a root\n            assigned[best] = true;\n            depth[best] = 0;\n            parent[best] = -1;\n            assigned_cnt++;\n            for (int nb : adj[best]) {\n                if (!assigned[nb]) try_attach(best, nb);\n            }\n            continue;\n        }\n\n        auto [gain, v, u] = pq.top();\n        pq.pop();\n        if (assigned[v]) continue;\n        // Assign v\n        assigned[v] = true;\n        parent[v] = u;\n        depth[v] = depth[u] + 1;\n        assigned_cnt++;\n\n        // Add possible attachments for neighbors of v\n        for (int nb : adj[v]) {\n            if (!assigned[nb]) try_attach(v, nb);\n        }\n    }\n\n    // Compute score\n    long long score = 0;\n    for (int v = 0; v < N; ++v) {\n        score += (depth[v] + 1) * 1LL * A[v];\n    }\n    return {score, parent};\n}\n\n// Compute total attractiveness\nlong long compute_score(const vector<int>& depth, const vector<int>& A, int N) {\n    long long score = 0;\n    for (int v = 0; v < N; ++v) {\n        score += (depth[v] + 1) * 1LL * A[v];\n    }\n    return score;\n}\n\n// Try to remove redundant roots to improve score\nvector<int> remove_roots(const vector<int>& roots, const vector<vector<short>>& dist,\n                         const vector<int>& A, int H, int N) {\n    vector<int> cur_roots = roots;\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // Compute current minDist for cur_roots\n        vector<short> cur_minDist(N, INF);\n        for (int v = 0; v < N; ++v) {\n            short md = INF;\n            for (int r : cur_roots) {\n                short d = dist[v][r];\n                if (d < md) md = d;\n            }\n            cur_minDist[v] = md;\n        }\n        long long curScore = 0;\n        for (int v = 0; v < N; ++v) {\n            curScore += (cur_minDist[v] + 1) * 1LL * A[v];\n        }\n        // Try each root removal\n        for (size_t i = 0; i < cur_roots.size(); ++i) {\n            int r = cur_roots[i];\n            vector<int> new_roots;\n            new_roots.reserve(cur_roots.size()-1);\n            for (size_t j = 0; j < cur_roots.size(); ++j) {\n                if (j != i) new_roots.push_back(cur_roots[j]);\n            }\n            // Compute new minDist without r\n            vector<short> new_minDist(N, INF);\n            for (int v = 0; v < N; ++v) {\n                short md = INF;\n                for (int rr : new_roots) {\n                    short d = dist[v][rr];\n                    if (d < md) md = d;\n                }\n                new_minDist[v] = md;\n            }\n            // Check feasibility\n            bool feasible = true;\n            for (int v = 0; v < N; ++v) {\n                if (new_minDist[v] > H) {\n                    feasible = false;\n                    break;\n                }\n            }\n            if (!feasible) continue;\n            // Compute new score\n            long long newScore = 0;\n            for (int v = 0; v < N; ++v) {\n                newScore += (new_minDist[v] + 1) * 1LL * A[v];\n            }\n            if (newScore > curScore) {\n                cur_roots = new_roots;\n                improved = true;\n                break; // restart the while loop\n            }\n        }\n    }\n    return cur_roots;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    // coordinates are not needed for this algorithm\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // All-pairs shortest distances (BFS from each vertex)\n    vector<vector<short>> dist(N, vector<short>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        queue<int> q;\n        dist[s][s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Precompute cover bitsets and total A within cover\n    vector<bitset<MAXN>> cover(N);\n    vector<long long> totalA_cover(N, 0);\n    for (int r = 0; r < N; ++r) {\n        for (int v = 0; v < N; ++v) {\n            short d = dist[r][v];\n            if (d != -1 && d <= H) {\n                cover[r].set(v);\n                totalA_cover[r] += A[v];\n            }\n        }\n    }\n\n    // Try several root selection strategies\n    vector<pair<long long, vector<int>>> candidates;\n\n    auto evaluate = [&](const vector<int>& roots) {\n        vector<int> parent(N, -1);\n        vector<int> depth(N, INF);\n        vector<int> root_of(N, -1);\n        build_forest(roots, dist, adj, parent, depth, root_of, N, H);\n        local_improvement(parent, depth, root_of, adj, A, N, H);\n        long long score = compute_score(depth, A, N);\n        return make_pair(score, parent);\n    };\n\n    // Strategy 1: cost = A[v] (weighted)\n    auto roots1 = set_cover(cover, A, N, [&](int v) { return A[v]; });\n    candidates.push_back(evaluate(roots1));\n\n    // Strategy 2: cost = 1 (unweighted)\n    auto roots2 = set_cover(cover, A, N, [](int v) { return 1.0; });\n    candidates.push_back(evaluate(roots2));\n\n    // Strategy 3: cost = A[v] * (H+1) (penalize high A more)\n    auto roots3 = set_cover(cover, A, N, [&](int v) { return A[v] * (H + 1); });\n    candidates.push_back(evaluate(roots3));\n\n    // Strategy 4: cost = sqrt(A[v]) (less penalty)\n    auto roots4 = set_cover(cover, A, N, [&](int v) { return sqrt(A[v]); });\n    candidates.push_back(evaluate(roots4));\n\n    // Strategy 5: cost = totalA_cover[v] (penalize covering high A)\n    auto roots5 = set_cover(cover, A, N, [&](int v) { return (double)totalA_cover[v]; });\n    candidates.push_back(evaluate(roots5));\n\n    // Strategy 6: greedy attachment forest\n    auto [greedy_score, greedy_parent] = greedy_forest(adj, A, N, H);\n    candidates.emplace_back(greedy_score, greedy_parent);\n\n    // Strategy 7: greedy root selection (maximize increase in depth*A)\n    auto roots7 = greedy_root_selection(dist, A, N, H);\n    candidates.push_back(evaluate(roots7));\n\n    // Choose best\n    int best_idx = 0;\n    for (size_t i = 1; i < candidates.size(); ++i) {\n        if (candidates[i].first > candidates[best_idx].first) {\n            best_idx = i;\n        }\n    }\n\n    // Extract roots from best parent\n    vector<int> cur_roots;\n    const auto& best_parent = candidates[best_idx].second;\n    for (int i = 0; i < N; ++i) {\n        if (best_parent[i] == -1) cur_roots.push_back(i);\n    }\n\n    // Try to remove redundant roots\n    cur_roots = remove_roots(cur_roots, dist, A, H, N);\n\n    // Rebuild forest with improved roots and apply local improvement\n    vector<int> parent(N, -1);\n    vector<int> depth(N, INF);\n    vector<int> root_of(N, -1);\n    build_forest(cur_roots, dist, adj, parent, depth, root_of, N, H);\n    local_improvement(parent, depth, root_of, adj, A, N, H);\n    long long final_score = compute_score(depth, A, N);\n\n    // If final score is better, output that, else output the previous best\n    if (final_score > candidates[best_idx].first) {\n        for (int i = 0; i < N; ++i) {\n            cout << parent[i];\n            if (i < N - 1) cout << ' ';\n        }\n    } else {\n        for (int i = 0; i < N; ++i) {\n            cout << candidates[best_idx].second[i];\n            if (i < N - 1) cout << ' ';\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<pair<char, int>> moves;\n    const size_t MAX_MOVES = 4 * N * N;\n\n    // Helper functions to perform a single shift and record the move\n    auto shiftRowLeft = [&](int i) {\n        for (int j = 0; j < N - 1; ++j) {\n            board[i][j] = board[i][j + 1];\n        }\n        board[i][N - 1] = '.';\n        moves.push_back({'L', i});\n    };\n\n    auto shiftRowRight = [&](int i) {\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n        moves.push_back({'R', i});\n    };\n\n    auto shiftColUp = [&](int j) {\n        for (int i = 0; i < N - 1; ++i) {\n            board[i][j] = board[i + 1][j];\n        }\n        board[N - 1][j] = '.';\n        moves.push_back({'U', j});\n    };\n\n    auto shiftColDown = [&](int j) {\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n        moves.push_back({'D', j});\n    };\n\n    // Check if a shift can be performed safely (edge not Fukunokami)\n    auto canShiftSafely = [&](char dir, int idx) -> bool {\n        if (dir == 'L') {\n            return board[idx][0] != 'o';\n        } else if (dir == 'R') {\n            return board[idx][N-1] != 'o';\n        } else if (dir == 'U') {\n            return board[0][idx] != 'o';\n        } else { // 'D'\n            return board[N-1][idx] != 'o';\n        }\n    };\n\n    // Try to remove a specific Oni by attempting each direction, checking safety per shift\n    auto tryRemoveOni = [&](int i, int j) -> bool {\n        vector<pair<char, int>> directions = {\n            {'U', j},\n            {'D', j},\n            {'L', i},\n            {'R', i}\n        };\n        vector<int> shifts_needed = {i+1, N-i, j+1, N-j};\n        \n        for (int d = 0; d < 4; ++d) {\n            char dir = directions[d].first;\n            int idx = directions[d].second;\n            int shifts = shifts_needed[d];\n            \n            bool safe = true;\n            vector<string> temp = board;\n            for (int s = 0; s < shifts; ++s) {\n                if (!canShiftSafely(dir, idx)) {\n                    safe = false;\n                    break;\n                }\n                // Perform the shift on temp board\n                if (dir == 'L') {\n                    for (int c = 0; c < N-1; ++c) temp[i][c] = temp[i][c+1];\n                    temp[i][N-1] = '.';\n                } else if (dir == 'R') {\n                    for (int c = N-1; c > 0; --c) temp[i][c] = temp[i][c-1];\n                    temp[i][0] = '.';\n                } else if (dir == 'U') {\n                    for (int r = 0; r < N-1; ++r) temp[r][j] = temp[r+1][j];\n                    temp[N-1][j] = '.';\n                } else { // 'D'\n                    for (int r = N-1; r > 0; --r) temp[r][j] = temp[r-1][j];\n                    temp[0][j] = '.';\n                }\n            }\n            if (safe) {\n                // Actually perform the shifts on the real board\n                if (dir == 'U') {\n                    for (int s = 0; s < shifts; ++s) shiftColUp(j);\n                } else if (dir == 'D') {\n                    for (int s = 0; s < shifts; ++s) shiftColDown(j);\n                } else if (dir == 'L') {\n                    for (int s = 0; s < shifts; ++s) shiftRowLeft(i);\n                } else if (dir == 'R') {\n                    for (int s = 0; s < shifts; ++s) shiftRowRight(i);\n                }\n                return true;\n            }\n        }\n        return false;\n    };\n\n    // Enhanced batch removal: find row/column where shifting in a direction removes all Oni safely\n    struct Batch {\n        bool isRow;\n        int idx;\n        char dir;\n        int shifts;\n        int count; // number of Oni removed\n    };\n    auto findBestBatchRemoval = [&]() -> Batch {\n        Batch best = {false, -1, ' ', N*N+1, 0};\n        // Check rows\n        for (int i = 0; i < N; ++i) {\n            int minCol = N, maxCol = -1;\n            int cnt = 0;\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    cnt++;\n                    minCol = min(minCol, j);\n                    maxCol = max(maxCol, j);\n                }\n            }\n            if (cnt == 0) continue;\n            // Check left shift safety: no Fukunokami in columns 0..maxCol\n            bool leftSafe = true;\n            for (int j = 0; j <= maxCol; ++j) {\n                if (board[i][j] == 'o') {\n                    leftSafe = false;\n                    break;\n                }\n            }\n            if (leftSafe) {\n                int shifts = maxCol + 1;\n                double score = (double)cnt / shifts;\n                if (score > (double)best.count / best.shifts || \n                    (fabs(score - (double)best.count / best.shifts) < 1e-9 && shifts < best.shifts)) {\n                    best = {true, i, 'L', shifts, cnt};\n                }\n            }\n            // Check right shift safety: no Fukunokami in columns minCol..N-1\n            bool rightSafe = true;\n            for (int j = minCol; j < N; ++j) {\n                if (board[i][j] == 'o') {\n                    rightSafe = false;\n                    break;\n                }\n            }\n            if (rightSafe) {\n                int shifts = N - minCol;\n                double score = (double)cnt / shifts;\n                if (score > (double)best.count / best.shifts || \n                    (fabs(score - (double)best.count / best.shifts) < 1e-9 && shifts < best.shifts)) {\n                    best = {true, i, 'R', shifts, cnt};\n                }\n            }\n        }\n        // Check columns\n        for (int j = 0; j < N; ++j) {\n            int minRow = N, maxRow = -1;\n            int cnt = 0;\n            for (int i = 0; i < N; ++i) {\n                if (board[i][j] == 'x') {\n                    cnt++;\n                    minRow = min(minRow, i);\n                    maxRow = max(maxRow, i);\n                }\n            }\n            if (cnt == 0) continue;\n            // Check up shift safety: no Fukunokami in rows 0..maxRow\n            bool upSafe = true;\n            for (int i = 0; i <= maxRow; ++i) {\n                if (board[i][j] == 'o') {\n                    upSafe = false;\n                    break;\n                }\n            }\n            if (upSafe) {\n                int shifts = maxRow + 1;\n                double score = (double)cnt / shifts;\n                if (score > (double)best.count / best.shifts || \n                    (fabs(score - (double)best.count / best.shifts) < 1e-9 && shifts < best.shifts)) {\n                    best = {false, j, 'U', shifts, cnt};\n                }\n            }\n            // Check down shift safety: no Fukunokami in rows minRow..N-1\n            bool downSafe = true;\n            for (int i = minRow; i < N; ++i) {\n                if (board[i][j] == 'o') {\n                    downSafe = false;\n                    break;\n                }\n            }\n            if (downSafe) {\n                int shifts = N - minRow;\n                double score = (double)cnt / shifts;\n                if (score > (double)best.count / best.shifts || \n                    (fabs(score - (double)best.count / best.shifts) < 1e-9 && shifts < best.shifts)) {\n                    best = {false, j, 'D', shifts, cnt};\n                }\n            }\n        }\n        return best;\n    };\n\n    // Helper to count Oni with safe directions in a given board state\n    auto countSafeDirections = [&](const vector<string>& b) -> int {\n        int cnt = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (b[i][j] != 'x') continue;\n                bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n                for (int r = 0; r < i; ++r) if (b[r][j] == 'o') safeUp = false;\n                for (int r = i+1; r < N; ++r) if (b[r][j] == 'o') safeDown = false;\n                for (int c = 0; c < j; ++c) if (b[i][c] == 'o') safeLeft = false;\n                for (int c = j+1; c < N; ++c) if (b[i][c] == 'o') safeRight = false;\n                if (safeUp || safeDown || safeLeft || safeRight) cnt++;\n            }\n        }\n        return cnt;\n    };\n\n    int stuck_counter = 0;\n    const int MAX_STUCK = 50;\n\n    while (moves.size() < MAX_MOVES) {\n        // High\u2011priority: batch removal of multiple Oni from a row/column\n        Batch batch = findBestBatchRemoval();\n        if (batch.idx != -1) {\n            if (batch.isRow) {\n                if (batch.dir == 'L') {\n                    for (int k = 0; k < batch.shifts; ++k) shiftRowLeft(batch.idx);\n                } else { // 'R'\n                    for (int k = 0; k < batch.shifts; ++k) shiftRowRight(batch.idx);\n                }\n            } else {\n                if (batch.dir == 'U') {\n                    for (int k = 0; k < batch.shifts; ++k) shiftColUp(batch.idx);\n                } else { // 'D'\n                    for (int k = 0; k < batch.shifts; ++k) shiftColDown(batch.idx);\n                }\n            }\n            stuck_counter = 0;\n            continue;\n        }\n\n        // No batch removal possible -> compute current Oni and their safe directions count\n        vector<pair<int, int>> oniList;\n        vector<int> safeCount;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    oniList.emplace_back(i, j);\n                    bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n                    for (int r = 0; r < i; ++r) if (board[r][j] == 'o') safeUp = false;\n                    for (int r = i+1; r < N; ++r) if (board[r][j] == 'o') safeDown = false;\n                    for (int c = 0; c < j; ++c) if (board[i][c] == 'o') safeLeft = false;\n                    for (int c = j+1; c < N; ++c) if (board[i][c] == 'o') safeRight = false;\n                    int cnt = safeUp + safeDown + safeLeft + safeRight;\n                    safeCount.push_back(cnt);\n                }\n            }\n        }\n        if (oniList.empty()) break;\n\n        // Find Oni with minimum safeCount (>0)\n        int minSafe = 5;\n        for (int cnt : safeCount) if (cnt > 0 && cnt < minSafe) minSafe = cnt;\n        if (minSafe == 5) {\n            // No Oni with safe direction -> stuck handling\n            stuck_counter++;\n            if (stuck_counter > MAX_STUCK) break; // safety break\n\n            // Generate all safe shifts and pick the one that maximizes Oni with safe directions after shift\n            int bestScore = -1;\n            char bestDir = ' ';\n            int bestIdx = -1; // row or col index\n            bool isRow = true;\n\n            // Try row left/right\n            for (int i = 0; i < N; ++i) {\n                if (board[i][0] != 'o') {\n                    // left shift safe\n                    vector<string> temp = board;\n                    for (int c = 0; c < N-1; ++c) temp[i][c] = temp[i][c+1];\n                    temp[i][N-1] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'L';\n                        bestIdx = i;\n                        isRow = true;\n                    }\n                }\n                if (board[i][N-1] != 'o') {\n                    // right shift safe\n                    vector<string> temp = board;\n                    for (int c = N-1; c > 0; --c) temp[i][c] = temp[i][c-1];\n                    temp[i][0] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'R';\n                        bestIdx = i;\n                        isRow = true;\n                    }\n                }\n            }\n            // Try column up/down\n            for (int j = 0; j < N; ++j) {\n                if (board[0][j] != 'o') {\n                    // up shift safe\n                    vector<string> temp = board;\n                    for (int r = 0; r < N-1; ++r) temp[r][j] = temp[r+1][j];\n                    temp[N-1][j] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'U';\n                        bestIdx = j;\n                        isRow = false;\n                    }\n                }\n                if (board[N-1][j] != 'o') {\n                    // down shift safe\n                    vector<string> temp = board;\n                    for (int r = N-1; r > 0; --r) temp[r][j] = temp[r-1][j];\n                    temp[0][j] = '.';\n                    int score = countSafeDirections(temp);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestDir = 'D';\n                        bestIdx = j;\n                        isRow = false;\n                    }\n                }\n            }\n\n            if (bestIdx != -1) {\n                if (isRow) {\n                    if (bestDir == 'L') shiftRowLeft(bestIdx);\n                    else shiftRowRight(bestIdx);\n                } else {\n                    if (bestDir == 'U') shiftColUp(bestIdx);\n                    else shiftColDown(bestIdx);\n                }\n                continue;\n            } else {\n                // No safe shift at all -> try fallback removal\n                for (auto [i, j] : oniList) {\n                    if (tryRemoveOni(i, j)) break;\n                }\n                continue;\n            }\n        }\n\n        // Among Oni with minSafe, pick the one with best removal ratio, tie\u2011break by fewer shifts\n        int bestIdx = -1;\n        char bestDir = ' ';\n        double bestScore = -1.0;\n        int bestShifts = N*N;\n        for (size_t idx = 0; idx < oniList.size(); ++idx) {\n            if (safeCount[idx] != minSafe) continue;\n            auto [i, j] = oniList[idx];\n            bool safeUp = true, safeDown = true, safeLeft = true, safeRight = true;\n            for (int r = 0; r < i; ++r) if (board[r][j] == 'o') safeUp = false;\n            for (int r = i+1; r < N; ++r) if (board[r][j] == 'o') safeDown = false;\n            for (int c = 0; c < j; ++c) if (board[i][c] == 'o') safeLeft = false;\n            for (int c = j+1; c < N; ++c) if (board[i][c] == 'o') safeRight = false;\n\n            if (safeUp) {\n                int shifts = i + 1;\n                int removed = 0;\n                for (int r = 0; r <= i; ++r) if (board[r][j] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore + 1e-9 || \n                    (fabs(score - bestScore) < 1e-9 && shifts < bestShifts)) {\n                    bestScore = score;\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'U';\n                }\n            }\n            if (safeDown) {\n                int shifts = N - i;\n                int removed = 0;\n                for (int r = i; r < N; ++r) if (board[r][j] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore + 1e-9 || \n                    (fabs(score - bestScore) < 1e-9 && shifts < bestShifts)) {\n                    bestScore = score;\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'D';\n                }\n            }\n            if (safeLeft) {\n                int shifts = j + 1;\n                int removed = 0;\n                for (int c = 0; c <= j; ++c) if (board[i][c] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore + 1e-9 || \n                    (fabs(score - bestScore) < 1e-9 && shifts < bestShifts)) {\n                    bestScore = score;\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'L';\n                }\n            }\n            if (safeRight) {\n                int shifts = N - j;\n                int removed = 0;\n                for (int c = j; c < N; ++c) if (board[i][c] == 'x') removed++;\n                double score = (double)removed / shifts;\n                if (score > bestScore + 1e-9 || \n                    (fabs(score - bestScore) < 1e-9 && shifts < bestShifts)) {\n                    bestScore = score;\n                    bestShifts = shifts;\n                    bestIdx = idx;\n                    bestDir = 'R';\n                }\n            }\n        }\n\n        if (bestIdx == -1) {\n            // Should not happen, but fallback\n            for (auto [i, j] : oniList) {\n                if (tryRemoveOni(i, j)) break;\n            }\n            stuck_counter++;\n            if (stuck_counter > MAX_STUCK) break;\n            continue;\n        }\n\n        auto [i, j] = oniList[bestIdx];\n        if (bestDir == 'U') {\n            for (int k = 0; k < i + 1; ++k) shiftColUp(j);\n        } else if (bestDir == 'D') {\n            for (int k = 0; k < N - i; ++k) shiftColDown(j);\n        } else if (bestDir == 'L') {\n            for (int k = 0; k < j + 1; ++k) shiftRowLeft(i);\n        } else if (bestDir == 'R') {\n            for (int k = 0; k < N - j; ++k) shiftRowRight(i);\n        }\n        stuck_counter = 0;\n    }\n\n    // Output the moves\n    for (auto [d, p] : moves) {\n        cout << d << \" \" << p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast simulation that reuses a preallocated cnt array\npair<long long, vector<int>&> simulate(vector<int>& cnt, const vector<int>& a, const vector<int>& b, const vector<long long>& T, int N, long long L) {\n    fill(cnt.begin(), cnt.end(), 0);\n    int current = 0;\n    cnt[current] = 1;\n    for (long long week = 2; week <= L; ++week) {\n        if (cnt[current] & 1) {  // faster than modulo\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        ++cnt[current];\n    }\n    long long error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(cnt[i] - T[i]);\n    }\n    return {error, cnt};\n}\n\n// Dinic's max flow\nstruct Edge {\n    int to, rev;\n    long long cap;\n};\nclass Dinic {\npublic:\n    vector<vector<Edge>> graph;\n    vector<int> level, iter;\n    Dinic(int n) : graph(n), level(n), iter(n) {}\n    void add_edge(int from, int to, long long cap) {\n        graph[from].push_back({to, (int)graph[to].size(), cap});\n        graph[to].push_back({from, (int)graph[from].size() - 1, 0});\n    }\n    void bfs(int s) {\n        fill(level.begin(), level.end(), -1);\n        queue<int> q;\n        level[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (auto& e : graph[v]) {\n                if (e.cap > 0 && level[e.to] < 0) {\n                    level[e.to] = level[v] + 1;\n                    q.push(e.to);\n                }\n            }\n        }\n    }\n    long long dfs(int v, int t, long long f) {\n        if (v == t) return f;\n        for (int& i = iter[v]; i < (int)graph[v].size(); ++i) {\n            Edge& e = graph[v][i];\n            if (e.cap > 0 && level[v] < level[e.to]) {\n                long long d = dfs(e.to, t, min(f, e.cap));\n                if (d > 0) {\n                    e.cap -= d;\n                    graph[e.to][e.rev].cap += d;\n                    return d;\n                }\n            }\n        }\n        return 0;\n    }\n    long long max_flow(int s, int t) {\n        long long flow = 0;\n        while (true) {\n            bfs(s);\n            if (level[t] < 0) return flow;\n            fill(iter.begin(), iter.end(), 0);\n            long long f;\n            while ((f = dfs(s, t, 1e18)) > 0) {\n                flow += f;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 100;\n    const long long L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // Build flow network\n    int source = 0;\n    int left_start = 1;                     // 1 .. 200\n    int right_start = left_start + 2 * N;   // 201 .. 300\n    int sink = right_start + N;             // 301\n    Dinic dinic(sink + 1);\n\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n        dinic.add_edge(source, node1, T[i]);\n        dinic.add_edge(source, node2, T[i]);\n    }\n    for (int j = 0; j < N; ++j) {\n        int node = right_start + j;\n        dinic.add_edge(node, sink, 2 * T[j]);\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node1 = left_start + 2 * i;\n            int node2 = left_start + 2 * i + 1;\n            int right_node = right_start + j;\n            dinic.add_edge(node1, right_node, L);\n            dinic.add_edge(node2, right_node, L);\n        }\n    }\n    long long flow = dinic.max_flow(source, sink);\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        int node1 = left_start + 2 * i;\n        int node2 = left_start + 2 * i + 1;\n\n        long long max_fl1 = -1;\n        int best_j1 = 0;\n        for (auto& e : dinic.graph[node1]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl1) {\n                    max_fl1 = fl;\n                    best_j1 = e.to - right_start;\n                }\n            }\n        }\n        a[i] = best_j1;\n\n        long long max_fl2 = -1;\n        int best_j2 = 0;\n        for (auto& e : dinic.graph[node2]) {\n            if (e.to >= right_start && e.to < right_start + N) {\n                long long fl = L - e.cap;\n                if (fl > max_fl2) {\n                    max_fl2 = fl;\n                    best_j2 = e.to - right_start;\n                }\n            }\n        }\n        b[i] = best_j2;\n    }\n\n    // Initial simulation\n    vector<int> cnt(N);\n    auto [best_error, _] = simulate(cnt, a, b, T, N, L);\n    vector<int> best_a = a, best_b = b;\n    vector<long long> err(N);\n    for (int i = 0; i < N; ++i) err[i] = cnt[i] - T[i];\n\n    // Local search with bias\n    const int max_iter = 2000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_emp(0, N-1);\n    uniform_int_distribution<int> rand_bool(0, 1);\n    uniform_int_distribution<int> rand_val(0, N-1);\n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        int i = rand_emp(rng);\n        bool change_a = rand_bool(rng);\n        int new_val;\n\n        if (err[i] > 0) {\n            // Collect under-visited employees\n            vector<int> candidates;\n            for (int j = 0; j < N; ++j) if (err[j] < 0) candidates.push_back(j);\n            if (!candidates.empty()) {\n                uniform_int_distribution<int> rand_cand(0, candidates.size()-1);\n                new_val = candidates[rand_cand(rng)];\n            } else {\n                new_val = rand_val(rng);\n            }\n        } else {\n            new_val = rand_val(rng);\n        }\n\n        int old_val = change_a ? best_a[i] : best_b[i];\n        if (change_a) a[i] = new_val;\n        else b[i] = new_val;\n\n        auto [new_error, new_cnt] = simulate(cnt, a, b, T, N, L);\n        if (new_error < best_error) {\n            best_error = new_error;\n            if (change_a) best_a[i] = new_val;\n            else best_b[i] = new_val;\n            for (int j = 0; j < N; ++j) err[j] = new_cnt[j] - T[j];\n        } else {\n            if (change_a) a[i] = old_val;\n            else b[i] = old_val;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int, int>;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\nvector<vector<double>> dist_center; // Euclidean distances between centers\n\nvector<vector<int>> groups;\nvector<vector<pii>> group_edges;\nint total_queries = 0;\n\n// Fortune\u2011telling query\nvector<pii> query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    vector<pii> edges;\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    ++total_queries;\n    return edges;\n}\n\n// Hilbert curve index for integer coordinates (14\u2011bit precision)\nuint64_t hilbertOrder(int x, int y) {\n    int pow = 14;\n    uint64_t d = 0;\n    int s = 1 << (pow - 1);\n    for (int i = pow - 1; i >= 0; --i) {\n        int rx = (x & s) ? 1 : 0;\n        int ry = (y & s) ? 1 : 0;\n        d = (d << 2) | ((rx * 3) ^ ry);\n        if (!ry) {\n            if (rx) {\n                x = (1 << pow) - 1 - x;\n                y = (1 << pow) - 1 - y;\n            }\n            swap(x, y);\n        }\n        s >>= 1;\n    }\n    return d;\n}\n\n// 2-opt improvement for a TSP path\nvoid two_opt(vector<int>& order) {\n    int n = order.size();\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < n - 1; ++i) {\n            for (int j = i + 2; j < n; ++j) {\n                int a = order[i], b = order[i+1];\n                int c = order[j], d = (j+1 < n) ? order[j+1] : -1;\n                double delta;\n                if (d != -1) {\n                    delta = dist_center[a][c] + dist_center[b][d] - dist_center[a][b] - dist_center[c][d];\n                } else {\n                    delta = dist_center[a][c] - dist_center[a][b];\n                }\n                if (delta < -1e-12) {\n                    reverse(order.begin() + i + 1, order.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n}\n\n// TSP order: try multiple starts and pick the best tour\nvector<int> approximateTSPorder(const vector<int>& group) {\n    int n = group.size();\n    if (n <= 5) {\n        // small group, just sort by Hilbert order\n        vector<int> order = group;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n        });\n        two_opt(order);\n        return order;\n    }\n\n    // map city to its index in the group vector\n    map<int, int> pos;\n    for (int i = 0; i < n; ++i) pos[group[i]] = i;\n\n    // sort group by Hilbert order to get a sequence\n    vector<int> sorted = group;\n    sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n        return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n    });\n\n    vector<int> best_order;\n    double best_len = 1e18;\n\n    // try starting from the first few cities in Hilbert order\n    int num_starts = min(10, n);\n    for (int k = 0; k < num_starts; ++k) {\n        int start = sorted[k];\n        // nearest neighbor tour from start\n        vector<bool> vis(n, false);\n        vector<int> order;\n        order.push_back(start);\n        int cur = pos[start];\n        vis[cur] = true;\n        for (int i = 1; i < n; ++i) {\n            int next = -1;\n            double best = 1e18;\n            for (int j = 0; j < n; ++j) {\n                if (!vis[j]) {\n                    double d = dist_center[group[cur]][group[j]];\n                    if (d < best) {\n                        best = d;\n                        next = j;\n                    }\n                }\n            }\n            cur = next;\n            vis[cur] = true;\n            order.push_back(group[cur]);\n        }\n        // apply 2-opt\n        two_opt(order);\n        // compute tour length (without closing edge)\n        double len = 0;\n        for (size_t i = 0; i + 1 < order.size(); ++i)\n            len += dist_center[order[i]][order[i+1]];\n        if (len < best_len) {\n            best_len = len;\n            best_order = order;\n        }\n    }\n\n    // also try the Hilbert order itself\n    vector<int> h_order = sorted;\n    two_opt(h_order);\n    double h_len = 0;\n    for (size_t i = 0; i + 1 < h_order.size(); ++i)\n        h_len += dist_center[h_order[i]][h_order[i+1]];\n    if (h_len < best_len) {\n        best_order = h_order;\n    }\n\n    return best_order;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Precompute Euclidean distances between centers\n    dist_center.assign(N, vector<double>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            double dx = cx[i] - cx[j];\n            double dy = cy[i] - cy[j];\n            dist_center[i][j] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Global ordering by Hilbert curve index\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return hilbertOrder(cx[i], cy[i]) < hilbertOrder(cx[j], cy[j]);\n    });\n\n    // Partition into groups according to G\n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n\n    // Process each group\n    for (int i = 0; i < M; ++i) {\n        int s = groups[i].size();\n        if (s == 1) continue;\n        if (s <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n        } else {\n            vector<int> reordered = approximateTSPorder(groups[i]);\n            int start = 0;\n            while (start < s) {\n                int end = min(start + L, s);\n                if (end - start >= 2) {\n                    vector<int> window(reordered.begin() + start, reordered.begin() + end);\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                }\n                start += L - 1; // overlap by exactly one city\n            }\n        }\n        if (total_queries > Q) break;\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> points(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> points[i].first >> points[i].second;\n    }\n\n    pair<int, int> cur = points[0];\n    vector<pair<int, int>> targets(points.begin() + 1, points.end());\n    vector<string> actions;\n\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n    const string dir_name[4] = {\"D\", \"U\", \"R\", \"L\"};\n\n    for (size_t k = 0; k < targets.size(); ++k) {\n        auto [ti, tj] = targets[k];\n\n        // Build blocked cells: future targets (index > k)\n        vector<vector<bool>> blocked_future(N, vector<bool>(N, false));\n        for (size_t i = k + 1; i < targets.size(); ++i) {\n            int x = targets[i].first, y = targets[i].second;\n            blocked_future[x][y] = true;\n        }\n\n        // Case 1: already aligned and target on boundary -> direct slide\n        if (cur.first == ti) {\n            if (tj == 0) {\n                actions.push_back(\"S L\");\n                cur.second = tj;\n                continue;\n            } else if (tj == N - 1) {\n                actions.push_back(\"S R\");\n                cur.second = tj;\n                continue;\n            }\n        } else if (cur.second == tj) {\n            if (ti == 0) {\n                actions.push_back(\"S U\");\n                cur.first = ti;\n                continue;\n            } else if (ti == N - 1) {\n                actions.push_back(\"S D\");\n                cur.first = ti;\n                continue;\n            }\n        }\n\n        // Case 2: target on a boundary, try align-then-slide if straight path clear\n        bool used_align_slide = false;\n        if (ti == 0 || ti == N-1 || tj == 0 || tj == N-1) {\n            // Target on top/bottom boundary: move horizontally to column tj, then slide vertically\n            if (ti == 0 || ti == N-1) {\n                // Check horizontal segment from (cur.first, cur.second) to (cur.first, tj)\n                bool clear = true;\n                if (cur.second != tj) {\n                    int step = (cur.second < tj) ? 1 : -1;\n                    for (int j = cur.second; j != tj; j += step) {\n                        if (blocked_future[cur.first][j]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                // Also ensure the destination cell (cur.first, tj) is not a future target\n                if (clear && blocked_future[cur.first][tj]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform horizontal moves\n                    if (cur.second < tj) {\n                        for (int j = cur.second; j < tj; ++j) actions.push_back(\"M R\");\n                    } else if (cur.second > tj) {\n                        for (int j = cur.second; j > tj; --j) actions.push_back(\"M L\");\n                    }\n                    cur.second = tj;\n                    // Perform slide\n                    if (ti == 0) {\n                        actions.push_back(\"S U\");\n                        cur.first = ti;\n                    } else {\n                        actions.push_back(\"S D\");\n                        cur.first = ti;\n                    }\n                    used_align_slide = true;\n                }\n            }\n            // If not used, try the other orientation if target on left/right boundary\n            if (!used_align_slide && (tj == 0 || tj == N-1)) {\n                // Move vertically to row ti, then slide horizontally\n                bool clear = true;\n                if (cur.first != ti) {\n                    int step = (cur.first < ti) ? 1 : -1;\n                    for (int i = cur.first; i != ti; i += step) {\n                        if (blocked_future[i][cur.second]) {\n                            clear = false;\n                            break;\n                        }\n                    }\n                }\n                if (clear && blocked_future[ti][cur.second]) {\n                    clear = false;\n                }\n                if (clear) {\n                    // Perform vertical moves\n                    if (cur.first < ti) {\n                        for (int i = cur.first; i < ti; ++i) actions.push_back(\"M D\");\n                    } else if (cur.first > ti) {\n                        for (int i = cur.first; i > ti; --i) actions.push_back(\"M U\");\n                    }\n                    cur.first = ti;\n                    // Perform slide\n                    if (tj == 0) {\n                        actions.push_back(\"S L\");\n                        cur.second = tj;\n                    } else {\n                        actions.push_back(\"S R\");\n                        cur.second = tj;\n                    }\n                    used_align_slide = true;\n                }\n            }\n        }\n        if (used_align_slide) {\n            continue;\n        }\n\n        // Case 3: fallback to BFS with moves and slides\n        vector<vector<int>> prev_x(N, vector<int>(N, -1));\n        vector<vector<int>> prev_y(N, vector<int>(N, -1));\n        vector<vector<int>> prev_dir(N, vector<int>(N, -1)); // 0-3: move, 4-7: slide\n        queue<pair<int, int>> q;\n        q.push(cur);\n        prev_x[cur.first][cur.second] = cur.first;\n        prev_y[cur.first][cur.second] = cur.second;\n\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            if (x == ti && y == tj) break;\n\n            // Move actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                if (blocked_future[nx][ny]) continue;\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = d; // 0-3 for moves\n                q.push({nx, ny});\n            }\n\n            // Slide actions\n            for (int d = 0; d < 4; ++d) {\n                int nx = x, ny = y;\n                // Simulate slide\n                while (true) {\n                    int next_x = nx + dx[d];\n                    int next_y = ny + dy[d];\n                    if (next_x < 0 || next_x >= N || next_y < 0 || next_y >= N) break;\n                    // If next cell is a future target, we can still move into it (since it's not a block),\n                    // but we must not end on it. We'll continue moving.\n                    // However, we cannot move into a cell that is a block. Since we have no blocks,\n                    // we just move.\n                    nx = next_x;\n                    ny = next_y;\n                }\n                // Now (nx, ny) is the final cell after sliding.\n                if (nx == x && ny == y) continue; // no movement\n                if (blocked_future[nx][ny]) continue; // cannot end on future target\n                if (prev_x[nx][ny] != -1) continue;\n                prev_x[nx][ny] = x;\n                prev_y[nx][ny] = y;\n                prev_dir[nx][ny] = 4 + d; // 4-7 for slides\n                q.push({nx, ny});\n            }\n        }\n\n        // Reconstruct path\n        vector<string> path_actions;\n        int x = ti, y = tj;\n        while (x != cur.first || y != cur.second) {\n            int dir = prev_dir[x][y];\n            int px = prev_x[x][y];\n            int py = prev_y[x][y];\n            if (dir < 4) {\n                // move action\n                path_actions.push_back(\"M \" + dir_name[dir]);\n            } else {\n                // slide action\n                path_actions.push_back(\"S \" + dir_name[dir - 4]);\n            }\n            x = px;\n            y = py;\n        }\n        reverse(path_actions.begin(), path_actions.end());\n\n        for (const string& a : path_actions) {\n            actions.push_back(a);\n        }\n\n        cur = {ti, tj};\n    }\n\n    // Output actions\n    for (const string& a : actions) {\n        cout << a << \"\\n\";\n    }\n\n    return 0;\n}"}}}