{"model_name":"gemma-4-26b-a4b-it","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to partition a 10000x10000 area into non-overlapping rectangles, each containing\n * one specific point (xi+0.5, yi+0.5), to maximize the sum of satisfaction levels.\n * Satisfaction is maximized when the rectangle's area s_i is close to the desired area r_i.\n * \n * Algorithm Strategy:\n * We use a recursive KD-tree-like partitioning (guillotine cuts). At each step, we choose a\n * vertical or horizontal split line that divides the current rectangle into two. \n * To keep the areas close to the sum of desired areas (r_i), we aim to maintain a constant \n * \"excess area\" ratio. Specifically, if the current rectangle has area A and the sum of\n * desired areas is R, the \"excess area\" is E = A - R. For any split, we try to distribute\n * E between the two new rectangles proportionally to the number of points in them.\n * \n * We use a randomized approach: at each recursive step, we collect all valid splits and\n * pick one of the top-scoring splits randomly. We run the entire process multiple times\n * with different random seeds and select the best overall result.\n */\n\nstruct Point {\n    int x, y, r, id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nint N;\nPoint points_orig[200];\nRect ans[200];\n\nstruct Split {\n    bool vertical;\n    int k;\n    double score;\n    int j; // number of points in the left partition\n};\n\n// Recursive function to partition a rectangle and its associated points\nvoid solve(Rect R, vector<Point> P, mt19937& gen) {\n    if (P.empty()) return;\n    if (P.size() == 1) {\n        ans[P[0].id] = R;\n        return;\n    }\n\n    long long total_r = 0;\n    for (const auto& p : P) total_r += p.r;\n    long long total_area = (long long)(R.x2 - R.x1) * (R.y2 - R.y1);\n    double E = (double)total_area - (double)total_r;\n\n    vector<Split> splits;\n\n    // --- Vertical Splits ---\n    sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n        if (a.x != b.x) return a.x < b.x;\n        return a.y < b.y;\n    });\n\n    int n = P.size();\n    for (int j = 1; j < n; ++j) {\n        // Points in the left partition are P[0...j-1]\n        // A split at x = k is valid if P[j-1].x < k <= P[j].x\n        if (P[j-1].x < P[j].x) {\n            long long R_L = 0;\n            for (int i = 0; i < j; ++i) R_L += P[i].r;\n            \n            double target_E_L = E * (double)j / n;\n            double target_A_L = (double)R_L + target_E_L;\n            int H = R.y2 - R.y1;\n            \n            // Target width is target_A_L / H\n            int k = R.x1 + (int)round(target_A_L / (double)H);\n            // Clamp k within the valid split range for this point partition\n            k = max(P[j-1].x + 1, min(P[j].x, k));\n            \n            long long actual_A_L = (long long)(k - R.x1) * H;\n            double actual_E_L = (double)actual_A_L - (double)R_L;\n            double score = abs(actual_E_L - target_E_L);\n            splits.push_back({true, k, score, j});\n        }\n    }\n\n    // --- Horizontal Splits ---\n    sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n        if (a.y != b.y) return a.y < b.y;\n        return a.x < b.x;\n    });\n\n    for (int j = 1; j < n; ++j) {\n        if (P[j-1].y < P[j].y) {\n            long long R_L = 0;\n            for (int i = 0; i < j; ++i) R_L += P[i].r;\n            \n            double target_E_L = E * (double)j / n;\n            double target_A_L = (double)R_L + target_E_L;\n            int W = R.x2 - R.x1;\n            \n            int k = R.y1 + (int)round(target_A_L / (double)W);\n            k = max(P[j-1].y + 1, min(P[j].y, k));\n\n            long long actual_A_L = (long long)W * (k - R.y1);\n            double actual_E_L = (double)actual_A_L - (double)R_L;\n            double score = abs(actual_E_L - target_E_L);\n            splits.push_back({false, k, score, j});\n        }\n    }\n\n    if (splits.empty()) {\n        // Fallback to avoid empty partitions\n        ans[P[0].id] = {R.x1, R.y1, R.x1 + 1, R.y1 + 1};\n        return;\n    }\n\n    // Sort splits by score (ascending)\n    sort(splits.begin(), splits.end(), [](const Split& a, const Split& b) {\n        return a.score < b.score;\n    });\n\n    // Pick one of the top-scoring splits to introduce randomness\n    int K_options = min((int)splits.size(), 3);\n    uniform_int_distribution<int> dist(0, K_options - 1);\n    Split best = splits[dist(gen)];\n\n    vector<Point> P_L, P_R;\n    Rect R_L, R_R;\n    if (best.vertical) {\n        R_L = {R.x1, R.y1, best.k, R.y2};\n        R_R = {best.k, R.y1, R.x2, R.y2};\n        // To split correctly, P must be sorted by X\n        sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n            if (a.x != b.x) return a.x < b.x;\n            return a.y < b.y;\n        });\n        for (int i = 0; i < best.j; ++i) P_L.push_back(P[i]);\n        for (int i = best.j; i < n; ++i) P_R.push_back(P[i]);\n    } else {\n        R_L = {R.x1, R.y1, R.x2, best.k};\n        R_R = {R.x1, best.k, R.x2, R.y2};\n        // To split correctly, P must be sorted by Y\n        sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n            if (a.y != b.y) return a.y < b.y;\n            return a.x < b.x;\n        });\n        for (int i = 0; i < best.j; ++i) P_L.push_back(P[i]);\n        for (int i = best.j; i < n; ++i) P_R.push_back(P[i]);\n    }\n\n    solve(R_L, P_L, gen);\n    solve(R_R, P_R, gen);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> points_orig[i].x >> points_orig[i].y >> points_orig[i].r;\n        points_orig[i].id = i;\n    }\n\n    Rect total_rect = {0, 0, 10000, 10000};\n    vector<Point> P_init;\n    for (int i = 0; i < N; ++i) P_init.push_back(points_orig[i]);\n\n    double best_total_sat = -1.0;\n    Rect best_ans_res[200];\n\n    // Perform multiple iterations to improve the final result\n    for (int iter = 0; iter < 120; ++iter) {\n        mt19937 current_gen(iter * 987654321LL);\n        solve(total_rect, P_init, current_gen);\n        \n        double current_sat = 0;\n        for (int i = 0; i < N; ++i) {\n            int xi = points_orig[i].x;\n            int yi = points_orig[i].y;\n            int ri = points_orig[i].r;\n            int a = ans[i].x1, b = ans[i].y1, c = ans[i].x2, d = ans[i].y2;\n            \n            // Check if point is contained in its assigned rectangle\n            if (xi >= a && xi < c && yi >= b && yi < d) {\n                long long si = (long long)(c - a) * (d - b);\n                double x = (double)min((long long)ri, si) / max((long long)ri, si);\n                current_sat += 1.0 - (1.0 - x) * (1.0 - x);\n            }\n        }\n        \n        if (current_sat > best_total_sat) {\n            best_total_sat = current_sat;\n            for (int i = 0; i < N; ++i) best_ans_res[i] = ans[i];\n        }\n    }\n\n    // Final output\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_res[i].x1 << \" \" << best_ans_res[i].y1 << \" \" \n             << best_ans_res[i].x2 << \" \" << best_ans_res[i].y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The problem asks for a path in a 50x50 grid that maximizes the total score.\n * A crucial constraint is that each tile (of size 1x1, 1x2, or 2x1) can be visited at most once.\n * This means if a tile has two squares, stepping on one square makes the other square of that tile inaccessible for future steps.\n * This problem is essentially finding a path in a graph of tiles, making it a variation of the Longest Path problem,\n * which is NP-hard. Given the heuristic nature of the contest, a randomized greedy approach with \n * many restarts and a smart heuristic is a viable strategy.\n *\n * Algorithm:\n * 1. Use a randomized greedy algorithm with many trials.\n * 2. In each trial, starting from the initial square (si, sj), greedily pick the next square.\n * 3. Heuristic: To choose the next square, we consider all adjacent squares that belong to unvisited tiles.\n *    The score for each candidate square is calculated as (P[nr][nc] + 1) * (neighbors + 1)^0.7,\n *    where 'neighbors' is the number of unvisited adjacent squares that belong to different tiles.\n *    This heuristic balances the immediate reward (P) with the potential for future moves (connectivity).\n * 4. Randomization: To explore more paths, instead of always picking the best candidate, \n *    we pick one from the top K (K=3) candidates using a weighted distribution (softmax-like).\n * 5. Keep track of the path with the maximum score across all trials.\n * 6. Continue the trials as long as time allows (within 2.0s).\n */\n\nint si, sj;\nint T[50][50];\nint P[50][50];\nbool visited_tile[2505];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nstruct Candidate {\n    double score;\n    int r, c;\n    int move_idx;\n};\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read initial position\n    if (!(cin >> si >> sj)) return 0;\n\n    // Read tile IDs\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> T[i][j];\n        }\n    }\n\n    // Read square values\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> P[i][j];\n        }\n    }\n\n    // Initialize random number generator\n    random_device rd;\n    mt19937 rng(rd());\n\n    string best_path = \"\";\n    int best_score = -1;\n\n    clock_t start_time = clock();\n\n    // Perform as many randomized greedy trials as possible within the time limit\n    while (true) {\n        // Limit execution to avoid time limit exceeded (TLE)\n        if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n\n        // Reset visited tiles for the new trial\n        for (int i = 0; i < 2505; ++i) visited_tile[i] = false;\n\n        int curr_r = si, curr_c = sj;\n        int curr_score = P[si][sj];\n        visited_tile[T[si][sj]] = true;\n        string path = \"\";\n\n        while (true) {\n            vector<Candidate> candidates;\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr_r + dr[i];\n                int nc = curr_c + dc[i];\n\n                // Check if neighbor is within bounds and belongs to an unvisited tile\n                if (nr >= 0 && nr < 50 && nc >= 0 && nc < 50 && !visited_tile[T[nr][nc]]) {\n                    int neighbors = 0;\n                    // Calculate number of unvisited neighbors (different tiles) to guide connectivity\n                    for (int j = 0; j < 4; ++j) {\n                        int nnr = nr + dr[j];\n                        int nnc = nc + dc[j];\n                        if (nnr >= 0 && nnr < 50 && nnc >= 0 && nnc < 50 &&\n                            !visited_tile[T[nnr][nnc]] && T[nnr][nnc] != T[nr][nc]) {\n                            neighbors++;\n                        }\n                    }\n                    // Heuristic: prioritize higher immediate score and higher connectivity\n                    double score = (double)(P[nr][nc] + 1) * pow(neighbors + 1, 0.7);\n                    candidates.push_back({score, nr, nc, i});\n                }\n            }\n\n            // No valid moves left\n            if (candidates.empty()) break;\n\n            // Sort candidates by their heuristic score in descending order\n            sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n                return a.score > b.score;\n            });\n\n            // Implement probabilistic selection from the top K best candidates\n            int K = min((int)candidates.size(), 3);\n            vector<double> weights;\n            for (int i = 0; i < K; ++i) {\n                // Using square of the score as a weight for a stronger preference for better candidates\n                weights.push_back(candidates[i].score * candidates[i].score);\n            }\n\n            // Generate a weighted selection\n            discrete_distribution<int> dist(weights.begin(), weights.end());\n            int chosen_idx = dist(rng);\n            Candidate chosen = candidates[chosen_idx];\n\n            // Update current position, score, visited set, and path\n            curr_r = chosen.r;\n            curr_c = chosen.c;\n            curr_score += P[curr_r][curr_c];\n            visited_tile[T[curr_r][curr_c]] = true;\n            path += move_char[chosen.move_idx];\n        }\n\n        // Update the best global path found so far\n        if (curr_score > best_score) {\n            best_score = curr_score;\n            best_path = path;\n        }\n    }\n\n    // Output the result path\n    cout << best_path << endl;\n\n    return 0;\n}\n","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\ndouble h[N][N-1]; // horizontal edges: h[i][j] connects (i, j) and (i, j+1)\ndouble v[N-1][N]; // vertical edges: v[i][j] connects (i, j) and (i+1, j)\n\nstruct Node {\n    int r, c;\n    double d;\n    bool operator>(const Node& other) const {\n        return d > other.d;\n    }\n};\n\nstruct Parent {\n    int r, c;\n    char dir;\n};\n\nParent parent[N][N];\ndouble dists[N][N];\n\nvoid dijkstra(int sr, int sc, int tr, int tc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j] = 1e18;\n            parent[i][j] = {-1, -1, ' '};\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[sr][sc] = 0;\n    pq.push({sr, sc, 0.0});\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char dirs[] = {'U', 'D', 'L', 'R'};\n\n    while (!pq.empty()) {\n        Node top = pq.top();\n        pq.pop();\n\n        int r = top.r;\n        int c = top.c;\n        double d = top.d;\n\n        if (d > dists[r][c]) continue;\n        if (r == tr && c == tc) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = 0;\n                if (dirs[i] == 'U') weight = v[nr][c];\n                else if (dirs[i] == 'D') weight = v[r][c];\n                else if (dirs[i] == 'L') weight = h[r][nc];\n                else if (dirs[i] == 'R') weight = h[r][c];\n\n                if (dists[nr][nc] > d + weight) {\n                    dists[nr][nc] = d + weight;\n                    parent[nr][nc] = {r, c, dirs[i]};\n                    pq.push({nr, nc, dists[nr][nc]});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Fast I/O setup\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize weights\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        dijkstra(si, sj, ti, tj);\n\n        string path = \"\";\n        int cr = ti, cc = tj;\n        while (cr != si || cc != sj) {\n            Parent p = parent[cr][cc];\n            path += p.dir;\n            cr = p.r;\n            cc = p.c;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl; // endl flushes standard output\n\n        long long L_k;\n        if (!(cin >> L_k)) break;\n\n        // Calculate current path length using current estimates\n        double current_path_len = 0;\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                current_path_len += v[cr - 1][cc];\n                cr--;\n            } else if (d == 'D') {\n                current_path_len += v[cr][cc];\n                cr++;\n            } else if (d == 'L') {\n                current_path_len += h[cr][cc - 1];\n                cc--;\n            } else if (d == 'R') {\n                current_path_len += h[cr][cc];\n                cc++;\n            }\n        }\n\n        // Stochastic Gradient Descent update\n        double diff = (double)L_k - current_path_len;\n        double eta = 0.1 * pow(0.999, k); // slowly decaying learning rate\n        double step = (diff / (double)path.size()) * eta;\n\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                v[cr - 1][cc] += step;\n                cr--;\n            } else if (d == 'D') {\n                v[cr][cc] += step;\n                cr++;\n            } else if (d == 'L') {\n                h[cr][cc - 1] += step;\n                cc--;\n            } else if (d == 'R') {\n                h[cr][cc] += step;\n                cc++;\n            }\n        }\n\n        // Keep weights within reasonable bounds\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) if (h[i][j] < 100.0) h[i][j] = 100.0;\n            if (i < N - 1) {\n                for (int j = 0; j < N; ++j) if (v[i][j] < 100.0) v[i][j] = 100.0;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find an N x N (N=20) matrix of characters A-H or '.' that satisfies \n * as many of M (400-800) given strings as possible. The matrix is a torus.\n * Scoring:\n * - If c < M: 10^8 * (c / M)\n * - If c = M: 10^8 * (2 * N^2 / (2 * N^2 - d)), where d is the number of '.' characters.\n * \n * Strategy:\n * 1. Use Simulated Annealing (SA) to maximize the number of satisfied strings (c).\n *    The state is an N x N matrix of characters A-H.\n *    An efficient way to update c during SA is to maintain a mismatch count for \n *    each possible occurrence of each string.\n * 2. If c = M is achieved, use a greedy approach to maximize the number of '.' characters (d).\n *    Replace characters with '.' as long as no string is lost.\n * \n * Complexity:\n * - SA: O(iterations * (number of occurrences covering a cell) * (strings per length))\n * - Pre-calculation: O(N^2 * M * L)\n */\n\nint N, M;\nstring s[800];\nchar A[20][20];\nint counts[800]; // Number of occurrences of string s[k] currently satisfied\nint c_satisfied = 0;\nvector<int> strings_by_len[13];\nvector<int> mismatch_count[2][20][20][13];\n\nstruct Occ {\n    int t, line, start, len, p, idx, k;\n};\nvector<Occ> cell_occs[20][20];\n\nstruct Change {\n    int t, line, start, len, idx, k;\n    int old_m, old_count_k;\n};\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        strings_by_len[s[i].length()].push_back(i);\n    }\n\n    // Initial random matrix of A-H\n    mt19937 rng(42);\n    string chars = \"ABCDEFGH\";\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = chars[rng() % 8];\n        }\n    }\n\n    // Pre-calculate mismatch counts for each occurrence of each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    mismatch_count[t][i][j][len].resize(strings_by_len[len].size());\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        int k = strings_by_len[len][idx];\n                        int mismatches = 0;\n                        for (int p = 0; p < len; ++p) {\n                            int ni = (t == 0) ? i : (i + p) % N;\n                            int nj = (t == 0) ? (j + p) % N : j;\n                            if (A[ni][nj] != s[k][p]) mismatches++;\n                        }\n                        mismatch_count[t][i][j][len][idx] = mismatches;\n                    }\n                }\n            }\n        }\n    }\n\n    // Calculate the number of satisfied occurrences for each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        if (mismatch_count[t][i][j][len][idx] == 0) {\n                            counts[strings_by_len[len][idx]]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    for (int k = 0; k < M; ++k) if (counts[k] > 0) c_satisfied++;\n\n    // Pre-calculate which occurrences cover which cell (i, j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int t = 0; t < 2; ++t) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int p = 0; p < len; ++p) {\n                        int line = (t == 0) ? i : (i - p + N) % N;\n                        int start = (t == 0) ? (j - p + N) % N : j;\n                        for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                            cell_occs[i][j].push_back({t, line, start, len, p, idx, strings_by_len[len][idx]});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulated Annealing phase\n    auto start_time = chrono::high_resolution_clock::now();\n    int max_iter = 250000;\n    vector<Change> changes;\n    changes.reserve(15000); \n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        if ((iter & 1023) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2600) break;\n        }\n\n        int r = rng() % (N * N);\n        int i = r / N, j = r % N;\n        char old_v = A[i][j];\n        char new_v = chars[rng() % 8];\n        if (old_v == new_v) continue;\n\n        double T = 1.0 * (1.0 - (double)iter / max_iter);\n        int delta_c = 0;\n        changes.clear();\n\n        for (auto& occ : cell_occs[i][j]) {\n            int& m = mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx];\n            int old_m = m;\n            if (old_v != s[occ.k][occ.p] && new_v == s[occ.k][occ.p]) m--;\n            else if (old_v == s[occ.k][occ.p] && new_v != s[occ.k][occ.p]) m++;\n            \n            if (old_m == 0 && m > 0) {\n                if (--counts[occ.k] == 0) delta_c--;\n            } else if (old_m > 0 && m == 0) {\n                if (++counts[occ.k] == 1) delta_c++;\n            }\n            changes.push_back({occ.t, occ.line, occ.start, occ.len, occ.idx, occ.k, old_m, counts[occ.k]});\n        }\n\n        if (delta_c >= 0 || (T > 1e-9 && (double)rng() / rng.max() < exp(delta_c / T))) {\n            A[i][j] = new_v;\n            c_satisfied += delta_c;\n        } else {\n            for (int idx = (int)changes.size() - 1; idx >= 0; --idx) {\n                auto& ch = changes[idx];\n                mismatch_count[ch.t][ch.line][ch.start][ch.len][ch.idx] = ch.old_m;\n                counts[ch.k] = ch.old_count_k;\n            }\n        }\n    }\n\n    // Phase 2: Maximize density (number of '.') if all strings are satisfied\n    if (c_satisfied == M) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (A[i][j] != '.') {\n                    char old_v = A[i][j];\n                    vector<int> matching_occs_using_ij(M, 0);\n                    for (auto& occ : cell_occs[i][j]) {\n                        if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                            matching_occs_using_ij[occ.k]++;\n                        }\n                    }\n                    bool ok = true;\n                    for (int k = 0; k < M; ++k) {\n                        if (matching_occs_using_ij[k] > 0 && counts[k] == matching_occs_using_ij[k]) {\n                            ok = false; \n                            break;\n                        }\n                    }\n                    if (ok) {\n                        A[i][j] = '.';\n                        for (auto& occ : cell_occs[i][j]) {\n                            if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                                counts[occ.k]--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << A[i][j];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a shortest patrol route that visits road squares such that\n * all road squares become \"visible\" at least once.\n * A square is visible if it's in the same row/column and no obstacles are between.\n * \n * Strategy:\n * 1. Represent the map and precompute visibility (which squares can see each other).\n * 2. Use a greedy strategy to pick a subset of road squares (ToVisit) that covers\n *    the most \"uncovered\" road squares with the minimum distance.\n * 3. The greedy heuristic: Pick the \"hardest-to-cover\" square (one with fewest \n *    potential visitors) and then pick the best visitor (maximizing newly covered / distance).\n * 4. Once the set of points to visit is found, solve the Traveling Salesperson Problem (TSP)\n *    on these points using a Nearest Neighbor heuristic followed by 2-opt refinement.\n * 5. Convert the TSP tour into the actual move string (U, D, L, R).\n */\n\nconst int INF = 1e9;\n\nint N, si, sj;\nint grid[70][70];\nvector<int> C[5000], S[5000];\nbool is_road[5000];\nint dists[5000];\nint parent_node[5000];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Standard Dijkstra to find shortest path distances from a source node\nvoid dijkstra(int start, int n_size) {\n    for (int i = 0; i < n_size; ++i) dists[i] = INF;\n    dists[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n\n    while (!pq.empty()) {\n        int d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n\n        if (d > dists[u]) continue;\n\n        int r = u / N, c = u % N;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != -1) {\n                int v = nr * N + nc;\n                if (dists[u] + grid[nr][nc] < dists[v]) {\n                    dists[v] = dists[u] + grid[nr][nc];\n                    parent_node[v] = u;\n                    pq.push({dists[v], v});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> si >> sj)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            if (row[j] == '#') {\n                grid[i][j] = -1;\n                is_road[i * N + j] = false;\n            } else {\n                grid[i][j] = row[j] - '0';\n                is_road[i * N + j] = true;\n            }\n        }\n    }\n\n    // Precompute visibility\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!is_road[i * N + j]) continue;\n            int u = i * N + j;\n            C[u].push_back(u);\n            S[u].push_back(u);\n            // Horizontal\n            for (int k = j - 1; k >= 0 && grid[i][k] != -1; --k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = j + 1; k < N && grid[i][k] != -1; ++k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            // Vertical\n            for (int k = i - 1; k >= 0 && grid[k][j] != -1; --k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = i + 1; k < N && grid[k][j] != -1; ++k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n        }\n    }\n\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            sort(C[i].begin(), C[i].end());\n            C[i].erase(unique(C[i].begin(), C[i].end()), C[i].end());\n            sort(S[i].begin(), S[i].end());\n            S[i].erase(unique(S[i].begin(), S[i].end()), S[i].end());\n        }\n    }\n\n    // Set Cover Greedy\n    vector<bool> is_uncovered(N * N, false);\n    vector<int> uncovered_list;\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            is_uncovered[i] = true;\n            uncovered_list.push_back(i);\n        }\n    }\n\n    vector<int> ToVisit;\n    int curr = si * N + sj;\n    while (!uncovered_list.empty()) {\n        dijkstra(curr, N * N);\n        int best_r = -1;\n        int min_S_r = 1000000;\n        for (int r : uncovered_list) {\n            if ((int)S[r].size() < min_S_r) {\n                min_S_r = S[r].size();\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break;\n\n        int best_v = -1;\n        double best_gain = -1.0;\n        for (int v : S[best_r]) {\n            int gain = 0;\n            for (int road_idx : C[v]) {\n                if (is_uncovered[road_idx]) gain++;\n            }\n            double current_gain = (double)gain / (dists[v] + 1.0);\n            if (current_gain > best_gain) {\n                best_gain = current_gain;\n                best_v = v;\n            }\n        }\n        if (best_v == -1 || best_gain <= 0.0) break;\n\n        ToVisit.push_back(best_v);\n        for (int road_idx : C[best_v]) {\n            is_uncovered[road_idx] = false;\n        }\n        \n        vector<int> next_uncovered;\n        for (int r : uncovered_list) {\n            if (is_uncovered[r]) next_uncovered.push_back(r);\n        }\n        uncovered_list = next_uncovered;\n        curr = best_v;\n    }\n\n    // TSP Step: Nearest Neighbor + 2-opt\n    vector<int> P;\n    P.push_back(si * N + sj);\n    set<int> seen;\n    seen.insert(si * N + sj);\n    for (int v : ToVisit) {\n        if (seen.find(v) == seen.end()) {\n            P.push_back(v);\n            seen.insert(v);\n        }\n    }\n\n    int k_points = P.size();\n    vector<vector<int>> dist_matrix(k_points, vector<int>(k_points, INF));\n    for (int i = 0; i < k_points; ++i) {\n        dijkstra(P[i], N * N);\n        for (int j = 0; j < k_points; ++j) {\n            dist_matrix[i][j] = dists[P[j]];\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited_tsp(k_points, false);\n    int current_idx = 0;\n    tour.push_back(0);\n    visited_tsp[0] = true;\n    for (int step = 1; step < k_points; ++step) {\n        int next_idx = -1;\n        int min_d = INF;\n        for (int j = 0; j < k_points; ++j) {\n            if (!visited_tsp[j] && dist_matrix[current_idx][j] < min_d) {\n                min_d = dist_matrix[current_idx][j];\n                next_idx = j;\n            }\n        }\n        if (next_idx == -1) break;\n        tour.push_back(next_idx);\n        visited_tsp[next_idx] = true;\n        current_idx = next_idx;\n    }\n    tour.push_back(0);\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 1; i < sz - 2; ++i) {\n            for (int j = i + 1; j < sz - 1; ++j) {\n                if (dist_matrix[tour[i - 1]][tour[i]] + dist_matrix[tour[j]][tour[j + 1]] >\n                    dist_matrix[tour[i - 1]][tour[j]] + dist_matrix[tour[i]][tour[j + 1]]) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Final Path Reconstruction\n    string final_route = \"\";\n    for (int i = 0; i < (int)tour.size() - 1; ++i) {\n        int u = P[tour[i]];\n        int v = P[tour[i+1]];\n        if (u == v) continue;\n        dijkstra(u, N * N);\n        vector<int> path_nodes;\n        int curr_node = v;\n        while (curr_node != u) {\n            path_nodes.push_back(curr_node);\n            curr_node = parent_node[curr_node];\n        }\n        reverse(path_nodes.begin(), path_nodes.end());\n        \n        int prev_r = u / N, prev_c = u % N;\n        for (int node : path_nodes) {\n            int nr = node / N, nc = node % N;\n            if (nr == prev_r + 1) final_route += 'D';\n            else if (nr == prev_r - 1) final_route += 'U';\n            else if (nc == prev_c + 1) final_route += 'R';\n            else if (nc == prev_c - 1) final_route += 'L';\n            prev_r = nr;\n            prev_c = nc;\n        }\n    }\n    cout << final_route << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * - N tasks, M team members, K skills, R dependencies.\n * - Each task i requires skill levels d_{i,k}.\n * - Each team member j has unknown skill levels s_{j,k}.\n * - Completion time t_{i,j} depends on w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k}).\n * - If w_{i,j} == 0, t_{i,j} = 1.\n * - If w_{i,j} > 0, t_{i,j} = max(1, w_{i,j} + r_i), where r_i is uniform in [-3, 3].\n * - Goal: Complete all tasks in minimum days (up to 2000).\n * \n * Algorithm:\n * 1. Skill Estimation: Maintain an estimate for each member's skill levels.\n *    After a task is completed, use the actual time taken to update skill estimates via \n *    a stochastic gradient descent-like approach.\n * 2. Scheduling: Each day, identify available tasks (those whose dependencies are all met)\n *    and idle members. Match them using a greedy score: Score(i, j) = Rank(i) / (ExpectedTime(i, j) + 1),\n *    where Rank(i) is the length of the longest chain of dependent tasks starting from task i.\n *    This prioritizes critical-path tasks and efficient member-task assignments.\n */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task requirement skill levels\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    // Task dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // Precalculate task rank (length of longest dependency chain)\n    vector<int> task_rank(N, -1);\n    auto get_rank = [&](auto self, int u) -> int {\n        if (task_rank[u] != -1) return task_rank[u];\n        int max_r = 0;\n        for (int v : adj[u]) {\n            max_r = max(max_r, self(self, v));\n        }\n        return task_rank[u] = max_r + 1;\n    };\n\n    for (int i = 0; i < N; ++i) {\n        get_rank(get_rank, i);\n    }\n\n    // State management\n    vector<vector<double>> s(M, vector<double>(K, 0.0)); // Skill level estimates\n    vector<int> task_status(N, 0);        // 0: not started, 1: in progress, 2: completed\n    vector<int> member_current_task(M, -1); // task index if member is busy, else -1\n    vector<int> task_start_day(N, 0);     // day the task started\n\n    int current_day = 1;\n    while (current_day <= 2000) {\n        // 1. Identify available tasks and idle members\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] == 0 && in_degree[i] == 0) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // 2. Greedy matching using score: Rank(i) / (Expected_t(i, j) + 1)\n        struct Assignment {\n            int m, t;\n            double score;\n        };\n        vector<Assignment> current_day_assignments;\n        vector<bool> task_assigned(N, false);\n        vector<bool> member_used(M, false);\n\n        while (true) {\n            int best_i = -1, best_j = -1;\n            double best_score = -1.0;\n\n            for (int i : available_tasks) {\n                if (task_assigned[i]) continue;\n                for (int j : idle_members) {\n                    if (member_used[j]) continue;\n\n                    // Estimate expected time\n                    double w_ij = 0;\n                    for (int k = 0; k < K; ++k) {\n                        w_ij += max(0.0, (double)d[i][k] - s[j][k]);\n                    }\n                    double expected_t = (w_ij < 1e-9) ? 1.0 : max(1.0, w_ij);\n                    double score = (double)task_rank[i] / (expected_t + 1.0);\n\n                    if (score > best_score) {\n                        best_score = score;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n\n            if (best_i == -1) break;\n\n            task_assigned[best_i] = true;\n            member_used[best_j] = true;\n            current_day_assignments.push_back({best_j, best_i, best_score});\n        }\n\n        // 3. Output the assignments for the current day\n        cout << current_day_assignments.size();\n        for (auto& assign : current_day_assignments) {\n            cout << \" \" << assign.m + 1 << \" \" << assign.t + 1;\n            task_status[assign.t] = 1; // In progress\n            member_current_task[assign.m] = assign.t;\n            task_start_day[assign.t] = current_day;\n        }\n        cout << endl;\n\n        // 4. Read completed members from Standard Input\n        int num_completed;\n        if (!(cin >> num_completed)) break;\n        if (num_completed == -1) break;\n\n        // 5. Update skills and task states for each completed task\n        for (int idx = 0; idx < num_completed; ++idx) {\n            int f;\n            cin >> f;\n            --f; // 0-indexed\n            int t_idx = member_current_task[f];\n            int actual_t = current_day - task_start_day[t_idx] + 1;\n\n            // Skill level update: Stochastic Gradient Descent\n            double w_ij_est = 0;\n            for (int k = 0; k < K; ++k) {\n                w_ij_est += max(0.0, (double)d[t_idx][k] - s[f][k]);\n            }\n            double expected_t_est = (w_ij_est < 1e-9) ? 1.0 : max(1.0, w_ij_est);\n            double eta = 1.0 / (1.0 + current_day * 0.01); // Decay learning rate\n\n            for (int k = 0; k < K; ++k) {\n                if (d[t_idx][k] > s[f][k]) {\n                    // If task took longer than expected (actual_t > expected_t), \n                    // we want to increase w_ij, which means decreasing s[f][k].\n                    s[f][k] -= eta * (actual_t - expected_t_est);\n                    if (s[f][k] < 0) s[f][k] = 0;\n                }\n            }\n\n            // Mark task as completed and update dependencies\n            task_status[t_idx] = 2; // Completed\n            member_current_task[f] = -1; // Member is now idle\n            for (int v : adj[t_idx]) {\n                in_degree[v]--;\n            }\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}\n","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Structure to represent a single delivery order\nstruct Order {\n    int a, b, c, d, id;\n};\n\n// Structure to represent a single stop in the delivery route\nstruct Point {\n    int x, y, order_idx;\n    bool is_pickup;\n};\n\n// Function to calculate Manhattan distance between two points\ninline int dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Function to calculate the total distance of the route\nint total_dist(const vector<Point>& P) {\n    int d = 0;\n    d += dist(400, 400, P[0].x, P[0].y);\n    for (size_t i = 0; i < P.size() - 1; ++i) {\n        d += dist(P[i].x, P[i].y, P[i + 1].x, P[i + 1].y);\n    }\n    d += dist(P.back().x, P.back().y, 400, 400);\n    return d;\n}\n\n// Function to update the positions of pickups and deliveries in the current sequence\nvoid update_pos(const vector<Point>& P, vector<int>& pos_A, vector<int>& pos_C) {\n    fill(pos_A.begin(), pos_A.end(), -1);\n    fill(pos_C.begin(), pos_C.end(), -1);\n    for (int i = 0; i < (int)P.size(); ++i) {\n        if (P[i].is_pickup) pos_A[P[i].order_idx] = i;\n        else pos_C[P[i].order_idx] = i;\n    }\n}\n\nint main() {\n    // Optimizing I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<Order> all_orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        if (!(cin >> all_orders[i].a >> all_orders[i].b >> all_orders[i].c >> all_orders[i].d)) break;\n        all_orders[i].id = i + 1;\n    }\n\n    // Initial strategy: Pick 50 orders with the smallest individual trip distance\n    vector<pair<int, int>> costs;\n    for (int i = 0; i < 1000; ++i) {\n        int d = dist(400, 400, all_orders[i].a, all_orders[i].b) +\n                dist(all_orders[i].a, all_orders[i].b, all_orders[i].c, all_orders[i].d) +\n                dist(all_orders[i].c, all_orders[i].d, 400, 400);\n        costs.push_back({d, i});\n    }\n    sort(costs.begin(), costs.end());\n\n    vector<int> S, not_S;\n    vector<bool> in_S(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        S.push_back(costs[i].second);\n        in_S[costs[i].second] = true;\n    }\n    for (int i = 0; i < 1000; ++i) {\n        if (!in_S[i]) not_S.push_back(i);\n    }\n\n    // Construct an initial valid delivery route: Alternating pickup and delivery for chosen orders\n    vector<Point> P;\n    for (int idx : S) {\n        P.push_back({all_orders[idx].a, all_orders[idx].b, idx, true});\n        P.push_back({all_orders[idx].c, all_orders[idx].d, idx, false});\n    }\n\n    vector<int> pos_A(1000), pos_C(1000);\n    update_pos(P, pos_A, pos_C);\n\n    int current_dist = total_dist(P);\n    vector<Point> best_P = P;\n    vector<int> best_S = S;\n    int best_dist = current_dist;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 1000.0;\n    double T_end = 1.0;\n\n    int iter = 0;\n    // Simulated Annealing to optimize the set S and the route P\n    while (true) {\n        iter++;\n        if (iter % 1000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n            if (elapsed >= 1.0) break;\n        }\n\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n        double T = T_start * pow(T_end / T_start, elapsed);\n\n        int move_type = rng() % 3;\n\n        if (move_type == 0) { // Move 1: Swap two points in the sequence\n            int i = rng() % 100;\n            int j = rng() % 100;\n            if (i == j) continue;\n\n            int ord_i = P[i].order_idx;\n            int ord_j = P[j].order_idx;\n\n            swap(P[i], P[j]);\n            update_pos(P, pos_A, pos_C);\n\n            // Check validity: pickup must precede delivery for the affected orders\n            bool valid = (pos_A[ord_i] < pos_C[ord_i]) && (pos_A[ord_j] < pos_C[ord_j]);\n\n            if (valid) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    swap(P[i], P[j]); // Undo swap\n                    update_pos(P, pos_A, pos_C);\n                }\n            } else {\n                swap(P[i], P[j]); // Undo invalid swap\n                update_pos(P, pos_A, pos_C);\n            }\n        } else if (move_type == 1) { // Move 2: Reinsert a point in a different position\n            int i = rng() % 100;\n            int j = rng() % 100;\n            if (i == j) continue;\n\n            Point p = P[i];\n            P.erase(P.begin() + i);\n            P.insert(P.begin() + j, p);\n            int ord = p.order_idx;\n            update_pos(P, pos_A, pos_C);\n\n            if (pos_A[ord] < pos_C[ord]) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    P.erase(P.begin() + j);\n                    P.insert(P.begin() + i, p); // Undo insertion\n                    update_pos(P, pos_A, pos_C);\n                }\n            } else {\n                P.erase(P.begin() + j);\n                P.insert(P.begin() + i, p); // Undo invalid insertion\n                update_pos(P, pos_A, pos_C);\n            }\n        } else { // Move 3: Replace an order in the set S with one from not_S\n            int i_idx = rng() % 50;\n            int j_idx = rng() % 950;\n            int old_ord = S[i_idx];\n            int new_ord = not_S[j_idx];\n\n            int pA = pos_A[old_ord];\n            int pC = pos_C[old_ord];\n\n            Point old_pA = P[pA];\n            Point old_pC = P[pC];\n\n            P[pA] = {all_orders[new_ord].a, all_orders[new_ord].b, new_ord, true};\n            P[pC] = {all_orders[new_ord].c, all_orders[new_ord].d, new_ord, false};\n            S[i_idx] = new_ord;\n            not_S[j_idx] = old_ord;\n            update_pos(P, pos_A, pos_C);\n\n            int new_dist = total_dist(P);\n            // Replacement is inherently valid for the new order\n            if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                current_dist = new_dist;\n                if (current_dist < best_dist) {\n                    best_dist = current_dist;\n                    best_P = P;\n                    best_S = S;\n                }\n            } else {\n                P[pA] = old_pA;\n                P[pC] = old_pC;\n                S[i_idx] = old_ord;\n                not_S[j_idx] = new_ord;\n                update_pos(P, pos_A, pos_C);\n            }\n        }\n    }\n\n    // Final output of selected orders and the optimized route\n    cout << 50;\n    for (int idx : best_S) cout << \" \" << all_orders[idx].id;\n    cout << endl;\n    cout << best_P.size() + 2; // Start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : best_P) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \" 400 400\" << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * This is an online minimum spanning tree (MST) problem. We are given edges one by one \n * and must decide whether to include each edge in our spanning set immediately.\n * We know the possible range of each edge's length [d_i, 3*d_i], where d_i is the \n * rounded Euclidean distance.\n * \n * To minimize the total length of our adopted edges (A), we should aim to pick edges \n * that are likely to be in the actual MST. An edge (u, v) with weight l is in the MST \n * if and only if there is no path between u and v using only edges with weights strictly \n * less than l. \n * \n * Since we don't know the true lengths of future edges, we use their minimum possible \n * weights (d_j) as an estimate. This heuristic approach builds an MST of the \"estimated\" \n * graph. If an edge is \"necessary\" to connect components given the estimated future, \n * we adopt it.\n * \n * Complexity:\n * For each of the M edges, we build a temporary DSU of the graph containing already \n * selected edges (with their realized lengths) and future edges (with their minimum \n * estimated lengths) that have weights <= current edge's weight.\n * Time Complexity: O(M^2 * alpha(N)), where N=400 and M=1995.\n * 1995^2 * alpha(400) is roughly 1.6 * 10^7, which fits well within the 2s limit.\n */\n\n// Disjoint Set Union (DSU) structure\nstruct DSU {\n    vector<int> parent;\n    vector<int> rank;\n    DSU(int n) {\n        parent.resize(n);\n        iota(parent.begin(), parent.end(), 0);\n        rank.assign(n, 0);\n    }\n    int find(int i) {\n        if (parent[i] == i) return i;\n        return parent[i] = find(parent[i]);\n    }\n    void unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            if (rank[root_i] < rank[root_j]) {\n                parent[root_i] = root_j;\n            } else if (rank[root_i] > rank[root_j]) {\n                parent[root_j] = root_i;\n            } else {\n                parent[root_i] = root_j;\n                rank[root_j]++;\n            }\n        }\n    }\n};\n\n// Edge structure to store coordinates and weights\nstruct Edge {\n    int u, v, d, l;\n};\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> coords[i].first >> coords[i].second)) break;\n    }\n\n    // Read initial edge information (endpoints and d_i)\n    vector<Edge> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) break;\n        all_edges[i].u = u;\n        all_edges[i].v = v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        all_edges[i].d = (int)round(hypot(dx, dy));\n    }\n\n    // DSU to maintain the connectivity of adopted edges\n    DSU dsu_S(N);\n    // Vector to store the edges we have chosen to adopt\n    vector<Edge> S;\n\n    // Process each edge one by one\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n        all_edges[i].l = l_i;\n\n        // If u and v are already connected in our current forest, adding this edge\n        // would create a cycle and increase the total cost A without decreasing B.\n        if (dsu_S.find(all_edges[i].u) == dsu_S.find(all_edges[i].v)) {\n            cout << 0 << endl;\n        } else {\n            // Heuristic: Decide whether edge i is in the MST of the \"estimated\" graph.\n            // The estimated graph uses realized lengths for S and minimum possible d_j for future edges.\n            // An edge is in the MST if it's required to connect two components using edges <= l_i.\n            DSU dsu_Gprime(N);\n            \n            // Add already selected edges with weight <= l_i\n            for (const auto& e : S) {\n                if (e.l <= l_i) {\n                    dsu_Gprime.unite(e.u, e.v);\n                }\n            }\n            // Add potential future edges with estimated weight d_j <= l_i\n            for (int j = i + 1; j < M; ++j) {\n                if (all_edges[j].d <= l_i) {\n                    dsu_Gprime.unite(all_edges[j].u, all_edges[j].v);\n                }\n            }\n\n            // If edge i is necessary to connect its endpoints in the estimated graph, adopt it.\n            if (dsu_Gprime.find(all_edges[i].u) != dsu_Gprime.find(all_edges[i].v)) {\n                cout << 1 << endl;\n                S.push_back(all_edges[i]);\n                dsu_S.unite(all_edges[i].u, all_edges[i].v);\n            } else {\n                cout << 0 << endl;\n            }\n        }\n        // Flush the output as required by the interactive format\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc008":"","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// Problem constants and global state\nint si, sj, ti, tj;\ndouble p;\nbool wall_h[20][20];\nbool wall_v[20][20];\n\n// Movement directions\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\n/**\n * Finds the shortest path using BFS.\n * This is used as a starting point for the optimization.\n */\nstring get_shortest_path() {\n    queue<pair<pair<int, int>, string>> q;\n    q.push({{si, sj}, \"\"});\n    bool visited[20][20];\n    memset(visited, 0, sizeof(visited));\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto curr = q.front();\n        q.pop();\n        int r = curr.first.first;\n        int c = curr.first.second;\n        string path = curr.second;\n\n        if (r == ti && c == tj) return path;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            if (nr >= 0 && nr < 20 && nc >= 0 && nc < 20 && !visited[nr][nc]) {\n                bool blocked = false;\n                if (dr[i] == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n                if (!blocked) {\n                    visited[nr][nc] = true;\n                    q.push({{nr, nc}, path + dir_char[i]});\n                }\n            }\n        }\n    }\n    return \"\";\n}\n\n/**\n * Calculates the expected value of S = 401 - t using DP.\n * Complexity: O(L * 20 * 20)\n */\ndouble calculate_expected_value(const string& S) {\n    int L = S.length();\n    if (L > 200) return 0;\n    double dp[20][20];\n    memset(dp, 0, sizeof(dp));\n    dp[si][sj] = 1.0;\n    double expected_val = 0;\n    for (int t = 0; t < L; ++t) {\n        double next_dp[20][20];\n        memset(next_dp, 0, sizeof(next_dp));\n        int move_dr = 0, move_dc = 0;\n        if (S[t] == 'U') move_dr = -1;\n        else if (S[t] == 'D') move_dr = 1;\n        else if (S[t] == 'L') move_dc = -1;\n        else if (S[t] == 'R') move_dc = 1;\n\n        for (int r = 0; r < 20; ++r) {\n            for (int c = 0; c < 20; ++c) {\n                if (dp[r][c] <= 1e-18 || (r == ti && c == tj)) continue;\n\n                // Case 1: Forget (stay in place)\n                next_dp[r][c] += dp[r][c] * p;\n\n                // Case 2: Attempt move\n                int nr = r + move_dr;\n                int nc = c + move_dc;\n                bool blocked = false;\n                if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) {\n                    blocked = true;\n                } else if (move_dr == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n\n                if (blocked) {\n                    next_dp[r][c] += dp[r][c] * (1.0 - p);\n                } else {\n                    if (nr == ti && nc == tj) {\n                        expected_val += dp[r][c] * (1.0 - p) * (401 - (t + 1));\n                    } else {\n                        next_dp[nr][nc] += dp[r][c] * (1.0 - p);\n                    }\n                }\n            }\n        }\n        memcpy(dp, next_dp, sizeof(dp));\n    }\n    return expected_val;\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            wall_h[i][j] = (row[j] == '1');\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            wall_v[i][j] = (row[j] == '1');\n        }\n    }\n\n    // Starting string is the shortest path\n    string best_S = get_shortest_path();\n    double best_E = calculate_expected_value(best_S);\n\n    // Use a seeded random number generator\n    mt19937 rng(1337);\n    \n    // Optimization step: Enrichment (repeating moves)\n    // This improves robustness against forgetting moves.\n    for (int k = 2; k <= 5; ++k) {\n        string enriched_S = \"\";\n        for (char c : best_S) {\n            for (int count = 0; count < k; ++count) enriched_S += c;\n        }\n        if (enriched_S.length() <= 200) {\n            double e = calculate_expected_value(enriched_S);\n            if (e > best_E) {\n                best_E = e;\n                best_S = enriched_S;\n            }\n        }\n    }\n\n    // Simulated Annealing to optimize the string\n    string current_S = best_S;\n    double current_E = best_E;\n\n    clock_t start_time = clock();\n    const double max_time = 1.85; // Leave some buffer for safety\n\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > max_time) break;\n\n        // Linear cooling\n        double T = 5.0 * (1.0 - elapsed / max_time); \n\n        string next_S = current_S;\n        int type = uniform_int_distribution<int>(0, 4)(rng);\n\n        // Neighbor generation\n        if (type == 0) { // Add a duplicate character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.insert(i, 1, next_S[i]);\n            } else type = 1;\n        } else if (type == 1) { // Remove a duplicate character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                if (i > 0 && next_S[i] == next_S[i-1]) {\n                    next_S.erase(i, 1);\n                } else if (i < (int)next_S.length() - 1 && next_S[i] == next_S[i+1]) {\n                    next_S.erase(i, 1);\n                } else type = 0;\n            } else type = 0;\n        } else if (type == 2) { // Add a random character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length())(rng);\n                char c = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n                next_S.insert(i, 1, c);\n            } else type = 1;\n        } else if (type == 3) { // Remove a random character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.erase(i, 1);\n            } else type = 2;\n        } else if (type == 4) { // Change a random character\n            int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            next_S[i] = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n        }\n\n        double next_E = calculate_expected_value(next_S);\n        \n        // Acceptance criteria\n        if (next_E > current_E || (T > 1e-9 && exp((next_E - current_E) / T) > uniform_real_distribution<double>(0, 1)(rng))) {\n            current_S = next_S;\n            current_E = next_E;\n            if (current_E > best_E) {\n                best_E = current_E;\n                best_S = current_S;\n            }\n        }\n    }\n\n    // Final output\n    cout << best_S << endl;\n\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// The directions: 0: Left, 1: Up, 2: Right, 3: Down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Initial connectivity table for the 8 types\nint base_to[8][4] = {\n    {1, 0, -1, -1}, // 0: one curve (Left, Up)\n    {3, -1, -1, 0}, // 1: one curve (Up, Down)\n    {-1, -1, 3, 2}, // 2: one curve (Right, Down)\n    {-1, 2, 1, -1}, // 3: one curve (Down, Left)\n    {1, 0, 3, 2},    // 4: two curves (Left-Up, Right-Down)\n    {3, 2, 1, 0},    // 5: two curves (Up-Down, Left-Right)\n    {2, -1, 0, -1}, // 6: one straight (Left, Right)\n    {-1, 3, -1, 1}, // 7: one straight (Up, Down)\n};\n\n// Precomputed rotation connectivity table\n// rot_to[t][r][d] is the direction to the next tile for type t, rotated r times CCW, \n// when entering from direction d.\nint rot_to[8][4][4];\n\n// Function to rotate a direction 90 degrees counterclockwise: \n// 0 (L) -> 3 (D), 3 (D) -> 2 (R), 2 (R) -> 1 (U), 1 (U) -> 0 (L)\ninline int rotate_dir(int d) { return (d + 3) % 4; }\n// Inverse rotation\ninline int inv_rotate_dir(int d) { return (d + 1) % 4; }\n\nvoid precompute() {\n    for (int t = 0; t < 8; ++t) {\n        for (int d = 0; d < 4; ++d) rot_to[t][0][d] = base_to[t][d];\n        for (int r = 1; r < 4; ++r) {\n            for (int d = 0; d < 4; ++d) {\n                int prev_d = inv_rotate_dir(d);\n                int prev_to = rot_to[t][r - 1][prev_d];\n                if (prev_to == -1) rot_to[t][r][d] = -1;\n                else rot_to[t][r][d] = rotate_dir(prev_to);\n            }\n        }\n    }\n}\n\nint current_to[30][30][4];\nint initial_type[30][30];\nint current_rot[30][30];\nint visited[30][30][4];\nint timer = 0;\n\nlong long get_score(int& L1, int& L2) {\n    vector<int> lengths;\n    timer++;\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                if (visited[i][j][d] != timer) {\n                    int ci = i, cj = j, cd = d;\n                    int len = 0;\n                    bool possible = true;\n                    while (visited[ci][cj][cd] != timer) {\n                        visited[ci][cj][cd] = timer;\n                        int cd2 = current_to[ci][cj][cd];\n                        if (cd2 == -1) {\n                            possible = false;\n                            break;\n                        }\n                        int ni = ci + di[cd2];\n                        int nj = cj + dj[cd2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            possible = false;\n                            break;\n                        }\n                        len++;\n                        ci = ni; cj = nj;\n                        cd = (cd2 + 2) % 4;\n                    }\n                    if (possible && len > 0) {\n                        lengths.push_back(len);\n                    }\n                }\n            }\n        }\n    }\n    if (lengths.size() < 2) {\n        L1 = 0; L2 = 0;\n        return 0;\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    L1 = lengths[0];\n    L2 = lengths[1];\n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precompute();\n\n    for (int i = 0; i < 30; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; ++j) {\n            initial_type[i][j] = s[j] - '0';\n            current_rot[i][j] = 0;\n            for (int d = 0; d < 4; ++d) {\n                current_to[i][j][d] = rot_to[initial_type[i][j]][0][d];\n            }\n        }\n    }\n\n    int L1, L2;\n    long long current_score = get_score(L1, L2);\n    \n    mt19937 rng(1337);\n    clock_t start_time = clock();\n    \n    // Use local time limit per test case (roughly 18ms)\n    // For competitive programming, we assume about 100 cases.\n    // We will check time roughly every 100 iterations.\n    int iterations = 0;\n    while (true) {\n        if (++iterations % 100 == 0) {\n            if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n        }\n\n        int ri = rng() % 30;\n        int rj = rng() % 30;\n        int old_r = current_rot[ri][rj];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        // Backup the current connectivity for this tile\n        int backup_to[4];\n        for (int d = 0; d < 4; ++d) backup_to[d] = current_to[ri][rj][d];\n\n        // Update connectivity\n        current_rot[ri][rj] = new_r;\n        for (int d = 0; d < 4; ++d) {\n            current_to[ri][rj][d] = rot_to[initial_type[ri][rj]][new_r][d];\n        }\n\n        int next_L1, next_L2;\n        long long next_score = get_score(next_L1, next_L2);\n\n        if (next_score >= current_score) {\n            current_score = next_score;\n            L1 = next_L1; L2 = next_L2;\n        } else {\n            // Simple Hill Climbing. For higher rank, use Simulated Annealing.\n            // Given the 20ms time limit, let's stick to Hill Climbing.\n            current_rot[ri][rj] = old_r;\n            for (int d = 0; d < 4; ++d) current_to[ri][rj][d] = backup_to[d];\n        }\n    }\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            cout << current_rot[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint N, T_limit;\nint board[10][10];\nint target_board[10][10];\nbool fixed_cell[10][10];\nstruct Pos { int r, c; bool operator==(const Pos& o) const { return r == o.r && c == o.c; } bool operator!=(const Pos& o) const { return !(*this == o); } };\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; // U, D, L, R\nchar dchar[] = {'U', 'D', 'L', 'R'};\n\nbool check_match(int t1, int t2, int dir) {\n    if (dir == 0) return (t1 & 8) && (t2 & 2); // U: t1 is (r,c), t2 is (r-1,c). t1 has U(2), t2 has D(8)\n    if (dir == 1) return (t1 & 2) && (t2 & 8); // D: t1 is (r,c), t2 is (r+1,c). t1 has D(8), t2 has U(2)\n    if (dir == 2) return (t1 & 1) && (t2 & 4); // L: t1 is (r,c), t2 is (r,c-1). t1 has L(1), t2 has R(4)\n    if (dir == 3) return (t1 & 4) && (t2 & 1); // R: t1 is (r,c), t2 is (r,c+1). t1 has R(4), t2 has L(1)\n    return false;\n}\n\n// The dir above is based on: if we move the tile from (r+dr, c+dc) to (r, c).\n// If dir=0 (Up), the tile at (r+1, c) moves to (r, c).\n// Let's just use the directions as: U means tile at (r+1, c) moves to (r, c).\n// D means tile at (r-1, c) moves to (r, c).\n// L means tile at (r, c+1) moves to (r, c).\n// R means tile at (r, c-1) moves to (r, c).\n\nint get_tile_dir(Pos from, Pos to) {\n    if (from.r == to.r + 1 && from.c == to.c) return 0; // Tile moves Up\n    if (from.r == to.r - 1 && from.c == to.c) return 1; // Tile moves Down\n    if (from.c == to.c + 1 && from.r == to.r) return 2; // Tile moves Left\n    if (from.c == to.c - 1 && from.r == to.r) return 3; // Tile moves Right\n    return -1;\n}\n\nint main() {\n    if (!(cin >> N >> T_limit)) return 0;\n    Pos empty_pos;\n    vector<int> all_tiles;\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) {\n            int val = stoi(s, nullptr, 16);\n            if (val == 0) empty_pos = {i, j};\n            else all_tiles.push_back(val);\n            board[i][j] = (val == 0 ? 0 : val);\n            target_board[i][j] = -1;\n        }\n    }\n\n    mt19937 rng(time(0));\n    vector<pair<Pos, Pos>> tree_edges;\n    vector<Pos> bfs_order;\n    while (true) {\n        tree_edges.clear(); bfs_order.clear();\n        vector<pair<Pos, Pos>> all_possible_edges;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (i == N - 1 && j == N - 1) continue;\n            if (i + 1 < N && !(i + 1 == N - 1 && j == N - 1)) all_possible_edges.push_back({{i, j}, {i + 1, j}});\n            if (j + 1 < N && !(i == N - 1 && j + 1 == N - 1)) all_possible_edges.push_back({{i, j}, {i, j + 1}});\n        }\n        shuffle(all_possible_edges.begin(), all_possible_edges.end(), rng);\n        vector<int> parent(N * N); for (int i = 0; i < N * N; ++i) parent[i] = i;\n        auto find = [&](auto self, int i) -> int { return parent[i] == i ? i : parent[i] = self(self, parent[i]); };\n        for (auto& e : all_possible_edges) {\n            int r1 = find(find, e.first.r * N + e.first.c), r2 = find(find, e.second.r * N + e.second.c);\n            if (r1 != r2) { parent[r1] = r2; tree_edges.push_back(e); }\n        }\n        bfs_order.push_back({0, 0});\n        vector<bool> visited(N * N, false); visited[0] = true;\n        queue<Pos> q; q.push({0, 0});\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = u.r + dr[i], nc = u.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !(nr == N - 1 && nc == N - 1) && !visited[nr * N + nc]) {\n                    visited[nr * N + nc] = true; bfs_order.push_back({nr, nc}); q.push({nr, nc});\n                }\n            }\n        }\n        auto backtrack = [&](auto self, int idx, vector<int>& used) -> bool {\n            if (idx == N * N - 1) return true;\n            Pos u = bfs_order[idx];\n            for (int i = 0; i < (int)all_tiles.size(); ++i) {\n                if (used[i]) continue;\n                int tile = all_tiles[i];\n                bool ok = true;\n                for (auto& edge : tree_edges) {\n                    if ((edge.first == u || edge.second == u)) {\n                        Pos other = (edge.first == u) ? edge.second : edge.first;\n                        if (target_board[other.r][other.c] != -1) {\n                            if (!check_match(tile, target_board[other.r][other.c], get_tile_dir(u, other))) { ok = false; break; }\n                        }\n                    }\n                }\n                if (ok) {\n                    target_board[u.r][u.c] = tile; used[i] = 1;\n                    if (self(self, idx + 1, used)) return true;\n                    used[i] = 0; target_board[u.r][u.c] = -1;\n                }\n            }\n            return false;\n        };\n        vector<int> used(all_tiles.size(), 0);\n        if (backtrack(backtrack, 0, used)) break;\n    }\n\n    vector<Pos> order;\n    for (int i = 0; i < N - 1; ++i) for (int j = 0; j < N; ++j) order.push_back({i, j});\n    for (int j = 0; j < N - 1; ++j) order.push_back({N - 1, j});\n\n    string res = \"\";\n    Pos cur_e = empty_pos;\n    for (auto p : order) {\n        int tr = -1, tc = -1;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (board[i][j] == target_board[p.r][p.c] && !fixed_cell[i][j]) { tr = i; tc = j; break; }\n        }\n        if (tr == p.r && tc == p.c) { fixed_cell[p.r][p.c] = true; continue; }\n\n        auto bfs_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            while (!q.empty()) {\n                auto [curr, path] = q.front(); q.pop();\n                if (curr == target) {\n                    res += path; cur_e = target;\n                    for (char c : path) {\n                        // To keep board in sync, we simulate. But easier to just swap.\n                    }\n                    return;\n                }\n                for (int i = 0; i < 4; ++i) {\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !v[nr][nc]) {\n                        v[nr][nc] = true;\n                        // If empty moves from (nr,nc) to (curr.r, curr.c), tile moves from (curr.r, curr.c) to (nr,nc)\n                        // The direction is the direction the TILE moves.\n                        // If empty moves (nr,nc) -> (curr.r, curr.c), tile moves (curr.r, curr.c) -> (nr,nc).\n                        // If nr = curr.r-1, tile moves Down. If nr = curr.r+1, tile moves Up.\n                        // If nc = curr.c-1, tile moves Right. If nc = curr.c+1, tile moves Left.\n                        char move_char;\n                        if (nr == curr.r - 1) move_char = 'D';\n                        else if (nr == curr.r + 1) move_char = 'U';\n                        else if (nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n        \n        // Correcting move: BFS to move empty to (tr, tc)\n        // But we must not move through the tile we are trying to move!\n        // No, we move the empty to (tr,tc) then to (p.r, p.c)? \n        // Let's do: 1. Move empty to (tr, tc) 2. Move empty to (p.r, p.c)\n        // Actually, to move tile from (tr,tc) to (p.r,p.c):\n        // Step 1: Move empty square to (p.r, p.c). Step 2: Move empty square to (tr, tc).\n        // Then the tile at (tr,tc) will be at (p.r, p.c).\n        \n        // Let's re-implement the BFS more simply.\n        auto move_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            // To move a tile to (p.r, p.c), we shouldn't let the empty square pass through (p.r, p.c)\n            // EXCEPT when it's the final step. But it's easier to say:\n            // During BFS, the empty square cannot pass through ANY fixed cell.\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply the moves to the board\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int nr = temp_e.r, nc = temp_e.c;\n                        int tr_idx = -1;\n                        if(c == 'U') tr_idx = 1; else if(c == 'D') tr_idx = 0;\n                        else if(c == 'L') tr_idx = 3; else tr_idx = 2;\n                        // Wait, the directions are for the TILE.\n                        // If tile moves Up, empty moves Down.\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char move_char;\n                        if(nr == curr.r - 1) move_char = 'D';\n                        else if(nr == curr.r + 1) move_char = 'U';\n                        else if(nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n\n        // 1. Move empty to (p.r, p.c)\n        // But we must avoid (tr, tc) during this, because it's the tile we want.\n        // Wait, the empty square can move through (tr, tc) if it's not fixed!\n        // Let's just move empty to (p.r, p.c) then to (tr, tc).\n        // Wait, the order is:\n        // 1. Move empty square to (p.r, p.c)\n        // 2. Move empty square to (tr, tc)\n        // Now the tile that was at (tr, tc) is at (p.r, p.c).\n        \n        // We'll use a slightly different approach: move empty to (tr, tc) and then to (p.r, p.c).\n        // Actually, the simplest: move empty to (p.r, p.c), then to (tr, tc).\n        // Let's use a modified BFS that avoids (tr, tc) if we are moving to (p.r, p.c).\n        // Wait, the current tile is at (tr, tc). The empty square should move to (p.r, p.c) \n        // without using (tr, tc) as an intermediate.\n        \n        // BFS to move empty to (p.r, p.c), avoiding (tr, tc) and all fixed cells.\n        auto bfs_with_avoid = [&](Pos target, Pos avoid) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            if(avoid.r != -1) v[avoid.r][avoid.c] = true;\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply moves\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char m;\n                        if(nr == curr.r - 1) m = 'D'; else if(nr == curr.r + 1) m = 'U';\n                        else if(nc == curr.c - 1) m = 'R'; else m = 'L';\n                        q.push({{nr, nc}, path + m});\n                    }\n                }\n            }\n        };\n\n        bfs_with_avoid(p, {tr, tc});\n        bfs_with_avoid({tr, tc}, {-1, -1});\n        fixed_cell[p.r][p.c] = true;\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <map>\n#include <unordered_map>\n\nusing namespace std;\n\ntypedef __int128_t int128;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long a, b, c;\n    long long px, py, qx, qy;\n};\n\nstruct Signature {\n    uint64_t low, high;\n    bool operator<(const Signature& other) const {\n        if (low != other.low) return low < other.low;\n        return high < other.high;\n    }\n    bool operator==(const Signature& other) const {\n        return low == other.low && high == other.high;\n    }\n};\n\nstruct SignatureHash {\n    size_t operator()(const Signature& s) const {\n        return s.low ^ (s.high + 0x9e3779b9 + (s.low << 6) + (s.low >> 2));\n    }\n};\n\nstruct SigBitset {\n    uint64_t low, high;\n    void set_bit(int idx) {\n        if (idx < 64) low |= (1ULL << idx);\n        else high |= (1ULL << (idx - 64));\n    }\n    void reset_bit(int idx) {\n        if (idx < 64) low &= ~(1ULL << idx);\n        else high &= ~(1ULL << (idx - 64));\n    }\n    Signature to_signature() const {\n        return {low, high};\n    }\n};\n\nint N, K;\nint a[11];\nPoint strawberries[5505];\nLine lines[105];\nSigBitset sigs[5505];\nint on_count[5505];\n\nLine make_line(long long px, long long py, long long qx, long long qy) {\n    Line l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = qy - py;\n    l.b = px - qx;\n    l.c = (int128)px * qy - (int128)qx * py; // Need to be careful about precision here, but int128 is ok.\n    // Wait, the line equation is (qy-py)x - (qx-px)y + (pxqy - qxpy) = 0\n    // So a = qy-py, b = -(qx-px) = px-qx, c = pxqy - qxpy.\n    // Let's re-calculate to be more robust.\n    return l;\n}\n\n// Since c can be very large, we use __int128 for it.\n// Let's change the Line struct.\nstruct RobustLine {\n    int128 a, b, c;\n    long long px, py, qx, qy;\n};\n\nRobustLine make_robust_line(long long px, long long py, long long qx, long long qy) {\n    RobustLine l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = (int128)qy - py;\n    l.b = (int128)px - qx;\n    l.c = (int128)px * qy - (int128)qx * py;\n    return l;\n}\n\nRobustLine robust_lines[105];\n\nint calculate_score() {\n    unordered_map<Signature, int, SignatureHash> counts;\n    for (int i = 0; i < N; ++i) {\n        if (on_count[i] == 0) {\n            counts[sigs[i].to_signature()]++;\n        }\n    }\n    int b[11] = {0};\n    for (auto const& [sig, count] : counts) {\n        if (count <= 10) b[count]++;\n    }\n    int total = 0;\n    for (int d = 1; d <= 10; ++d) {\n        total += min(a[d], b[d]);\n    }\n    return total;\n}\n\nvoid update_line(int idx, RobustLine new_line) {\n    for (int i = 0; i < N; ++i) {\n        int128 val_old = robust_lines[idx].a * strawberries[i].x + robust_lines[idx].b * strawberries[i].y + robust_lines[idx].c;\n        if (val_old == 0) {\n            on_count[i]--;\n        } else {\n            // Bit was already set based on val_old.\n        }\n\n        int128 val_new = new_line.a * strawberries[i].x + new_line.b * strawberries[i].y + new_line.c;\n        if (val_new == 0) {\n            on_count[i]++;\n        } else {\n            if (val_new > 0) sigs[i].set_bit(idx);\n            else sigs[i].reset_bit(idx);\n        }\n    }\n    robust_lines[idx] = new_line;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> K)) return 0;\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    for (int i = 0; i < N; ++i) cin >> strawberries[i].x >> strawberries[i].y;\n\n    mt19937 rng(1337);\n    uniform_int_distribution<long long> dist_coord(-10000, 10000);\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    uniform_int_distribution<int> dist_K(0, K - 1);\n\n    // Dummy line\n    robust_lines[0] = make_robust_line(0, 1000000000, 1, 1000000000); \n    // Wait, the dummy line above is a bit invalid (a=0, b=-1, c=-10^9)\n    // Let's use a more standard dummy: y = -10^9\n    robust_lines[0] = make_robust_line(0, -1000000000, 1, -1000000000);\n    for (int i = 0; i < K; ++i) {\n        robust_lines[i] = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        // Re-initialize sigs and on_count\n    }\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        // Actually we need to initialize sigs and on_count properly\n        // Let's just set everything to 0 then update each line one by one.\n    }\n    // Correct initialization:\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        RobustLine rl = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        update_line(i, rl);\n    }\n\n    int current_score = calculate_score();\n    int best_score = current_score;\n    vector<RobustLine> best_lines(robust_lines, robust_lines + K);\n\n    auto start_time = chrono::steady_clock::now();\n    double T = 1.0;\n    double factor = 0.99995;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 127) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2800) break;\n        }\n        iter++;\n\n        int idx = dist_K(rng);\n        RobustLine old_line = robust_lines[idx];\n        RobustLine new_line;\n        \n        if (rng() % 10 < 7) {\n            new_line = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        } else {\n            int s1 = dist_idx(rng);\n            int s2 = dist_idx(rng);\n            if (s1 == s2) {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s1].x + 1, strawberries[s1].y + 1);\n            } else {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s2].x + (rng() % 3 - 1), strawberries[s2].y + (rng() % 3 - 1));\n            }\n        }\n\n        update_line(idx, new_line);\n        int new_score = calculate_score();\n\n        if (new_score >= current_score || (exp((new_score - current_score) / T) > (double)rng() / mt19937::max())) {\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < K; ++i) best_lines[i] = robust_lines[i];\n            }\n        } else {\n            update_line(idx, old_line);\n        }\n        T *= factor;\n    }\n\n    cout << K << \"\\n\";\n    for (int i = 0; i < K; ++i) {\n        cout << best_lines[i].px << \" \" << best_lines[i].py << \" \" << best_lines[i].qx << \" \" << best_lines[i].qy << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The goal is to maximize the sum of weights of dots placed on an N x N grid.\n * The weight of each point (x, y) is (x-c)^2 + (y-c)^2 + 1, where c is the center of the grid.\n * This means we want to place as many dots as possible, especially those far from the center.\n * We can place a new dot by forming a rectangle (axis-aligned or 45-degree inclined) \n * using three existing dots as corners.\n * \n * STRATEGY:\n * A greedy approach should work well here. In each step, find all possible valid \n * rectangles that can be formed and select the one that adds the point with \n * the highest weight.\n * \n * VALIDITY CONDITIONS:\n * 1. A new dot p1 must not currently have a dot.\n * 2. Three other corners (p2, p3, p4) must have dots.\n * 3. No other dots on the rectangle's perimeter.\n * 4. The perimeter must not share a common segment with any existing rectangle.\n * \n * ALGORITHM COMPLEXITY:\n * The number of existing dots M is up to N^2.\n * Searching for rectangles by iterating through all pairs (p2, p3) of existing dots \n * takes O(M^2) per step. \n * Total complexity across all steps is approximately O(N^5), which fits within the 5-second limit.\n */\n\nstruct Point {\n    int x, y;\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nint N, M;\nbool is_dot[65][65];\nbool used_h[65][65];   // used_h[x][y] represents segment (x, y) to (x+1, y)\nbool used_v[65][65];   // used_v[x][y] represents segment (x, y) to (x, y+1)\nbool used_d1[65][65];  // used_d1[x][y] represents segment (x, y) to (x+1, y+1)\nbool used_d2[65][65];  // used_d2[x][y] represents segment (x, y) to (x+1, y-1)\n\ndouble get_weight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1.0;\n}\n\nbool is_in_grid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Checks if any segment of the rectangle's perimeter is already used.\n// If check_and_use is true, it marks these segments as used.\nbool check_segments(const vector<Point>& rect, bool check_and_use) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x, cur_y = start.y;\n        while (cur_x != end.x || cur_y != end.y) {\n            int next_x = cur_x + dx;\n            int next_y = cur_y + dy;\n            if (dx != 0 && dy == 0) { // Horizontal\n                int min_x = min(cur_x, next_x);\n                if (used_h[min_x][cur_y]) return false;\n                if (check_and_use) used_h[min_x][cur_y] = true;\n            } else if (dx == 0 && dy != 0) { // Vertical\n                int min_y = min(cur_y, next_y);\n                if (used_v[cur_x][min_y]) return false;\n                if (check_and_use) used_v[cur_x][min_y] = true;\n            } else if (dx == 1 && dy == 1) { // Diag 1 (up-right)\n                int min_x = cur_x, min_y = cur_y;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == -1) { // Diag 1 (down-left)\n                int min_x = cur_x - 1, min_y = cur_y - 1;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == 1) { // Diag 2 (up-left)\n                int min_x = cur_x - 1, min_y = cur_y;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            } else if (dx == 1 && dy == -1) { // Diag 2 (down-right)\n                int min_x = cur_x, min_y = cur_y - 1;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            }\n            cur_x = next_x; cur_y = next_y;\n        }\n    }\n    return true;\n}\n\n// Checks if any other dots (not among the rectangle's corners p2, p3, p4) are on the perimeter.\nbool check_no_other_dots(const vector<Point>& rect) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x + dx, cur_y = start.y + dy;\n        while (cur_x != end.x || cur_y != end.y) {\n            if (is_dot[cur_x][cur_y]) {\n                bool is_corner = false;\n                for (int j = 1; j < 4; ++j) { // p2, p3, p4 are corners rect[1], rect[2], rect[3]\n                    if (cur_x == rect[j].x && cur_y == rect[j].y) is_corner = true;\n                }\n                if (!is_corner) return false;\n            }\n            cur_x += dx; cur_y += dy;\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M)) return 0;\n    vector<Point> dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        is_dot[x][y] = true;\n        dots.push_back({x, y});\n    }\n\n    vector<vector<Point>> operations;\n\n    while (true) {\n        double best_val = -1;\n        vector<Point> best_rect;\n\n        for (int i = 0; i < (int)dots.size(); ++i) {\n            for (int j = i + 1; j < (int)dots.size(); ++j) {\n                Point p2 = dots[i];\n                Point p3 = dots[j];\n\n                // Axis-aligned rectangle search\n                if (p2.x != p3.x && p2.y != p3.y) {\n                    // Two potential cases: p2 and p3 are opposite corners.\n                    // The other two corners are (p2.x, p3.y) and (p3.x, p2.y).\n                    // One of these must be the new dot p1, the other must be an existing dot p4.\n                    Point corners[2] = {{p2.x, p3.y}, {p3.x, p2.y}};\n                    for (int k = 0; k < 2; ++k) {\n                        Point p1 = corners[k];\n                        Point p4 = corners[1 - k];\n                        if (is_in_grid(p1.x, p1.y) && is_in_grid(p4.x, p4.y)) {\n                            if (!is_dot[p1.x][p1.y] && is_dot[p4.x][p4.y]) {\n                                vector<Point> rect = {p1, p2, p3, p4};\n                                if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                    double val = get_weight(p1.x, p1.y);\n                                    if (val > best_val) {\n                                        best_val = val;\n                                        best_rect = rect;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // 45-degree rectangle search\n                int dx = p3.x - p2.x;\n                int dy = p3.y - p2.y;\n                if ((dx + dy) % 2 == 0) {\n                    // For 45-degree rectangles, the center of the diagonal p2-p3 is a corner of the grid-dual.\n                    // Use geometric properties to find p1 and p4.\n                    int x12 = p2.x + p3.x + p2.y - p3.y;\n                    int y12 = p2.y + p3.y + p3.x - p2.x;\n                    if (x12 % 2 == 0 && y12 % 2 == 0) {\n                        Point p1_cand = {x12 / 2, y12 / 2};\n                        int x42 = p2.x + p3.x - p2.y + p3.y;\n                        int y42 = p2.y + p3.y - p3.x + p2.x;\n                        if (x42 % 2 == 0 && y42 % 2 == 0) {\n                            Point p4_cand = {x42 / 2, y42 / 2};\n                            if (is_in_grid(p1_cand.x, p1_cand.y) && is_in_grid(p4_cand.x, p4_cand.y)) {\n                                // p1_cand could be p1 (the new dot) and p4_cand could be p4 (an existing dot)\n                                if (!is_dot[p1_cand.x][p1_cand.y] && is_dot[p4_cand.x][p4_cand.y]) {\n                                    vector<Point> rect = {p1_cand, p2, p3, p4_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p1_cand.x, p1_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                                // Or vice versa\n                                if (!is_dot[p4_cand.x][p4_cand.y] && is_dot[p1_cand.x][p1_cand.y]) {\n                                    vector<Point> rect = {p4_cand, p2, p3, p1_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p4_cand.x, p4_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_val > 0) {\n            is_dot[best_rect[0].x][best_rect[0].y] = true;\n            dots.push_back(best_rect[0]);\n            check_segments(best_rect, true); // Commit segments as used\n            operations.push_back(best_rect);\n        } else {\n            break;\n        }\n    }\n\n    // Output results\n    cout << operations.size() << \"\\n\";\n    for (const auto& rect : operations) {\n        cout << rect[0].x << \" \" << rect[0].y << \" \"\n             << rect[1].x << \" \" << rect[1].y << \" \"\n             << rect[2].x << \" \" << rect[2].y << \" \"\n             << rect[3].x << \" \" << rect[3].y << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global grid and flavors to store current state and input\nint grid[10][10];\nint flavors[100];\n\nstruct Point {\n    int r, c;\n};\n\n// Directions for adjacency\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n/**\n * Calculates the connectivity score (sum of n_i^2) for the current grid.\n * n_i is the size of the i-th connected component of the same flavor.\n */\nint calculate_score(int current_grid[10][10]) {\n    bool visited[10][10] = {false};\n    int total_score = 0;\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (current_grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = current_grid[r][c];\n                int size = 0;\n                queue<Point> q;\n                q.push({r, c});\n                visited[r][c] = true;\n                while (!q.empty()) {\n                    Point curr = q.front();\n                    q.pop();\n                    size++;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = curr.r + dr[i];\n                        int nc = curr.c + dc[i];\n                        if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 &&\n                            !visited[nr][nc] && current_grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n/**\n * Simulates the effect of tilting the box in a given direction.\n * F: Front (r decreases), B: Backward (r increases), L: Left (c decreases), R: Right (c increases)\n */\nvoid simulate_tilt(int current_grid[10][10], char dir, int next_grid[10][10]) {\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            next_grid[i][j] = 0;\n\n    if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 0; r < 10; ++r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 9; r >= 0; --r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[9 - count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 0; c < 10; ++c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][count++] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 9; c >= 0; --c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][9 - count++] = current_grid[r][c];\n                }\n            }\n        }\n    }\n}\n\n/**\n * Applies the selected tilt to the current grid.\n */\nvoid apply_tilt(int current_grid[10][10], char dir) {\n    int next_grid[10][10];\n    simulate_tilt(current_grid, dir, next_grid);\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            current_grid[i][j] = next_grid[i][j];\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read the flavors of the 100 candies\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    // Initialize the grid as empty\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            grid[i][j] = 0;\n\n    char directions[] = {'F', 'B', 'L', 'R'};\n\n    // Process each of the 100 candies\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        if (!(cin >> p_t)) break;\n\n        // Locate the p_t-th empty cell (1-indexed)\n        vector<Point> empty_cells;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    empty_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // Place the t-th candy in the determined cell\n        Point pos = empty_cells[p_t - 1];\n        grid[pos.r][pos.c] = flavors[t - 1];\n\n        // Greedy strategy: choose the tilt direction that maximizes the current score\n        int best_score = -1;\n        char best_dir = 'F';\n\n        for (char d : directions) {\n            int next_grid_temp[10][10];\n            simulate_tilt(grid, d, next_grid_temp);\n            int score = calculate_score(next_grid_temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        // Output the chosen direction and flush\n        cout << best_dir << endl;\n        // Apply the move to the actual grid state\n        apply_tilt(grid, best_dir);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The task is to encode M distinct labels into N-vertex undirected graphs.\n * We then receive a noisy (edge flips with probability epsilon) and shuffled \n * (vertex permutation) version of a graph G_{s_k} and must predict s_k.\n * \n * Algorithm Strategy:\n * 1. Choice of G_i: Use cliques of different sizes. Let N = 100. \n *    For i = 0 to M-1, let G_i be a clique of size k_i = i+1.\n *    This ensures all G_i are distinct and have different edge counts and degree distributions.\n *    As i increases, the edge count and degrees increase.\n * \n * 2. Decoding (Prediction):\n *    For each received graph H, we want to find the index i that maximizes the \n *    likelihood P(H | G_i, P), which is equivalent to minimizing the number of \n *    mismatched edges under the best permutation P.\n *    - Step A: Filter candidate G_i based on the number of edges in H. \n *      The expected edge count in H is E[e(H)] = e(G_i)*(1-2*epsilon) + L*epsilon.\n *      We check only the top 40 G_i that have the closest expected edge counts.\n *    - Step B: For each candidate G_i, find an initial permutation P by sorting \n *      the vertex degrees of H and G_i. This is a robust starting point for \n *      clique-like graphs.\n *    - Step C: Improve the permutation using a greedy local search. \n *      Randomly pick two vertices and swap their mappings if it reduces the \n *      mismatch count.\n * \n * Efficiency:\n * With N=100 and M up to 100, the greedy swap search is O(M_candidates * iterations * N).\n * Given M_candidates = 40 and iterations = 300, this performs approximately 1.2e8 operations, \n * fitting comfortably within the 5s time limit.\n */\n\nint main() {\n    // Standard fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    if (!(cin >> M >> epsilon)) return 0;\n\n    int N = 100;\n    int L = N * (N - 1) / 2;\n    \n    // Pre-calculate G_i as adjacency matrices and edge counts\n    vector<vector<vector<int>>> G(M, vector<vector<int>>(N, vector<int>(N, 0)));\n    vector<int> Gi_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int k = i + 1; // Clique size\n        Gi_edges[i] = k * (k - 1) / 2;\n        for (int u = 0; u < k; ++u) {\n            for (int v = u + 1; v < k; ++v) {\n                G[i][u][v] = G[i][v][u] = 1;\n            }\n        }\n    }\n\n    // Output encoded graphs\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        string s = \"\";\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s += (G[i][u][v] ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    // Random number generator for local search\n    mt19937 rng(42);\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H_str;\n        if (!(cin >> H_str)) break;\n        \n        vector<vector<int>> H(N, vector<int>(N, 0));\n        int idx = 0;\n        int h_edges = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (H_str[idx++] == '1') {\n                    H[u][v] = H[v][u] = 1;\n                    h_edges++;\n                }\n            }\n        }\n\n        // Calculate degrees of H\n        vector<int> H_deg(N, 0);\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (H[u][v]) H_deg[u]++;\n            }\n        }\n\n        // Filter candidates by expected edge counts\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < M; ++i) {\n            double expected_h_edges = (double)Gi_edges[i] * (1.0 - 2.0 * epsilon) + (double)L * epsilon;\n            candidates.push_back({abs((double)h_edges - expected_h_edges), i});\n        }\n        sort(candidates.begin(), candidates.end());\n\n        int best_i = 0;\n        int min_mismatches = 1e9;\n\n        // Search in the top candidates\n        for (int c = 0; c < min(M, 40); ++c) {\n            int i = candidates[c].second;\n\n            // Calculate degrees of G_i\n            vector<int> G_deg(N, 0);\n            for (int u = 0; u < N; ++u) {\n                for (int v = 0; v < N; ++v) {\n                    if (G[i][u][v]) G_deg[u]++;\n                }\n            }\n\n            // Initialize permutation P by sorting vertex degrees\n            vector<int> H_indices(N), G_indices(N);\n            for (int j = 0; j < N; ++j) {\n                H_indices[j] = j;\n                G_indices[j] = j;\n            }\n            sort(H_indices.begin(), H_indices.end(), [&](int a, int b) {\n                return H_deg[a] < H_deg[b];\n            });\n            sort(G_indices.begin(), G_indices.end(), [&](int a, int b) {\n                return G_deg[a] < G_deg[b];\n            });\n\n            vector<int> P(N);\n            for (int j = 0; j < N; ++j) {\n                P[H_indices[j]] = G_indices[j];\n            }\n\n            // Initial mismatch count\n            int cur_mismatches = 0;\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (G[i][P[u]][P[v]] != H[u][v]) cur_mismatches++;\n                }\n            }\n\n            // Greedy local search to minimize mismatches\n            for (int iter = 0; iter < 300; ++iter) {\n                int u = rng() % N;\n                int v = rng() % N;\n                if (u == v) continue;\n\n                // Calculate change in mismatch count for swapping P[u] and P[v]\n                int delta = 0;\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    // Subtract current mismatch status for edges (u, k) and (v, k)\n                    if (G[i][P[u]][P[k]] != H[u][k]) delta--;\n                    if (G[i][P[v]][P[k]] != H[v][k]) delta--;\n                    // Add new mismatch status after swap\n                    if (G[i][P[v]][P[k]] != H[u][k]) delta++;\n                    if (G[i][P[u]][P[k]] != H[v][k]) delta++;\n                }\n                // Note: Edge (u, v) mismatch doesn't change as G is undirected\n\n                if (delta < 0) {\n                    cur_mismatches += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n\n            if (cur_mismatches < min_mismatches) {\n                min_mismatches = cur_mismatches;\n                best_i = i;\n            }\n        }\n\n        // Output prediction\n        cout << best_i << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Problem: Minimize the average frustration level caused by repairing roads over D days.\n * Each day, at most K edges can be repaired.\n * Frustration level f_k is the expected increase in shortest distances when edges of day k are removed.\n * \n * Strategy:\n * 1. The objective is to minimize the sum of f_k over all days.\n * 2. f_k depends only on the set of edges repaired on day k.\n * 3. Each edge's contribution to frustration can be estimated by how many shortest paths pass through it.\n * 4. An edge e=(u,v) with weight w is likely to increase distances by at least w if it's on a shortest path.\n * 5. We calculate an impact score for each edge: I(e) = edge_count[e] * weight[e],\n *    where edge_count[e] is the number of (i, j) pairs such that e is on the chosen shortest path from i to j.\n * 6. We sort edges by their impact score in descending order and distribute them across D days\n *    using a round-robin approach to spread out the most \"impactful\" edges.\n * 7. This ensures that no single day carries too many critical edges, thereby minimizing f_k.\n */\n\nconst long long INF = 1e18;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct AdjEdge {\n    int to, w, id;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w, i});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w, i});\n    }\n\n    // Read and skip coordinates (not needed for our strategy)\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // edge_count[i] will store how many shortest paths (for all starting vertices) pass through edge i\n    vector<long long> edge_count(M, 0);\n\n    // Calculate edge_count using Dijkstra and DAG-based counting\n    // Total complexity: O(N * (M + N log N))\n    for (int start = 1; start <= N; ++start) {\n        vector<long long> dist(N + 1, INF);\n        vector<int> parent_node(N + 1, -1);\n        vector<int> parent_edge(N + 1, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n\n        dist[start] = 0;\n        pq.push({0, start});\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& e : adj[u]) {\n                if (dist[e.to] > dist[u] + e.w) {\n                    dist[e.to] = dist[u] + e.w;\n                    parent_node[e.to] = u;\n                    parent_edge[e.to] = e.id;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n\n        // Sort nodes by distance in descending order to propagate counts up the shortest path DAG\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 1);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n\n        // node_count[u] is the number of reachable nodes from 'start' via paths passing through u\n        vector<long long> node_count(N + 1, 1);\n        for (int u : nodes) {\n            if (u != start && parent_edge[u] != -1) {\n                int p = parent_node[u];\n                int id = parent_edge[u];\n                edge_count[id] += node_count[u];\n                node_count[p] += node_count[u];\n            }\n        }\n    }\n\n    // Create an array of edge indices and sort them by the calculated impact score\n    vector<int> edge_indices(M);\n    iota(edge_indices.begin(), edge_indices.end(), 0);\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        // Heuristic impact: (count of shortest paths) * (weight of the edge)\n        return (long long)edge_count[a] * edges[a].w > (long long)edge_count[b] * edges[b].w;\n    });\n\n    // Distribute edges across D days using round-robin to balance the impact\n    vector<int> assignment(M);\n    int current_day = 0;\n    for (int idx : edge_indices) {\n        assignment[idx] = current_day + 1;\n        current_day = (current_day + 1) % D;\n    }\n\n    // Output the assigned day for each edge\n    for (int i = 0; i < M; ++i) {\n        cout << assignment[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem: AHC019 - Silhouette\n * \n * Analysis:\n * We are given two pairs of 2D silhouettes (front and right) for two 3D objects.\n * We need to construct a set of blocks such that the first set of silhouettes can be\n * formed by one subset of blocks, and the second set by another subset.\n * The score is minimized by using large blocks in both objects (as common blocks).\n * \n * Strategy:\n * 1. Identify the set of possible cubic regions (x, y, z) that satisfy the\n *    silhouette for object 1: S1 = {(x, y, z) | f1(z, x) == 1 and r1(z, y) == 1}.\n *    Similarly for S2.\n * 2. A cell (x, y, z) can be part of object 1 if and only if (x, y, z) is in S1.\n *    The set S1 itself satisfies the silhouette f1 and r1.\n * 3. To minimize the score, we maximize the volume of common blocks.\n *    The best common blocks are the connected components of S1 \u2229 S2.\n * 4. To avoid wasting blocks, we cover the remaining cells in S1 (those not in S2)\n *    and the remaining cells in S2 (those not in S1) with their own connected components.\n * 5. Each connected component becomes a single block. Since each block is a component,\n *    it is guaranteed to be connected. Since the components are derived from disjoint\n *    sets of cells (S_common, S_only1, S_only2), they do not overlap.\n * \n * Complexity:\n * O(D^3) time and memory, which is well within limits for D up to 14.\n */\n\nstruct Cell {\n    int x, y, z;\n};\n\nvoid find_components(const vector<vector<vector<bool>>>& S, int type, int D,\n                    vector<vector<vector<int>>>& b1, vector<vector<vector<int>>>& b2,\n                    int& block_id) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    static const int dx[] = {1, -1, 0, 0, 0, 0};\n    static const int dy[] = {0, 0, 1, -1, 0, 0};\n    static const int dz[] = {0, 0, 0, 0, 1, -1};\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S[x][y][z] && !visited[x][y][z]) {\n                    block_id++;\n                    queue<Cell> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    while (!q.empty()) {\n                        Cell curr = q.front();\n                        q.pop();\n                        \n                        if (type == 0) { // block in both objects\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 1) { // block in object 1 only\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 2) { // block in object 2 only\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        }\n\n                        for (int i = 0; i < 6; ++i) {\n                            int nx = curr.x + dx[i];\n                            int ny = curr.y + dy[i];\n                            int nz = curr.z + dz[i];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && \n                                S[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                visited[nx][ny][nz] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n    for (int i = 0; i < D; ++i) cin >> f2[i];\n    for (int i = 0; i < D; ++i) cin >> r2[i];\n\n    // Function to derive the set of valid cells from silhouette arrays\n    auto get_S = [&](const vector<string>& f, const vector<string>& r) {\n        vector<vector<vector<bool>>> S(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x) {\n                for (int y = 0; y < D; ++y) {\n                    if (f[z][x] == '1' && r[z][y] == '1') {\n                        S[x][y][z] = true;\n                    }\n                }\n            }\n        }\n        return S;\n    };\n\n    auto S1 = get_S(f1, r1);\n    auto S2 = get_S(f2, r2);\n\n    // Arrays to store the block ID at each location for each object\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int total_blocks = 0;\n\n    // Pre-calculating the three types of cell sets\n    vector<vector<vector<bool>>> S_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S1[x][y][z] && S2[x][y][z]) {\n                    S_common[x][y][z] = true;\n                } else if (S1[x][y][z]) {\n                    S_only1[x][y][z] = true;\n                } else if (S2[x][y][z]) {\n                    S_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Find all connected components in each of the three sets\n    find_components(S_common, 0, D, b1, b2, total_blocks);\n    find_components(S_only1, 1, D, b1, b2, total_blocks);\n    find_components(S_only2, 2, D, b1, b2, total_blocks);\n\n    // Output the results\n    cout << total_blocks << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b1[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b2[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize a cost function S = sum(P_i^2) + sum(w_j) where P_i is the output strength\n * of station i and w_j is the weight of an activated edge j. All residents must be covered.\n * A resident is covered if it's within distance P_i of some station i reachable from station 1.\n * \n * Algorithm:\n * 1. We use a Steiner Tree approximation approach to ensure connectivity and cover all residents.\n * 2. First, compute all-pairs shortest paths (APSP) using Floyd-Warshall.\n * 3. For each resident, identify its closest vertex in the entire graph. Let this set of vertices be V_target.\n * 4. Construct a metric closure of the graph using only vertices in V_target and find its Minimum Spanning Tree (MST).\n * 5. The union of the shortest paths corresponding to the MST edges forms our connected set of stations (V_prime) and cables (E_prime).\n * 6. For each resident, assign it to its closest vertex in V_prime and calculate the required P_i.\n * 7. Since all residents were within 5000 of some station, a valid configuration exists.\n */\n\nstruct Edge {\n    int u, v;\n    long long w;\n    int id;\n};\n\nstruct Resident {\n    int x, y;\n};\n\nstruct Station {\n    int x, y;\n};\n\nconst long long INF_LL = 1e18;\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n\n    vector<Edge> edges(M);\n    vector<vector<long long>> dist_matrix(N, vector<long long>(N, INF_LL));\n    vector<vector<int>> next_node(N, vector<int>(N, -1));\n    vector<vector<int>> adj_edge_idx(N, vector<int>(N, -1));\n\n    for (int i = 0; i < N; ++i) dist_matrix[i][i] = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        // Standard way to handle weights in adjacency matrices for Floyd-Warshall\n        if (w < dist_matrix[u][v]) {\n            dist_matrix[u][v] = dist_matrix[v][u] = w;\n            next_node[u][v] = v;\n            next_node[v][u] = u;\n            adj_edge_idx[u][v] = adj_edge_idx[v][u] = i;\n        }\n    }\n\n    vector<Resident> residents(K);\n    for (int i = 0; i < K; ++i) {\n        cin >> residents[i].x >> residents[i].y;\n    }\n\n    // Floyd-Warshall for All-Pairs Shortest Paths and reconstruction paths\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (dist_matrix[i][k] != INF_LL && dist_matrix[k][j] != INF_LL && \n                    dist_matrix[i][k] + dist_matrix[k][j] < dist_matrix[i][j]) {\n                    dist_matrix[i][j] = dist_matrix[i][k] + dist_matrix[k][j];\n                    next_node[i][j] = next_node[i][k];\n                }\n            }\n        }\n    }\n\n    // Determine the set of target vertices V_target\n    vector<int> V_target;\n    vector<bool> is_in_target(N, false);\n    V_target.push_back(0); // Station 1 is always a source\n    is_in_target[0] = true;\n\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_sq = 1e20;\n        for (int i = 0; i < N; ++i) {\n            double dx = (double)stations[i].x - residents[k].x;\n            double dy = (double)stations[i].y - residents[k].y;\n            double d2 = dx * dx + dy * dy;\n            if (d2 < min_dist_sq) {\n                min_dist_sq = d2;\n                best_i = i;\n            }\n        }\n        if (best_i != -1 && !is_in_target[best_i]) {\n            is_in_target[best_i] = true;\n            V_target.push_back(best_i);\n        }\n    }\n\n    // Calculate MST of the metric closure of V_target\n    int T_size = (int)V_target.size();\n    struct MSTEdge {\n        int u, v;\n        long long w;\n    };\n    vector<MSTEdge> mst_edges;\n    if (T_size > 1) {\n        // Prim's algorithm for MST on metric closure\n        vector<long long> min_dist_prim(T_size, INF_LL);\n        vector<int> parent(T_size, -1);\n        vector<bool> visited(T_size, false);\n        min_dist_prim[0] = 0;\n        for (int i = 0; i < T_size; ++i) {\n            int u_idx = -1;\n            for (int j = 0; j < T_size; ++j) {\n                if (!visited[j] && (u_idx == -1 || min_dist_prim[j] < min_dist_prim[u_idx])) {\n                    u_idx = j;\n                }\n            }\n            if (u_idx == -1 || min_dist_prim[u_idx] == INF_LL) break;\n            visited[u_idx] = true;\n            if (parent[u_idx] != -1) {\n                mst_edges.push_back({V_target[parent[u_idx]], V_target[u_idx], min_dist_prim[u_idx]});\n            }\n            for (int v_idx = 0; v_idx < T_size; ++v_idx) {\n                if (!visited[v_idx]) {\n                    long long weight_uv = dist_matrix[V_target[u_idx]][V_target[v_idx]];\n                    if (weight_uv < min_dist_prim[v_idx]) {\n                        min_dist_prim[v_idx] = weight_uv;\n                        parent[v_idx] = u_idx;\n                    }\n                }\n            }\n        }\n    }\n\n    // Reconstruct the connected subgraph V_prime and E_prime\n    vector<bool> is_in_prime(N, false);\n    is_in_prime[0] = true;\n    vector<int> B(M, 0);\n\n    for (auto& me : mst_edges) {\n        int u = me.u;\n        int v = me.v;\n        int curr = u;\n        while (curr != v) {\n            int nxt = next_node[curr][v];\n            if (nxt == -1) break;\n            int edge_idx = adj_edge_idx[curr][nxt];\n            if (edge_idx != -1) B[edge_idx] = 1;\n            is_in_prime[nxt] = true;\n            curr = nxt;\n        }\n        is_in_prime[u] = true;\n    }\n\n    // Determine minimal P_i for all i in V_prime to cover all residents\n    vector<int> P(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_val = 1e20;\n        for (int i = 0; i < N; ++i) {\n            if (is_in_prime[i]) {\n                double dx = (double)stations[i].x - residents[k].x;\n                double dy = (double)stations[i].y - residents[k].y;\n                double cur_dist = sqrt(dx * dx + dy * dy);\n                if (cur_dist < min_dist_val) {\n                    min_dist_val = cur_dist;\n                    best_i = i;\n                }\n            }\n        }\n        if (best_i != -1) {\n            // Use ceil to ensure coverage, subtracting epsilon for precision stability\n            int needed_radius = (int)ceil(min_dist_val - 1e-8);\n            if (needed_radius > P[best_i]) P[best_i] = needed_radius;\n        }\n    }\n\n    // Clamp P_i to maximum possible radius\n    for (int i = 0; i < N; ++i) {\n        if (P[i] > 5000) P[i] = 5000;\n    }\n\n    // Output P values\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    // Output B values\n    for (int i = 0; i < M; ++i) {\n        cout << B[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\n/**\n * Problem Analysis:\n * The problem asks to arrange balls in an N-tiered pyramid such that for every ball \n * at (x, y), its value is smaller than the values of its two children at (x+1, y) \n * and (x+1, y+1). This is exactly the min-heap property in a 2D triangular structure.\n * The allowed operation is swapping two adjacent balls in six directions. \n * Since the parent (x, y) and its children (x+1, y) and (x+1, y+1) are \n * already adjacent in the six specified directions, we can use the standard \n * \"heapify\" algorithm (sift-down approach) to satisfy the heap property.\n *\n * Heapify Algorithm:\n * Starting from the last non-leaf node (tier N-2 down to 0), we perform \n * a sift-down operation for each node. A sift-down operation swaps a node \n * with its smallest child if the node's value is larger than the smallest \n * child's value, and repeats this until the heap property is satisfied \n * for that node.\n *\n * Complexity:\n * The number of balls M = N(N+1)/2 = 465 for N = 30.\n * The heapify algorithm's worst-case number of swaps is roughly the sum \n * of the depths of all nodes, which for N=30 is at most 4495. \n * This is well within the 10,000 swap limit.\n * The time complexity is O(M), which is very efficient for the given constraints.\n *\n * Score Optimization:\n * A complete heap (E=0) will yield a score of 100000 - 5K.\n * Since K <= 4495, the minimum score will be at least 77525, \n * which is much higher than the maximum possible score for E > 0 (50000).\n */\n\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    // Speed up I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    vector<vector<int>> pyramid(N, vector<int>(N, 0));\n\n    // Read input: N-tiered pyramid\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> pyramid[i][j])) break;\n        }\n    }\n\n    vector<Swap> swaps;\n\n    // Build the min-heap using the sift-down (heapify) method\n    // Start from the second to last tier and move up to the top tier.\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int curX = x;\n            int curY = y;\n\n            // Sift down the ball at (curX, curY)\n            while (curX < N - 1) {\n                int childX = curX + 1;\n                int childY1 = curY;\n                int childY2 = curY + 1;\n\n                int smallestX = curX;\n                int smallestY = curY;\n                int minVal = pyramid[curX][curY];\n\n                // Compare with child 1: (curX+1, curY)\n                if (childX < N && childY1 <= childX) {\n                    if (pyramid[childX][childY1] < minVal) {\n                        minVal = pyramid[childX][childY1];\n                        smallestX = childX;\n                        smallestY = childY1;\n                    }\n                }\n                // Compare with child 2: (curX+1, curY+1)\n                if (childX < N && childY2 <= childX) {\n                    if (pyramid[childX][childY2] < minVal) {\n                        minVal = pyramid[childX][childY2];\n                        smallestX = childX;\n                        smallestY = childY2;\n                    }\n                }\n\n                // If the smallest of the current node and its children is one of the children, swap.\n                if (smallestX != curX) {\n                    swaps.push_back({curX, curY, smallestX, smallestY});\n                    swap(pyramid[curX][curY], pyramid[smallestX][smallestY]);\n                    // Continue sifting down the ball that was swapped up.\n                    curX = smallestX;\n                    curY = smallestY;\n                } else {\n                    // Heap property satisfied for this subtree.\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output the number of operations and the sequence of swaps.\n    cout << swaps.size() << \"\\n\";\n    for (const auto& s : swaps) {\n        cout << s.x1 << \" \" << s.y1 << \" \" << s.x2 << \" \" << s.y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to store containers such that they can be transported out in an order close to 0, 1, 2, ...\n * The primary constraint is that a container must be reachable from the entrance via empty squares.\n * During storage, \"empty\" means \"has not had a container placed in it yet\".\n * During transportation, \"empty\" means \"has had its container transported out already\".\n *\n * Strategy:\n * 1. Precompute a BFS order of all non-obstacle, non-entrance squares. Let this be v_0, v_1, ..., v_M.\n * 2. When container t_d arrives, try to place it in v_{t_d}. \n *    Check if v_{t_d} is reachable from the entrance using only currently empty (unoccupied) squares.\n *    If v_{t_d} is reachable, place it there.\n *    Otherwise, place it in the first available empty square in the BFS order that is reachable.\n * 3. Once all containers are stored, the transport phase begins. \n *    To minimize inversions, use a greedy strategy: at each step, pick the reachable container with the smallest ID.\n *    A container is reachable if it's adjacent to an empty square (initially only the entrance is empty).\n */\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint D, N;\nbool is_obstacle[9][9];\nbool is_occupied[9][9];\nPos square_of_id[81];\nint id_at_square[9][9];\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D && !is_obstacle[r][c];\n}\n\n// Checks if a square is reachable from the entrance through currently empty squares\nbool is_reachable(Pos target, Pos entrance) {\n    if (target == entrance) return true;\n    if (is_occupied[target.r][target.c]) return false;\n\n    queue<Pos> q;\n    q.push(entrance);\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    visited[entrance.r][entrance.c] = true;\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        if (curr == target) return true;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc) && !is_occupied[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                q.push({nr, nc});\n            }\n        }\n    }\n    // One more check: the target itself might be adjacent to an empty square\n    for (int i = 0; i < 4; ++i) {\n        int nr = target.r + dr[i];\n        int nc = target.c + dc[i];\n        if (nr == entrance.r && nc == entrance.c) return true;\n        if (is_valid(nr, nc) && !is_occupied[nr][nc] && visited[nr][nc]) return true;\n    }\n\n    return false;\n}\n\n// Alternative reachability: is target reachable if it is adjacent to an empty square that is reachable?\nbool is_reachable_final(Pos target, Pos entrance) {\n    queue<Pos> q;\n    q.push(entrance);\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    visited[entrance.r][entrance.c] = true;\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc)) {\n                if (nr == target.r && nc == target.c) return true;\n                if (!is_occupied[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n\n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            is_obstacle[i][j] = false;\n            is_occupied[i][j] = false;\n            id_at_square[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    Pos entrance = {0, (D - 1) / 2};\n    int total_containers = D * D - 1 - N;\n\n    // BFS order to define preferred squares\n    vector<Pos> bfs_order;\n    queue<Pos> q_bfs;\n    vector<vector<bool>> bfs_visited(D, vector<bool>(D, false));\n    q_bfs.push(entrance);\n    bfs_visited[entrance.r][entrance.c] = true;\n\n    while (!q_bfs.empty()) {\n        Pos curr = q_bfs.front();\n        q_bfs.pop();\n        if (!(curr == entrance)) bfs_order.push_back(curr);\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc) && !bfs_visited[nr][nc]) {\n                bfs_visited[nr][nc] = true;\n                q_bfs.push({nr, nc});\n            }\n        }\n    }\n\n    for (int d = 0; d < total_containers; ++d) {\n        int t_d;\n        cin >> t_d;\n\n        Pos target = (t_d < (int)bfs_order.size()) ? bfs_order[t_d] : bfs_order.back();\n        \n        // If the preferred square isn't reachable, find the first reachable empty square in BFS order\n        if (!is_reachable_final(target, entrance)) {\n            bool found = false;\n            for (auto& p : bfs_order) {\n                if (!is_occupied[p.r][p.c] && is_reachable_final(p, entrance)) {\n                    target = p;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                // Fallback: just pick the first available valid square\n                for (auto& p : bfs_order) {\n                    if (!is_occupied[p.r][p.c]) {\n                        target = p;\n                        break;\n                    }\n                }\n            }\n        }\n\n        is_occupied[target.r][target.c] = true;\n        id_at_square[target.r][target.c] = t_d;\n        square_of_id[t_d] = target;\n        cout << target.r << \" \" << target.c << endl;\n    }\n\n    // Transport phase\n    vector<Pos> transport_order;\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[entrance.r][entrance.c] = true;\n    \n    // Initially, only the entrance is empty\n    // A container is reachable if it's adjacent to an empty square\n    auto get_reachable_containers = [&]() {\n        vector<pair<int, Pos>> reachable;\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                if (id_at_square[r][c] != -1) {\n                    bool adj_to_empty = false;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r + dr[i], nc = c + dc[i];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && is_empty[nr][nc]) {\n                            adj_to_empty = true;\n                            break;\n                        }\n                    }\n                    if (adj_to_empty) {\n                        reachable.push_back({id_at_square[r][c], {r, c}});\n                    }\n                }\n            }\n        }\n        return reachable;\n    };\n\n    // Greedy transport: pick smallest ID among reachable\n    // Since the number of containers is small (up to 80), we can re-scan every time\n    vector<bool> transported(total_containers, false);\n    for (int i = 0; i < total_containers; ++i) {\n        int best_id = 1e9;\n        Pos best_pos = {-1, -1};\n\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                int id = id_at_square[r][c];\n                if (id != -1 && !transported[id]) {\n                    bool adj_to_empty = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = r + dr[k], nc = c + dc[k];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && is_empty[nr][nc]) {\n                            adj_to_empty = true;\n                            break;\n                        }\n                    }\n                    if (adj_to_empty && id < best_id) {\n                        best_id = id;\n                        best_pos = {r, c};\n                    }\n                }\n            }\n        }\n\n        if (best_id != 1e9) {\n            transported[best_id] = true;\n            is_empty[best_pos.r][best_pos.c] = true;\n            id_at_square[best_pos.r][best_pos.c] = -1; // Mark square as empty\n            transport_order.push_back(best_pos);\n        } else {\n            // If no container is reachable, there's an issue with the storage or path.\n            // In a real contest, we would need to handle this. For this problem, the BFS order\n            // and the logic should prevent this.\n            break;\n        }\n    }\n\n    for (auto& p : transport_order) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to represent a given adjacency graph of colors (wards) on an n x n grid,\n * minimizing the number of tiles used for the wards (maximizing the number of color 0 tiles).\n * The adjacencies between any two colors (including color 0) must be identical to the original.\n * Each color must form a connected set of tiles.\n * \n * Since the adjacency graph is planar (derived from a map), and the grid (50x50) is much larger \n * than the number of colors (100), we can use a greedy approach.\n * We place each color one by one using a BFS-based path construction.\n * To maintain the \"identical adjacency\" property, we use a \"safe cell\" condition:\n * a cell is safe for color c if it is currently color 0 and all its non-zero neighbors \n * are colors that c is actually adjacent to in the original map.\n * \n * Algorithm:\n * 1. Construct the adjacency graph G from the input.\n * 2. Use a BFS order starting from color 0 to decide the order of placing colors.\n * 3. For each color c:\n *    a. Identify the set T of colors already placed that c is adjacent to in G.\n *    b. Find a path of \"safe\" cells that connects c to all colors in T.\n *    c. A cell is safe if it's 0 and all its neighbors in the current grid belong to T.\n *    d. Use BFS to find the shortest paths connecting these target colors.\n *    e. Update the grid by coloring these cells with c.\n * 4. Output the resulting grid.\n */\n\nconst int N = 50;\nint grid[N][N];\nint n, m;\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < n && c >= 0 && c < n;\n}\n\n// A cell is safe for color c if it's 0 and its non-0 neighbors are all in the target set T.\nbool is_safe(int r, int c, const set<int>& T) {\n    if (grid[r][c] != 0) return false;\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (is_valid(nr, nc)) {\n            if (grid[nr][nc] != 0) {\n                if (T.find(grid[nr][nc]) == T.end()) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> original_grid(n, vector<int>(n));\n    set<int> adj[105]; // m can be up to 100\n    \n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> original_grid[i][j];\n        }\n    }\n\n    // Build the adjacency graph from the input map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = original_grid[i][j];\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (is_valid(ni, nj)) {\n                    int nc = original_grid[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                        adj[nc].insert(c);\n                    }\n                } else {\n                    // Adjacent to the outside (represented by color 0)\n                    if (c != 0) {\n                        adj[c].insert(0);\n                        adj[0].insert(c);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initialize the output grid with 0\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            grid[i][j] = 0;\n        }\n    }\n\n    // Determine the order of placement using BFS from color 0\n    vector<int> bfs_order;\n    queue<int> q_bfs;\n    q_bfs.push(0);\n    vector<bool> visited_bfs(m + 1, false);\n    visited_bfs[0] = true;\n    while (!q_bfs.empty()) {\n        int u = q_bfs.front();\n        q_bfs.pop();\n        if (u != 0) bfs_order.push_back(u);\n        for (int v : adj[u]) {\n            if (v <= m && v != 0 && !visited_bfs[v]) {\n                visited_bfs[v] = true;\n                q_bfs.push(v);\n            }\n        }\n    }\n    // Add any unvisited colors just in case\n    for (int i = 1; i <= m; ++i) {\n        if (!visited_bfs[i]) bfs_order.push_back(i);\n    }\n\n    set<int> P = {0}; // Colors already placed in the output grid\n\n    for (int c : bfs_order) {\n        // T is the set of colors already in the grid that c must be adjacent to\n        set<int> T;\n        for (int neighbor : adj[c]) {\n            if (P.count(neighbor)) {\n                T.insert(neighbor);\n            }\n        }\n\n        if (T.empty()) continue;\n\n        vector<Pos> Sc; // Set of cells to be assigned color c\n        Pos start_pos = {-1, -1};\n        bool found_start = false;\n        \n        // Find a starting safe cell adjacent to the first color in T\n        int d_first = *T.begin();\n        if (d_first != 0) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (grid[i][j] == d_first) {\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && is_safe(ni, nj, T)) {\n                                start_pos = {ni, nj};\n                                found_start = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            // If the first color is 0, any safe cell adjacent to 0 works\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        bool adj_to_zero = false;\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && grid[ni][nj] == 0) {\n                                adj_to_zero = true;\n                                break;\n                            }\n                        }\n                        if (adj_to_zero) {\n                            start_pos = {i, j};\n                            found_start = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: if no specifically adjacent start cell is found, pick any safe cell\n        if (!found_start) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        start_pos = {i, j};\n                        found_start = true;\n                    }\n                }\n            }\n        }\n\n        if (found_start) {\n            Sc.push_back(start_pos);\n            // Iteratively connect Sc to every other color in T using BFS\n            for (int d : T) {\n                if (d == d_first) continue;\n                \n                // Check if Sc is already adjacent to color d\n                bool already_adj = false;\n                for (auto p : Sc) {\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = p.r + dr[k], nj = p.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            already_adj = true;\n                            break;\n                        }\n                    }\n                    if (already_adj) break;\n                }\n                if (already_adj) continue;\n\n                // BFS to find the shortest path of safe cells to color d\n                queue<Pos> q;\n                vector<vector<int>> dist(n, vector<int>(n, -1));\n                vector<vector<Pos>> parent(n, vector<Pos>(n, {-1, -1}));\n                for (auto p : Sc) {\n                    q.push(p);\n                    dist[p.r][p.c] = 0;\n                }\n                Pos end_pos = {-1, -1};\n                while (!q.empty()) {\n                    Pos curr = q.front(); q.pop();\n                    bool adj_to_d = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = curr.r + dr[k], nj = curr.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            adj_to_d = true; \n                            break;\n                        }\n                    }\n                    if (adj_to_d) {\n                        end_pos = curr;\n                        break;\n                    }\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = curr.r + dr[k], nc = curr.c + dc[k];\n                        if (is_valid(nr, nc) && dist[nr][nc] == -1 && is_safe(nr, nc, T)) {\n                            dist[nr][nc] = dist[curr.r][curr.c] + 1;\n                            parent[nr][nc] = curr;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                // If a path is found, add it to the set Sc\n                if (end_pos.r != -1) {\n                    Pos curr = end_pos;\n                    while (dist[curr.r][curr.c] != 0) {\n                        Sc.push_back(curr);\n                        curr = parent[curr.r][curr.c];\n                    }\n                }\n            }\n            // Update grid with color c\n            for (auto p : Sc) grid[p.r][p.c] = c;\n            P.insert(c);\n        }\n    }\n\n    // Print the resulting map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc025":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to divide N items into D sets of equal total weight as much as possible, \n * given that item weights are unknown and we can only query the balance.\n * \n * Strategy:\n * 1. Estimate item weights: Use a gradient descent-based approach (specifically, Adam optimizer) \n *    to find weights that satisfy the comparison queries. We use the logarithm of weights \n *    (x_i = log(w_i)) to ensure weights are always positive and to handle potential scale issues.\n * 2. Intelligent Queries: In each step, pick items for the balance that make the sums on both sides \n *    as close as possible. This maximizes information gain when the balance result is unexpected.\n * 3. Partitioning: Once weights are estimated, use a Greedy approach combined with local \n *    search (hill climbing) to minimize the variance of the sums of weights in each set.\n */\n\nstruct Query {\n    vector<int> L, R;\n    char res;\n};\n\nint main() {\n    // Speed up input and output\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // x_i stores the log of the estimated weight w_i\n    vector<double> x(N, 0.0);\n    // Adam optimizer parameters\n    vector<double> m(N, 0.0); // First moment\n    vector<double> v(N, 0.0); // Second moment\n    double beta1 = 0.9, beta2 = 0.999, eps = 1e-8, alpha = 0.01;\n    double lambda = 0.01; // Regularization constant\n    vector<Query> queries;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int t_adam = 0; // Time step for Adam\n\n    for (int q = 0; q < Q; ++q) {\n        // Step 1: Select L and R for the query. \n        // We want |sum(L) - sum(R)| to be small.\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n\n        vector<int> best_L, best_R;\n        double best_diff = 1e18;\n\n        // Try multiple randomized greedy attempts to find good L and R\n        for (int attempt = 0; attempt < 40; ++attempt) {\n            vector<int> L, R;\n            double sumL = 0, sumR = 0;\n\n            // Ensure sets are non-empty\n            int i1 = indices[0], i2 = indices[1];\n            L.push_back(i1); sumL += exp(x[i1]);\n            R.push_back(i2); sumR += exp(x[i2]);\n\n            for (int i = 2; i < N; ++i) {\n                int idx = indices[i];\n                double val = exp(x[idx]);\n                double diff_L = abs(sumL + val - sumR);\n                double diff_R = abs(sumL - (sumR + val));\n                double diff_none = abs(sumL - sumR);\n\n                // Greedily decide to add item to L, R, or skip it\n                if (diff_L < diff_R && diff_L < diff_none) {\n                    L.push_back(idx);\n                    sumL += val;\n                } else if (diff_R < diff_none) {\n                    R.push_back(idx);\n                    sumR += val;\n                }\n            }\n\n            double diff = abs(sumL - sumR);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_L = L;\n                best_R = R;\n            }\n        }\n\n        // Output selected sets for the balance query\n        cout << best_L.size() << \" \" << best_R.size();\n        for (int idx : best_L) cout << \" \" << idx;\n        for (int idx : best_R) cout << \" \" << idx;\n        cout << endl;\n\n        char res;\n        if (!(cin >> res)) break;\n        queries.push_back({best_L, best_R, res});\n\n        // Step 2: Update weight estimates using Adam optimizer on recent queries\n        int M_window = min((int)queries.size(), 150);\n        int K_steps = 4;\n        for (int k_step = 0; k_step < K_steps; ++k_step) {\n            t_adam++;\n            vector<double> g(N, 0.0);\n            for (int i = 0; i < M_window; ++i) {\n                const auto& query = queries[queries.size() - 1 - i];\n                double sumL = 0, sumR = 0;\n                for (int idx : query.L) sumL += exp(x[idx]);\n                for (int idx : query.R) sumR += exp(x[idx]);\n                double d = sumL - sumR;\n\n                // Calculate gradient of squared loss function\n                if (query.res == '<') {\n                    if (d > 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '>') {\n                    if (d < 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '=') {\n                    for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                    for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                }\n            }\n            // Add regularization gradient to prevent x_i from exploding\n            for (int i = 0; i < N; ++i) g[i] += 2 * lambda * x[i];\n\n            // Adam update step\n            for (int i = 0; i < N; ++i) {\n                m[i] = beta1 * m[i] + (1.0 - beta1) * g[i];\n                v[i] = beta2 * v[i] + (1.0 - beta2) * g[i] * g[i];\n                double m_hat = m[i] / (1.0 - pow(beta1, t_adam));\n                double v_hat = v[i] / (1.0 - pow(beta2, t_adam));\n                x[i] -= alpha * m_hat / (sqrt(v_hat) + eps);\n            }\n        }\n    }\n\n    // Step 3: Final Division\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = exp(x[i]);\n\n    vector<int> d(N);\n    vector<double> set_sum(D, 0.0);\n\n    // Initial division using a greedy approach\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    for (int idx : p) {\n        int best_s = 0;\n        for (int s = 1; s < D; ++s) {\n            if (set_sum[s] < set_sum[best_s]) best_s = s;\n        }\n        d[idx] = best_s;\n        set_sum[best_s] += w[idx];\n    }\n\n    // Refine partition using hill climbing to minimize sum of squares (proportional to variance)\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            int old_s = d[i];\n            for (int new_s = 0; new_s < D; ++new_s) {\n                if (old_s == new_s) continue;\n                \n                double old_sum_sq = 0;\n                for (int s = 0; s < D; ++s) old_sum_sq += set_sum[s] * set_sum[s];\n                \n                double temp_sum_old = set_sum[old_s] - w[i];\n                double temp_sum_new = set_sum[new_s] + w[i];\n                double new_sum_sq_val = old_sum_sq - set_sum[old_s]*set_sum[old_s] - set_sum[new_s]*set_sum[new_s] + temp_sum_old*temp_sum_old + temp_sum_new*temp_sum_new;\n                \n                // If moving item i to new_s reduces the sum of squared set weights, accept move\n                if (new_sum_sq_val < old_sum_sq - 1e-7) {\n                    set_sum[old_s] -= w[i];\n                    set_sum[new_s] += w[i];\n                    d[i] = new_s;\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <deque>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - There are n boxes in m stacks.\n * - We need to remove boxes in ascending order (1, 2, ..., n).\n * - Operation 1: Move box v and all boxes above it in its stack to the top of another stack i.\n *   Cost: (number of boxes moved) + 1.\n * - Operation 2: Remove the current smallest box if it is at the top of a stack.\n *   Cost: 0.\n * - Goal: Minimize the total energy expenditure (sum of costs of Operation 1).\n * - Constraints: n = 200, m = 10, max operations 5000.\n *\n * Strategy:\n * - For each box v = 1, 2, ..., n:\n *   - Identify the stack where box v is currently located.\n *   - If v is not at the top of its stack, it must be moved. To make v the top,\n *     we need to move all boxes currently sitting on top of it to other stacks.\n *   - To minimize the number of Operation 1 calls, we can move all boxes above v\n *     to another stack in a single operation.\n *   - We pick the box immediately above v (let's call it u) to be the trigger for\n *     Operation 1. Moving u and all boxes above it will leave v at the top.\n *   - The destination stack for the moved boxes should be chosen to balance the\n *     stacks, so we select the stack with the minimum number of boxes (excluding\n *     the current stack).\n *   - Once v is at the top, use Operation 2 to remove it.\n *\n * Complexity Analysis:\n * - Each box is moved to another stack at most a few times. The total number of\n *   Operation 1 calls will be at most n, and the total number of operations\n *   (Op 1 + Op 2) will be at most 2n = 400, well within the 5000 limit.\n * - The total energy cost will be approximately O(n^2), which for n=200 is roughly 20,000.\n *   While this might not reach the highest score, it is a solid heuristic approach.\n * - Finding v and performing operations takes O(n) per box, so the overall \n *   complexity is O(n^2), which is very efficient for n=200.\n */\n\nint main() {\n    // Optimize standard I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    // stacks[i] stores the boxes in stack i (bottom to top)\n    vector<deque<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n\n    // Store the list of operations (box, stack_index)\n    // stack_index is 0 for Operation 2, and 1-indexed for Operation 1\n    vector<pair<int, int>> operations;\n\n    for (int v = 1; v <= n; ++v) {\n        int current_stack_idx = -1;\n        int v_pos = -1;\n\n        // Step 1: Find the current position and stack of box v\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                    current_stack_idx = i;\n                    v_pos = j;\n                    break;\n                }\n            }\n            if (current_stack_idx != -1) break;\n        }\n\n        // Step 2: If v is not at the top, move all boxes above it\n        while (v_pos < (int)stacks[current_stack_idx].size() - 1) {\n            // The box immediately above v becomes the target for Operation 1\n            int u_idx = v_pos + 1;\n            int u = stacks[current_stack_idx][u_idx];\n            \n            // Find the best target stack (the one with the fewest boxes)\n            int target_stack_idx = -1;\n            size_t min_size = (size_t)n + 1;\n            for (int i = 0; i < m; ++i) {\n                if (i != current_stack_idx) {\n                    if (stacks[i].size() < min_size) {\n                        min_size = stacks[i].size();\n                        target_stack_idx = i;\n                    }\n                }\n            }\n\n            // Collect all boxes to move (from u to the current top of the stack)\n            vector<int> to_move;\n            for (int k = u_idx; k < (int)stacks[current_stack_idx].size(); ++k) {\n                to_move.push_back(stacks[current_stack_idx][k]);\n            }\n            \n            // Remove the moved boxes from the current stack\n            for (int k = 0; k < (int)to_move.size(); ++k) {\n                stacks[current_stack_idx].pop_back();\n            }\n\n            // Add the moved boxes to the top of the target stack\n            for (int val : to_move) {\n                stacks[target_stack_idx].push_back(val);\n            }\n\n            // Record the Operation 1 (v_target, target_stack_1_indexed)\n            operations.push_back({u, target_stack_idx + 1});\n\n            // After this move, v remains at the same index in the current stack,\n            // and it is now at the top because all boxes above it were moved.\n        }\n\n        // Step 3: v is now at the top, so remove it using Operation 2\n        operations.push_back({v, 0});\n        stacks[current_stack_idx].pop_back();\n    }\n\n    // Step 4: Output the generated sequence of operations\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem analysis:\n * The goal is to minimize the average dirtiness of an N x N grid by finding a cleaning route\n * of length L (L <= 10^5) that visits every square at least once and returns to (0,0).\n * The dirtiness of square (i, j) is (time since last visit) * d_{i,j}.\n * In the steady state (after repeating the cycle), the average dirtiness of square (i, j) \n * is approximately d_{i,j} * (gap_{i,j} - 1) / 2, where gap_{i,j} is the average interval\n * between visits to square (i, j).\n * To minimize sum(d_{i,j} * (gap_{i,j} - 1) / 2) subject to sum(1 / gap_{i,j}) = 1,\n * the optimal visit frequency f_{i,j} = 1/gap_{i,j} should be proportional to sqrt(d_{i,j}).\n * This suggests that squares with higher susceptibility should be visited more frequently.\n * \n * Algorithm:\n * 1. Generate an initial cleaning route that visits all reachable squares using DFS.\n *    In a DFS traversal of the grid, each edge is traversed twice, ensuring we visit all nodes.\n * 2. Calculate the target visit frequency for each square: m_{i,j} proportional to sqrt(d_{i,j}).\n * 3. To increase the visit frequency of certain squares, add \"detours\" to the DFS route.\n *    For any edge (u, v) in the DFS route, a detour consists of moving u -> v -> u -> v,\n *    which increases the visit counts of both u and v by 1 and increases the total length L by 2.\n * 4. Greedily add detours to the edges that provide the most benefit towards reaching the target \n *    visit counts, using a priority queue to efficiently select the best edge.\n * 5. Output the resulting sequence of moves.\n */\n\nint N;\nvector<string> h_walls;\nvector<string> v_walls;\nvector<vector<int>> d;\n\nstruct Square {\n    int r, c;\n};\n\nvector<Square> path;\nvector<char> move_chars;\nbool visited[40][40];\n\n// DFS to generate a route that visits all squares and returns to (0,0)\nvoid dfs_correct(int r, int c) {\n    visited[r][c] = true;\n\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n    char move_c[] = {'R', 'D', 'L', 'U'};\n    char back_c[] = {'L', 'U', 'R', 'D'};\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {\n            bool wall = false;\n            if (i == 0) wall = (v_walls[r][c] == '1');\n            else if (i == 1) wall = (h_walls[r][c] == '1');\n            else if (i == 2) wall = (v_walls[nr][nc] == '1');\n            else if (i == 3) wall = (h_walls[nr][nc] == '1');\n\n            if (!wall) {\n                move_chars.push_back(move_c[i]);\n                path.push_back({nr, nc});\n                dfs_correct(nr, nc);\n                move_chars.push_back(back_c[i]);\n                path.push_back({r, c});\n            }\n        }\n    }\n}\n\nint main() {\n    // Standard optimizations for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[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    }\n\n    // Reset visited array\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited[i][j] = false;\n        }\n    }\n\n    // Generate initial DFS route\n    path.push_back({0, 0});\n    dfs_correct(0, 0);\n\n    int L_dfs = move_chars.size();\n    vector<int> m(N * N, 0);\n    for (const auto& sq : path) {\n        m[sq.r * N + sq.c]++;\n    }\n\n    // Calculate target visit frequency constant C\n    double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((double)d[i][j]);\n        }\n    }\n    // L_max is 10^5. Total visits = L + 1\n    double C = 100001.0 / sum_sqrt_d;\n\n    // Function to calculate the benefit of adding a detour to the k-th edge\n    auto get_benefit = [&](int k) -> double {\n        int r1 = path[k].r, c1 = path[k].c;\n        int r2 = path[k+1].r, c2 = path[k+1].c;\n        double b1 = max(0.0, C * sqrt((double)d[r1][c1]) - m[r1 * N + c1]);\n        double b2 = max(0.0, C * sqrt((double)d[r2][c2]) - m[r2 * N + c2]);\n        return b1 + b2;\n    };\n\n    // Greedy selection of edges for detours\n    priority_queue<pair<double, int>> pq;\n    for (int k = 0; k < L_dfs; ++k) {\n        pq.push({get_benefit(k), k});\n    }\n\n    vector<int> count(L_dfs, 0);\n    int L_current = L_dfs;\n\n    while (L_current + 2 <= 100000 && !pq.empty()) {\n        pair<double, int> top = pq.top();\n        pq.pop();\n\n        int k = top.second;\n        double b = top.first;\n\n        // If benefit is near zero or the benefit value is stale, skip\n        if (b < 1e-7) break;\n        if (abs(b - get_benefit(k)) > 1e-7) continue;\n\n        // Apply detour\n        count[k]++;\n        L_current += 2;\n        m[path[k].r * N + path[k].c]++;\n        m[path[k+1].r * N + path[k+1].c]++;\n        \n        // Re-push updated edge to priority queue\n        pq.push({get_benefit(k), k});\n    }\n\n    // Build and output the final route string\n    string final_moves = \"\";\n    final_moves.reserve(L_current);\n    for (int k = 0; k < L_dfs; ++k) {\n        final_moves += move_chars[k];\n        if (count[k] > 0) {\n            char m_k = move_chars[k];\n            char rev_m_k;\n            if (m_k == 'R') rev_m_k = 'L';\n            else if (m_k == 'L') rev_m_k = 'R';\n            else if (m_k == 'U') rev_m_k = 'D';\n            else rev_m_k = 'U';\n\n            for (int i = 0; i < count[k]; ++i) {\n                final_moves += rev_m_k;\n                final_moves += m_k;\n            }\n        }\n    }\n\n    cout << final_moves << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Kakizome Taikai\n * Goal: Create a \"lucky string\" containing all M target strings (each of length 5)\n * as substrings, while minimizing the movement cost.\n * \n * Strategy:\n * 1. Pre-calculate the Manhattan distance + 1 between any two squares.\n * 2. Use a greedy strategy to build the lucky string:\n *    a. At each step, find the target string not yet covered that can be added\n *       with the minimum \"cost per new string covered\" ratio.\n *    b. To add a target string t_k, find the maximum overlap between its prefix\n *       and the current string's suffix.\n *    c. Use DP to find the minimum cost to add the remaining characters of t_k\n *       from the current finger position.\n *    d. Update the finger position, the current string, and the set of covered strings.\n * 3. Repeat until all strings are covered or the length limit (5000) is reached.\n */\n\nconst int MAX_N = 15;\nconst int MAX_M = 200;\n\nint N, M;\nint si, sj;\nstring A[MAX_N];\nstring t[MAX_M];\n\nstruct Pos {\n    int r, c;\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dist(Pos a, Pos b) {\n    return abs(a.r - b.r) + abs(a.c - b.c) + 1;\n}\n\nstruct Result {\n    int cost;\n    vector<Pos> path;\n    string added_chars;\n};\n\nResult get_min_cost_to_add(Pos last_pos, const string& target, int p) {\n    int len = target.length() - p;\n    if (len <= 0) return {0, {}, \"\"};\n\n    // dp[i][r][c] = min cost to add first i characters of target[p:], ending at (r, c)\n    // i from 1 to len\n    vector<vector<vector<int>>> dp(len + 1, vector<vector<int>>(N, vector<int>(N, 1e9)));\n    vector<vector<vector<Pos>>> parent(len + 1, vector<vector<Pos>>(N, vector<Pos>(N, {-1, -1})));\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (A[r][c] == target[p]) {\n                dp[1][r][c] = dist(last_pos, {r, c});\n                parent[1][r][c] = last_pos;\n            }\n        }\n    }\n\n    for (int i = 2; i <= len; ++i) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (A[r][c] == target[p + i - 1]) {\n                    for (int pr = 0; pr < N; ++pr) {\n                        for (int pc = 0; pc < N; ++pc) {\n                            if (dp[i - 1][pr][pc] != 1e9) {\n                                int d = dp[i - 1][pr][pc] + dist({pr, pc}, {r, c});\n                                if (d < dp[i][r][c]) {\n                                    dp[i][r][c] = d;\n                                    parent[i][r][c] = {pr, pc};\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    int min_cost = 1e9;\n    Pos best_end = {-1, -1};\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[len][r][c] < min_cost) {\n                min_cost = dp[len][r][c];\n                best_end = {r, c};\n            }\n        }\n    }\n\n    if (min_cost == 1e9) return {1000000, {}, \"\"};\n\n    vector<Pos> path;\n    string added = \"\";\n    Pos curr = best_end;\n    for (int i = len; i >= 1; --i) {\n        path.push_back(curr);\n        added += target[p + i - 1];\n        curr = parent[i][curr.r][curr.c];\n    }\n    reverse(path.begin(), path.end());\n    reverse(added.begin(), added.end());\n\n    return {min_cost, path, added};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    string S = \"\";\n    Pos current_pos = {si, sj};\n    vector<bool> covered(M, false);\n    int covered_count = 0;\n    vector<Pos> final_path;\n\n    while (covered_count < M && S.length() < 5000) {\n        int best_k = -1;\n        Result best_res = {1000000, {}, \"\"};\n        double best_ratio = 1e18;\n\n        // Identify current suffix for overlap checking (up to 4 characters)\n        string suffix = \"\";\n        if (S.length() >= 4) {\n            suffix = S.substr(S.length() - 4);\n        } else {\n            suffix = S;\n        }\n\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n\n            // Find max overlap p between suffix and t[k].prefix(p)\n            int p = 0;\n            for (int len = min((int)suffix.length(), 4); len >= 1; --len) {\n                if (suffix.substr(suffix.length() - len) == t[k].substr(0, len)) {\n                    p = len;\n                    break;\n                }\n            }\n\n            // The target string could already be a substring if p=5 (not possible here)\n            // or if we already covered it.\n            Result res = get_min_cost_to_add(current_pos, t[k], p);\n            if (res.cost >= 1000000) continue;\n\n            // Calculate how many new strings are covered by adding this t[k]\n            string next_S = S + res.added_chars;\n            int new_covered = 0;\n            for (int j = 0; j < M; ++j) {\n                if (!covered[j] && next_S.find(t[j]) != string::npos) {\n                    new_covered++;\n                }\n            }\n\n            double ratio = (double)res.cost / (new_covered + 1e-9);\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best_k = k;\n                best_res = res;\n            }\n        }\n\n        if (best_k == -1) break; // Should not happen given problem constraints\n\n        // Apply the best choice\n        S += best_res.added_chars;\n        for (auto p : best_res.path) {\n            final_path.push_back(p);\n        }\n        current_pos = best_res.path.back();\n\n        // Re-check all strings for coverage\n        for (int j = 0; j < M; ++j) {\n            if (!covered[j] && S.find(t[j]) != string::npos) {\n                covered[j] = true;\n                covered_count++;\n            }\n        }\n    }\n\n    // Output the sequence of operations\n    for (const auto& p : final_path) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct Polyomino {\n    int d;\n    vector<pair<int, int>> shape;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> fields;\nvector<vector<pair<int, int>>> field_positions;\nvector<vector<double>> field_probs;\ndouble Q1[20][20][20];\n\nbool is_valid(int r, int c, const Polyomino& poly) {\n    for (auto& p : poly.shape) {\n        int nr = r + p.first;\n        int nc = c + p.second;\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> fields[i].d;\n        for (int j = 0; j < fields[i].d; ++j) {\n            int r, c;\n            cin >> r >> c;\n            fields[i].shape.push_back({r, c});\n        }\n    }\n\n    field_positions.resize(M);\n    for (int i = 0; i < M; ++i) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_valid(r, c, fields[i])) {\n                    field_positions[i].push_back({r, c});\n                }\n            }\n        }\n    }\n\n    field_probs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        field_probs[i].assign(field_positions[i].size(), 1.0 / (double)field_positions[i].size());\n    }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            for (int m = 0; m < M; ++m)\n                Q1[i][j][m] = 0.0;\n\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n            for (auto& coord : fields[m].shape) {\n                int r = field_positions[m][p].first + coord.first;\n                int c = field_positions[m][p].second + coord.second;\n                if (r >= 0 && r < N && c >= 0 && c < N) {\n                    Q1[r][c][m] += field_probs[m][p];\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> v_known(N, vector<int>(N, -1));\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n\n    for (int step = 0; step < N * N; ++step) {\n        vector<vector<double>> p_ij(N, vector<double>(N, 0.0));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double prob_zero = 1.0;\n                for (int m = 0; m < M; ++m) {\n                    prob_zero *= (1.0 - Q1[i][j][m]);\n                }\n                p_ij[i][j] = 1.0 - prob_zero;\n            }\n        }\n\n        bool all_certain = true;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j] && p_ij[i][j] > 1e-4 && p_ij[i][j] < (1.0 - 1e-4)) {\n                    all_certain = false;\n                    break;\n                }\n            }\n            if (!all_certain) break;\n        }\n\n        if (all_certain) {\n            vector<pair<int, int>> ans;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (v_known[i][j] > 0 || p_ij[i][j] > 0.5) {\n                        ans.push_back({i, j});\n                    }\n                }\n            }\n            cout << \"a \" << ans.size();\n            for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n            cout << endl;\n            int resp; cin >> resp;\n            return 0;\n        }\n\n        int best_i = -1, best_j = -1;\n        double max_unc = -1.0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j]) {\n                    double unc = p_ij[i][j] * (1.0 - p_ij[i][j]);\n                    if (unc > max_unc) {\n                        max_unc = unc;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n\n        if (best_i == -1) break;\n\n        cout << \"q 1 \" << best_i << \" \" << best_j << endl;\n        int V;\n        if (!(cin >> V)) break;\n        v_known[best_i][best_j] = V;\n        drilled[best_i][best_j] = true;\n\n        for (int m = 0; m < M; ++m) {\n            vector<double> dp(M + 1, 0.0);\n            dp[0] = 1.0;\n            for (int mp = 0; mp < M; ++mp) {\n                if (mp == m) continue;\n                double q1 = Q1[best_i][best_j][mp];\n                double q0 = 1.0 - q1;\n                for (int s = M; s >= 0; --s) {\n                    dp[s] = dp[s] * q0 + (s > 0 ? dp[s - 1] * q1 : 0.0);\n                }\n            }\n\n            vector<double> old_probs = field_probs[m];\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                bool covered = false;\n                for (auto& coord : fields[m].shape) {\n                    if (field_positions[m][p].first + coord.first == best_i &&\n                        field_positions[m][p].second + coord.second == best_j) {\n                        covered = true;\n                        break;\n                    }\n                }\n                int target = V - (covered ? 1 : 0);\n                if (target >= 0 && target < M) field_probs[m][p] *= dp[target];\n                else field_probs[m][p] = 0.0;\n            }\n\n            double sum_p = 0;\n            for (double pr : field_probs[m]) sum_p += pr;\n            if (sum_p > 1e-18) {\n                for (double& pr : field_probs[m]) pr /= sum_p;\n            } else {\n                field_probs[m].assign(field_positions[m].size(), 1.0 / field_positions[m].size());\n            }\n\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                double diff = field_probs[m][p] - old_probs[p];\n                if (abs(diff) > 1e-18) {\n                    for (auto& coord : fields[m].shape) {\n                        int r = field_positions[m][p].first + coord.first;\n                        int c = field_positions[m][p].second + coord.second;\n                        if (r >= 0 && r < N && c >= 0 && c < N) {\n                            Q1[r][c][m] += diff;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If we reach here, guess everything we know\n    vector<pair<int, int>> ans;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (v_known[i][j] > 0) ans.push_back({i, j});\n        }\n    }\n    cout << \"a \" << ans.size();\n    for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int resp; cin >> resp;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * 1. The goal is to minimize the total cost, which consists of area shortfall cost and partition cost.\n *    Area shortfall cost: 100 * (desired_area - actual_area).\n *    Partition cost: Total length of partition segments that change between consecutive days.\n * 2. Area shortfall cost is very expensive (100x), so we should prioritize meeting area requirements.\n * 3. Partition cost is proportional to the number of changing horizontal/vertical segments. \n *    If we use horizontal strips (rectangles spanning the full width W), only horizontal partitions exist.\n *    A change in boundary at y-coordinate y costs W (for each of the W horizontal segments at that height).\n * 4. Let the y-coordinates of the boundaries on day d be 0 = y_{d,0} < y_{d,1} < ... < y_{d,N} = W.\n *    The k-th rectangle (k=0...N-1) has height (y_{d,k+1} - y_{d,k}) and area W * (y_{d,k+1} - y_{d,k}).\n *    We ensure the area requirement by setting y_{d,k+1} - y_{d,k} >= ceil(a_{d,k} / W).\n * 5. To minimize partition cost, we want the boundaries y_{d,k} on day d to be the same as day d-1\n *    as much as possible. This can be modeled as maximizing the number of shared boundary coordinates.\n * 6. We can use Dynamic Programming (DP) for each day to find the best set of boundaries.\n *    dp[k][y] = maximum number of boundaries in {y_{d,1}, ..., y_{d,k}} that are in S_{d-1}, \n *    where y_{d,k} = y.\n *    Complexity: O(D * N * W), which is roughly 50 * 50 * 1000 = 2.5 * 10^6 operations.\n */\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i][j];\n        }\n    }\n\n    // y_vals[d][k] is the y-coordinate of the boundary after the (k-1)-th rectangle.\n    // y_vals[d][0] = 0, y_vals[d][N] = W.\n    vector<vector<int>> y_vals(D, vector<int>(N + 1));\n\n    for (int d = 0; d < D; ++d) {\n        // H[k] is the minimum height (integer) required for the k-th rectangle to satisfy area a[d][k].\n        vector<int> H(N);\n        for (int k = 0; k < N; ++k) {\n            H[k] = (a[d][k] + W - 1) / W;\n            if (H[k] < 1) H[k] = 1;\n        }\n\n        // Pre-calculate cumulative minimum heights to define valid ranges for y_vals[d][k].\n        vector<int> PreH(N + 1, 0);\n        for (int k = 0; k < N; ++k) PreH[k + 1] = PreH[k] + H[k];\n\n        vector<int> SufH(N + 1, 0);\n        for (int k = N - 1; k >= 0; --k) SufH[k] = SufH[k + 1] + H[k];\n\n        if (d == 0) {\n            // First day partition installation cost is 0, so just satisfy requirements.\n            y_vals[d][0] = 0;\n            for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n            y_vals[d][N] = W;\n        } else {\n            // Identify which boundary y-coordinates were used on the previous day.\n            vector<bool> is_in_S_prev(W + 1, false);\n            for (int k = 1; k < N; ++k) {\n                is_in_S_prev[y_vals[d - 1][k]] = true;\n            }\n\n            // dp[k][y] = max common boundaries in {y_{d,1}, ..., y_{d,k}} with y_{d,k} = y.\n            // k ranges from 1 to N-1.\n            vector<vector<int>> dp(N, vector<int>(W + 1, -1000000));\n            vector<vector<int>> parent(N, vector<int>(W + 1, -1));\n\n            // Base case: k=0, y_{d,0}=0.\n            dp[0][0] = 0;\n\n            for (int k = 1; k < N; ++k) {\n                // Use prefix maximum optimization to speed up the DP transition to O(1) per state.\n                vector<int> pref_max(W + 1, -1000000);\n                vector<int> pref_max_idx(W + 1, -1);\n                int cur_max = -1000000;\n                int cur_idx = -1;\n                for (int i = 0; i <= W; ++i) {\n                    if (dp[k - 1][i] > cur_max) {\n                        cur_max = dp[k - 1][i];\n                        cur_idx = i;\n                    }\n                    pref_max[i] = cur_max;\n                    pref_max_idx[i] = cur_idx;\n                }\n\n                // Iterate over valid y-coordinates for the k-th boundary.\n                for (int y = PreH[k]; y <= W - SufH[k]; ++y) {\n                    int max_y_prev = y - H[k - 1];\n                    if (max_y_prev >= 0) {\n                        int val = pref_max[max_y_prev];\n                        if (val >= 0) {\n                            dp[k][y] = val + (is_in_S_prev[y] ? 1 : 0);\n                            parent[k][y] = pref_max_idx[max_y_prev];\n                        }\n                    }\n                }\n            }\n\n            // Backtrack to find the optimal boundaries.\n            int best_y = -1;\n            int max_val = -1000000;\n            for (int y = PreH[N - 1]; y <= W - SufH[N - 1]; ++y) {\n                if (dp[N - 1][y] > max_val) {\n                    max_val = dp[N - 1][y];\n                    best_y = y;\n                }\n            }\n\n            y_vals[d][N] = W;\n            y_vals[d][0] = 0;\n            if (best_y != -1) {\n                y_vals[d][N - 1] = best_y;\n                for (int k = N - 1; k >= 1; --k) {\n                    y_vals[d][k - 1] = parent[k][y_vals[d][k]];\n                }\n            } else {\n                // Safety fallback if the DP failed (should not occur).\n                for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n                y_vals[d][0] = 0;\n                y_vals[d][N] = W;\n            }\n        }\n    }\n\n    // Output the rectangles in the required format.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            // Rectangle for k-th reservation on day d.\n            // Top-left (y_vals[d][k], 0), Bottom-right (y_vals[d][k+1], W).\n            cout << y_vals[d][k] << \" \" << 0 << \" \" << y_vals[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size N=9, stamps M=20, max operations K=81.\n * - Score = sum over all squares of (value % 998244353).\n * - Objective: Maximize the sum of remainders.\n * - The modulo makes the objective non-linear and non-monotonic.\n * \n * Algorithm:\n * - Use Simulated Annealing (SA) to explore the space of operations.\n * - State: A collection of up to K stamp operations (each defined by stamp index and board position).\n * - Moves:\n *   1. Add an operation (if current number of operations < K).\n *   2. Remove an operation.\n *   3. Replace an operation with a different one.\n * - Efficient Score Update: Since each operation only affects a 3x3 area, delta score \n *   can be calculated in O(1) (up to 18 squares per move).\n * - Data types: Use long long for board values to prevent overflow before modulo.\n */\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\nlong long a[N][N];\nlong long s[M][3][3];\nlong long b[N][N];\n\nstruct Slot {\n    bool empty = true;\n    int m, p, q;\n};\n\nSlot slots[K];\n\nint main() {\n    // Standard I/O optimization\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in, k_in;\n    if (!(cin >> n_in >> m_in >> k_in)) return 0;\n    \n    // Read initial board values\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n    \n    // Read stamp patterns\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 >> s[m][i][j];\n\n    // Initialize current board state\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            b[i][j] = a[i][j];\n\n    // Calculate initial total score\n    long long current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            current_score += b[i][j] % P;\n\n    mt19937_64 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    long long best_score = current_score;\n    vector<Slot> best_slots(K);\n    for (int i = 0; i < K; ++i) best_slots[i] = slots[i];\n\n    // SA temperature schedule\n    double T_start = 1e10;\n    double T_end = 1e-1;\n\n    // Time-based SA loop (runs for ~1.85 seconds)\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.85) break;\n\n        double T = T_start * pow(T_end / T_start, elapsed / 1.85);\n\n        int slot_idx = rng() % K;\n\n        if (slots[slot_idx].empty) {\n            // Move: Try to Add\n            int m_new = rng() % M;\n            int p_new = rng() % (N - 2);\n            int q_new = rng() % (N - 2);\n\n            long long delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int r = p_new + di, c = q_new + dj;\n                    if (r < N && c < N) {\n                        delta += (b[r][c] + s[m_new][di][dj]) % P - (b[r][c] % P);\n                    }\n                }\n            }\n\n            // Accept/Reject based on SA condition\n            if (delta > 0 || exp((double)delta / T) > (double)rng() / rng.max()) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (r < N && c < N) b[r][c] += s[m_new][di][dj];\n                    }\n                }\n                slots[slot_idx] = {false, m_new, p_new, q_new};\n                current_score += delta;\n            }\n        } else {\n            // Move: Try to Remove or Replace\n            int mode = rng() % 2;\n            if (mode == 0) {\n                // Move: Remove\n                int m = slots[slot_idx].m;\n                int p = slots[slot_idx].p;\n                int q = slots[slot_idx].q;\n\n                long long delta = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        if (r < N && c < N) {\n                            delta += (b[r][c] - s[m][di][dj]) % P - (b[r][c] % P);\n                        }\n                    }\n                }\n\n                if (delta > 0 || exp((double)delta / T) > (double)rng() / rng.max()) {\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int r = p + di, c = q + dj;\n                            if (r < N && c < N) b[r][c] -= s[m][di][dj];\n                        }\n                    }\n                    slots[slot_idx].empty = true;\n                    current_score += delta;\n                }\n            } else {\n                // Move: Replace\n                int m = slots[slot_idx].m;\n                int p = slots[slot_idx].p;\n                int q = slots[slot_idx].q;\n\n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n\n                // Use a fast way to collect unique affected coordinates\n                int aff_r[18], aff_c[18], count = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        if (r < N && c < N) {\n                            aff_r[count] = r; aff_c[count] = c; count++;\n                        }\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (r < N && c < N) {\n                            bool found = false;\n                            for (int k = 0; k < count; ++k) {\n                                if (aff_r[k] == r && aff_c[k] == c) { found = true; break; }\n                            }\n                            if (!found) { aff_r[count] = r; aff_c[count] = c; count++; }\n                        }\n                    }\n                }\n\n                long long delta = 0;\n                for (int k = 0; k < count; ++k) {\n                    int r = aff_r[k], c = aff_c[k];\n                    long long old_mod = b[r][c] % P;\n                    long long new_val = b[r][c];\n                    if (r >= p && r < p + 3 && c >= q && c < q + 3)\n                        new_val -= s[m][r - p][c - q];\n                    if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                        new_val += s[m_new][r - p_new][c - q_new];\n                    delta += (new_val % P) - old_mod;\n                }\n\n                if (delta > 0 || exp((double)delta / T) > (double)rng() / rng.max()) {\n                    for (int k = 0; k < count; ++k) {\n                        int r = aff_r[k], c = aff_c[k];\n                        long long new_val = b[r][c];\n                        if (r >= p && r < p + 3 && c >= q && c < q + 3)\n                            new_val -= s[m][r - p][c - q];\n                        if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                            new_val += s[m_new][r - p_new][c - q_new];\n                        b[r][c] = new_val;\n                    }\n                    slots[slot_idx] = {false, m_new, p_new, q_new};\n                    current_score += delta;\n                }\n            }\n        }\n\n        // Track best solution found\n        if (current_score > best_score) {\n            best_score = current_score;\n            for (int i = 0; i < K; ++i) best_slots[i] = slots[i];\n        }\n    }\n\n    // Output the result\n    vector<pair<int, pair<int, int>>> final_ops;\n    for (int i = 0; i < K; ++i) {\n        if (!best_slots[i].empty) {\n            final_ops.push_back({best_slots[i].m, {best_slots[i].p, best_slots[i].q}});\n        }\n    }\n\n    cout << final_ops.size() << endl;\n    for (auto& op : final_ops) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/*\nProblem Analysis:\n- The goal is to dispatch N^2 = 25 containers from specific Dispatch Gates.\n- Containers must be dispatched in a specific order: 0, 1, ..., 24.\n- The scoring favors minimizing the total turns (M0), the number of inversions (M1),\n  wrong dispatch gates (M2), and undispatched containers (M3).\n- To minimize M1, M2, and M3, the most important thing is to dispatch containers\n  in the correct order 0, 1, ..., 24 at their respective correct gates (c/N, N-1).\n- We use a single large crane (crane 0) to pick up each container one by one in \n  increasing order.\n- All other cranes are immediately bombed to ensure they don't block the path.\n- The large crane is capable of moving through squares with other containers.\n- BFS is used to find the shortest path for the large crane between target locations.\n*/\n\nint N;\nint A[5][5];\nint grid[5][5];\nint arrival_idx[5];\nint crane_x[5], crane_y[5];\nint crane_holding[5];\nbool container_on_grid[25];\nint container_pos_x[25], container_pos_y[25];\nbool container_dispatched[25];\nint target_c = 0;\n\n// Returns the direction char to move from (sx, sy) to (nx, ny)\nchar get_move_char(int sx, int sy, int nx, int ny) {\n    if (nx < sx) return 'U';\n    if (nx > sx) return 'D';\n    if (ny < sy) return 'L';\n    if (ny > sy) return 'R';\n    return '.';\n}\n\n// BFS to find the next step towards (tx, ty) on a 5x5 grid\npair<int, int> get_next_step(int sx, int sy, int tx, int ty) {\n    if (sx == tx && sy == ty) return {sx, sy};\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    queue<pair<int, int>> q;\n    q.push({sx, sy});\n    int dist[5][5];\n    pair<int, int> parent[5][5];\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    dist[sx][sy] = 0;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        if (curr.first == tx && curr.second == ty) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.first + dx[i];\n            int ny = curr.second + dy[i];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n\n    if (dist[tx][ty] == -1) return {sx, sy};\n\n    // Backtrack to find the first step along the path from (sx, sy)\n    int cx = tx, cy = ty;\n    while (parent[cx][cy].first != sx || parent[cx][cy].second != sy) {\n        pair<int, int> p = parent[cx][cy];\n        cx = p.first;\n        cy = p.second;\n    }\n    return {cx, cy};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            grid[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        arrival_idx[i] = 0;\n        crane_x[i] = i;\n        crane_y[i] = 0;\n        crane_holding[i] = -1;\n    }\n    crane_x[0] = 0;\n    crane_y[0] = 0;\n    for (int i = 0; i < 25; ++i) {\n        container_on_grid[i] = false;\n        container_dispatched[i] = false;\n    }\n\n    // Pre-allocate strings for outputs\n    vector<string> actions(N, string(10000, '.'));\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // 1. Arrivals (Step 1)\n        for (int i = 0; i < N; ++i) {\n            bool crane_holding_at_gate = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_holding[k] != -1 && crane_x[k] == i && crane_y[k] == 0) {\n                    crane_holding_at_gate = true;\n                    break;\n                }\n            }\n            if (arrival_idx[i] < N && grid[i][0] == -1 && !crane_holding_at_gate) {\n                int c = A[i][arrival_idx[i]];\n                grid[i][0] = c;\n                container_on_grid[c] = true;\n                container_pos_x[c] = i;\n                container_pos_y[c] = 0;\n                arrival_idx[i]++;\n            }\n        }\n\n        // 2. Crane Actions (Step 2)\n        // First turn: Bomb all small cranes to clear paths\n        if (turn == 1) {\n            for (int i = 1; i < N; ++i) {\n                actions[i][0] = 'B';\n                // Small cranes are effectively removed from the simulation now\n            }\n        }\n\n        // Decision for the large crane (crane 0)\n        if (crane_holding[0] == -1) {\n            if (target_c < 25) {\n                // Check if target container is on the grid\n                if (container_on_grid[target_c]) {\n                    int rx = container_pos_x[target_c];\n                    int ry = container_pos_y[target_c];\n                    if (crane_x[0] == rx && crane_y[0] == ry) {\n                        // If at the container, pick it up\n                        actions[0][turn - 1] = 'P';\n                        crane_holding[0] = target_c;\n                        grid[rx][ry] = -1;\n                        container_on_grid[target_c] = false;\n                    } else {\n                        // Otherwise, move towards it\n                        pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                        actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                        crane_x[0] = next_pos.first;\n                        crane_y[0] = next_pos.second;\n                    }\n                } else {\n                    // Target container hasn't arrived yet\n                    actions[0][turn - 1] = '.';\n                }\n            } else {\n                actions[0][turn - 1] = '.';\n            }\n        } else {\n            // Large crane is holding a container\n            int c = crane_holding[0];\n            int rx = c / N, ry = N - 1;\n            if (crane_x[0] == rx && crane_y[0] == ry) {\n                // If at target dispatch gate, release it\n                actions[0][turn - 1] = 'Q';\n                grid[rx][ry] = c;\n                crane_holding[0] = -1;\n                target_c++;\n            } else {\n                // Move towards the dispatch gate\n                pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                crane_x[0] = next_pos.first;\n                crane_y[0] = next_pos.second;\n            }\n        }\n\n        // 3. Dispatches (Step 3)\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][N - 1] != -1) {\n                int c = grid[i][N - 1];\n                grid[i][N - 1] = -1;\n                container_on_grid[c] = false;\n                container_dispatched[c] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - The goal is to level the ground by making all h_{i,j} = 0.\n * - We use a dump truck that can load (increases load, decreases h_{i,j}) or unload (decreases load, increases h_{i,j}).\n * - Cost of loading/unloading d units is d.\n * - Cost of moving to an adjacent square is 100 + current_load.\n * - The sum of all h_{i,j} is 0.\n * - We need to minimize the total cost: Sum of |h_{i,j}| + Sum of (100 + load) for each move.\n * \n * Strategy:\n * - This is a variation of the Pickup and Delivery Problem (PDP).\n * - We identify sources (h_{i,j} > 0) and sinks (h_{i,j} < 0).\n * - We use a greedy approach to decide the next destination.\n * - At each step, we choose the next destination v (source or sink) that minimizes:\n *   score(v) = cost_of_moving_to_v + expected_future_cost_after_v.\n * - cost_of_moving_to_v = Manhattan_dist(current_pos, v) * (100 + current_load).\n * - expected_future_cost_after_v = avg_distance_between_squares * (100 + new_load).\n * - The avg_distance is approximately 13 for a 20x20 grid.\n * - This strategy balances minimizing the travel distance and minimizing the amount of soil carried.\n */\n\nstruct Square {\n    int r, c, h;\n    int id;\n};\n\nint get_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Square> sources, sinks;\n    int id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int h;\n            cin >> h;\n            if (h > 0) {\n                sources.push_back({i, j, h, id_counter++});\n            } else if (h < 0) {\n                sinks.push_back({i, j, -h, id_counter++});\n            }\n        }\n    }\n\n    int cur_r = 0, cur_c = 0, cur_load = 0;\n    vector<string> operations;\n    const double avg_dist = 13.0;\n\n    while (!sources.empty() || !sinks.empty()) {\n        int best_idx = -1;\n        bool is_source = true;\n        double min_score = 1e18;\n\n        // If current load is 0, we must pick a source.\n        if (cur_load == 0) {\n            for (int i = 0; i < (int)sources.size(); ++i) {\n                double dist_pv = get_dist(cur_r, cur_c, sources[i].r, sources[i].c);\n                double score = dist_pv * (100 + cur_load) + avg_dist * (100 + cur_load + sources[i].h);\n                if (score < min_score) {\n                    min_score = score;\n                    best_idx = i;\n                    is_source = true;\n                }\n            }\n        } else {\n            // Try all unvisited sources\n            for (int i = 0; i < (int)sources.size(); ++i) {\n                double dist_pv = get_dist(cur_r, cur_c, sources[i].r, sources[i].c);\n                double score = dist_pv * (100 + cur_load) + avg_dist * (100 + cur_load + sources[i].h);\n                if (score < min_score) {\n                    min_score = score;\n                    best_idx = i;\n                    is_source = true;\n                }\n            }\n            // Try all unvisited sinks that we can afford to unload at\n            for (int i = 0; i < (int)sinks.size(); ++i) {\n                if (sinks[i].h <= cur_load) {\n                    double dist_pv = get_dist(cur_r, cur_c, sinks[i].r, sinks[i].c);\n                    double score = dist_pv * (100 + cur_load) + avg_dist * (100 + cur_load - sinks[i].h);\n                    if (score < min_score) {\n                        min_score = score;\n                        best_idx = i;\n                        is_source = false;\n                    }\n                }\n            }\n        }\n\n        if (best_idx == -1) break; // Should not happen given the sum(h) = 0\n\n        Square target;\n        if (is_source) {\n            target = sources[best_idx];\n        } else {\n            target = sinks[best_idx];\n        }\n\n        // Move the truck to the target square\n        while (cur_r < target.r) { operations.push_back(\"D\"); cur_r++; }\n        while (cur_r > target.r) { operations.push_back(\"U\"); cur_r--; }\n        while (cur_c < target.c) { operations.push_back(\"R\"); cur_c++; }\n        while (cur_c > target.c) { operations.push_back(\"L\"); cur_c--; }\n\n        // Perform the load/unload operation\n        if (is_source) {\n            operations.push_back(\"+\" + to_string(target.h));\n            cur_load += target.h;\n            sources.erase(sources.begin() + best_idx);\n        } else {\n            operations.push_back(\"-\" + to_string(target.h));\n            cur_load -= target.h;\n            sinks.erase(sinks.begin() + best_idx);\n        }\n    }\n\n    // Output the sequence of operations\n    cout << operations.size() << \"\\n\";\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to maximize the maximum sum of evaluation criteria for a single seed after T operations.\n * In each operation, we place 36 seeds on a 6x6 grid. Adjacent pairs (60 pairs in total) generate \n * new seeds where each criterion is inherited from one of the two parents.\n * \n * Heuristic Approach:\n * To maximize the sum, we want to have a single pair of seeds where, for many criteria, one seed\n * has a very high value. The potential of a pair (k, k') can be estimated by the maximum possible\n * sum it could produce: V_max(k, k') = sum_{l=0}^{M-1} max(x_{k,l}, x_{k',l}).\n * We use Simulated Annealing (SA) to find a placement of seeds on the grid that maximizes \n * a function related to these potential values.\n * \n * The objective function for SA is: max_{p in Pairs} V_max(p) + 0.01 * sum_{p in Pairs} V_max(p).\n * This encourages both a single very good pair and many moderately good pairs.\n */\n\n// Fixed problem parameters based on constraints\nconst int MAX_N = 6;\nconst int MAX_M = 15;\nconst int MAX_SEEDS = 60;\nconst int MAX_PAIRS = 60;\n\nint N, M, T;\nint seed_count;\nint grid_size;\n\nstruct Seed {\n    int x[MAX_M];\n    int v;\n};\n\nSeed seeds[MAX_SEEDS];\nint grid[MAX_N][MAX_N];\nint pos[MAX_SEEDS]; // Position of seed k in the grid (0-35) or -1\n\nstruct Pair {\n    int r1, c1, r2, c2;\n};\nPair adj_pairs[MAX_PAIRS];\nint cell_to_pairs[MAX_N][MAX_N][8];\nint cell_to_pairs_size[MAX_N][MAX_N];\ndouble pair_scores[MAX_PAIRS];\n\n// Calculate the maximum possible value of a new seed from a pair of seeds\ndouble calculate_pair_vmax(int k1, int k2) {\n    double vmax = 0;\n    for (int l = 0; l < M; ++l) {\n        vmax += max(seeds[k1].x[l], seeds[k2].x[l]);\n    }\n    return vmax;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial input\n    if (!(cin >> N >> M >> T)) return 0;\n\n    seed_count = 2 * N * (N - 1);\n    grid_size = N * N;\n\n    for (int i = 0; i < seed_count; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> seeds[i].x[j];\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    // Precompute grid adjacency\n    int pair_idx = 0;\n    for (int i = 0; i < MAX_N; ++i) {\n        for (int j = 0; j < MAX_N; ++j) {\n            cell_to_pairs_size[i][j] = 0;\n        }\n    }\n\n    // Horizontal adjacent pairs\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            adj_pairs[pair_idx] = {i, j, i, j + 1};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i][j + 1][cell_to_pairs_size[i][j + 1]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    // Vertical adjacent pairs\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            adj_pairs[pair_idx] = {i, j, i + 1, j};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i + 1][j][cell_to_pairs_size[i + 1][j]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Reset grid for the current turn\n        for (int i = 0; i < seed_count; ++i) pos[i] = -1;\n        for (int i = 0; i < grid_size; ++i) {\n            grid[i / N][i % N] = i;\n            pos[i] = i;\n        }\n\n        // Initial score setup\n        for (int i = 0; i < pair_idx; ++i) {\n            pair_scores[i] = calculate_pair_vmax(grid[adj_pairs[i].r1][adj_pairs[i].c1], grid[adj_pairs[i].r2][adj_pairs[i].c2]);\n        }\n\n        auto get_current_score = [&]() {\n            double max_v = 0;\n            double sum_v = 0;\n            for (int i = 0; i < pair_idx; ++i) {\n                if (pair_scores[i] > max_v) max_v = pair_scores[i];\n                sum_v += pair_scores[i];\n            }\n            return max_v + 0.01 * sum_v;\n        };\n\n        double current_score = get_current_score();\n        auto start_time = chrono::steady_clock::now();\n\n        int iter = 0;\n        // Simulated Annealing core loop\n        while (true) {\n            // Periodically check for the time limit (each turn gets ~0.15 seconds)\n            if ((iter & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start_time).count() > 0.16) break;\n            }\n            iter++;\n\n            int r = uniform_int_distribution<int>(0, N - 1)(rng);\n            int c = uniform_int_distribution<int>(0, N - 1)(rng);\n            int s = uniform_int_distribution<int>(0, seed_count - 1)(rng);\n\n            int r2 = -1, c2 = -1;\n            if (pos[s] != -1) {\n                r2 = pos[s] / N;\n                c2 = pos[s] % N;\n            }\n\n            if (r == r2 && c == c2) continue;\n\n            int old_seed_rc = grid[r][c];\n            int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n\n            int changed_pairs[10];\n            double old_pair_scores[10];\n            int cp_cnt = 0;\n\n            // Lambda to record affected pairs and their scores for undoing moves\n            auto record_affected_pairs = [&](int row, int col) {\n                for (int i = 0; i < cell_to_pairs_size[row][col]; ++i) {\n                    int p_idx = cell_to_pairs[row][col][i];\n                    bool already_recorded = false;\n                    for (int k = 0; k < cp_cnt; ++k) {\n                        if (changed_pairs[k] == p_idx) {\n                            already_recorded = true;\n                            break;\n                        }\n                    }\n                    if (!already_recorded) {\n                        changed_pairs[cp_cnt] = p_idx;\n                        old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                        cp_cnt++;\n                    }\n                }\n            };\n\n            record_affected_pairs(r, c);\n            if (r2 != -1) record_affected_pairs(r2, c2);\n\n            // Apply the potential move (either swap or replace)\n            if (r2 != -1) {\n                // Swap\n                grid[r][c] = s;\n                grid[r2][c2] = old_seed_rc;\n                pos[s] = r * N + c;\n                pos[old_seed_rc] = r2 * N + c2;\n            } else {\n                // Replace\n                grid[r][c] = s;\n                pos[old_seed_rc] = -1;\n                pos[s] = r * N + c;\n            }\n\n            // Recalculate pair scores for the updated grid\n            for (int i = 0; i < cp_cnt; ++i) {\n                int p_idx = changed_pairs[i];\n                pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n            }\n\n            double next_score = get_current_score();\n            \n            // Time-based temperature reduction\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double temp = 10.0 * (1.0 - elapsed / 0.16);\n            if (temp < 0.01) temp = 0.01;\n\n            // Metropolis criterion\n            if (next_score > current_score || exp((next_score - current_score) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_score = next_score;\n            } else {\n                // Revert the move\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc;\n                    grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2;\n                    pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc;\n                    pos[s] = -1;\n                    pos[old_seed_rc] = r * N + c;\n                }\n                for (int i = 0; i < cp_cnt; ++i) {\n                    pair_scores[changed_pairs[i]] = old_pair_scores[i];\n                }\n            }\n        }\n\n        // Output current placement\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // Read newly generated seeds from the judge\n        for (int i = 0; i < seed_count; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                cin >> seeds[i].x[j];\n                seeds[i].v += seeds[i].x[j];\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We need to move M takoyaki from initial positions S to target positions T.\n * We can design a robotic arm as a tree with up to V vertices.\n * A star-like tree with a single fingertip (leaf) and the root at the center is a good choice.\n * Let's use V'=2 (one root and one fingertip) with an edge length L=1.\n * The fingertip (vertex 1) can reach any cell (sx, sy) if the root (vertex 0) is placed\n * at an adjacent cell (sx+/-1, sy) or (sx, sy+/-1).\n * The movements involve moving the root (U, D, L, R) and rotating the fingertip (L, R).\n * \n * The score is based on the number of turns. Moving one takoyaki at a time\n * from its current position to its target position should be efficient.\n */\n\nstruct State {\n    int rx, ry, dir_idx;\n};\n\nint N, M, V;\nvector<string> s_grid, t_grid;\nint curr_rx, curr_ry, curr_dir_idx;\n\n// Directions for dir_idx: 0: Down (1,0), 1: Right (0,1), 2: Up (-1,0), 3: Left (0,-1)\nint dx[] = {1, 0, -1, 0};\nint dy[] = {0, 1, 0, -1};\n\nvoid move_to(int target_rx, int target_ry, int target_dir_idx, bool is_last) {\n    int dist = abs(curr_rx - target_rx) + abs(curr_ry - target_ry);\n    int rot_ccw = (target_dir_idx - curr_dir_idx + 4) % 4;\n    int rot_cw = (curr_dir_idx - target_dir_idx + 4) % 4;\n\n    int turns, rot_needed;\n    char rot_char;\n    if (max(dist, rot_ccw) <= max(dist, rot_cw)) {\n        turns = max(dist, rot_ccw);\n        rot_needed = rot_ccw;\n        rot_char = 'L';\n    } else {\n        turns = max(dist, rot_cw);\n        rot_needed = rot_cw;\n        rot_char = 'R';\n    }\n\n    // If already at the target position and direction, we still need one turn to pick/place.\n    if (turns == 0) turns = 1;\n\n    int temp_rx = curr_rx, temp_ry = curr_ry;\n    int temp_dir = curr_dir_idx;\n    int rotations_done = 0;\n\n    for (int i = 1; i <= turns; ++i) {\n        char move_char = '.';\n        if (temp_rx < target_rx) { move_char = 'D'; temp_rx++; }\n        else if (temp_rx > target_rx) { move_char = 'U'; temp_rx--; }\n        else if (temp_ry < target_ry) { move_char = 'R'; temp_ry++; }\n        else if (temp_ry > target_ry) { move_char = 'L'; temp_ry--; }\n\n        char cur_rot_char = '.';\n        if (rotations_done < rot_needed) {\n            cur_rot_char = rot_char;\n            if (rot_char == 'L') temp_dir = (temp_dir + 1) % 4;\n            else temp_dir = (temp_dir + 3) % 4;\n            rotations_done++;\n        }\n\n        char action_char = (is_last && i == turns) ? 'P' : '.';\n        // Turn format: S[0] (move), S[1] (rotation of vertex 1), S[2] (action of root), S[3] (action of leaf)\n        cout << move_char << cur_rot_char << '.' << action_char << \"\\n\";\n    }\n    curr_rx = target_rx;\n    curr_ry = target_ry;\n    curr_dir_idx = target_dir_idx;\n}\n\nState find_state(int sx, int sy, int n) {\n    for (int d = 0; d < 4; ++d) {\n        int rx = sx - dx[d];\n        int ry = sy - dy[d];\n        if (rx >= 0 && rx < n && ry >= 0 && ry < n) {\n            return {rx, ry, d};\n        }\n    }\n    return {0, 0, 0};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    s_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Design the tree: V'=2, vertex 0 is root, vertex 1 is leaf. Edge (0,1) length 1.\n    cout << 2 << \"\\n\";\n    cout << \"0 1\" << \"\\n\";\n    // Initial root position (0, 0)\n    cout << \"0 0\" << \"\\n\";\n\n    // Initial robotic arm state (root at 0,0 and all edges extend to the right: dir_idx = 1)\n    curr_rx = 0;\n    curr_ry = 0;\n    curr_dir_idx = 1;\n\n    // Identify takoyaki that need to be moved\n    vector<pair<int, int>> s_only, t_only;\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                s_only.push_back({i, j});\n            }\n            if (s_grid[i][j] == '0' && t_grid[i][j] == '1') {\n                t_only.push_back({i, j});\n            }\n        }\n    }\n\n    // Each takoyaki in s_only must be moved to a position in t_only\n    for (size_t i = 0; i < s_only.size(); ++i) {\n        // 1. Pick up from current s_only[i]\n        State pick_state = find_state(s_only[i].first, s_only[i].second, N);\n        move_to(pick_state.rx, pick_state.ry, pick_state.dir_idx, true);\n\n        // 2. Drop at target t_only[i]\n        State drop_state = find_state(t_only[i].first, t_only[i].second, N);\n        move_to(drop_state.rx, drop_state.ry, drop_state.dir_idx, true);\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We are given N mackerels (weight +1) and N sardines (weight -1).\n * We need to find an axis-parallel polygon that maximizes the sum of weights of fish inside it.\n * The polygon must have at most 1000 vertices, edge length at most 4*10^5, \n * and coordinates between 0 and 10^5. It must not self-intersect.\n * \n * The maximum weight rectangle problem can be solved in O(N^2) by iterating \n * through all pairs of y-coordinates and using Kadane's algorithm on x-coordinates.\n * With N = 5000, O(N^2) is approximately 2.5 * 10^7, which fits within the 2-second limit.\n * Specifically, if we collect unique x and y coordinates, the complexity becomes O(L^2 + LN),\n * where L is the number of unique y-coordinates and N is the total number of fish.\n */\n\nstruct Fish {\n    int x, y, weight;\n};\n\nint main() {\n    // Speed up I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Fish> all_fish;\n    vector<int> all_x, all_y;\n\n    // Read mackerels\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    // Read sardines\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Pre-process unique coordinates for compression\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n\n    int K = all_x.size();\n    int L = all_y.size();\n\n    // Group fish by their unique y-coordinate index\n    vector<vector<pair<int, int>>> fish_at_y(L);\n    for (const auto& f : all_fish) {\n        int xi = lower_bound(all_x.begin(), all_x.end(), f.x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), f.y) - all_y.begin();\n        fish_at_y[yi].push_back({xi, f.weight});\n    }\n\n    // Initialize with a single mackerel to ensure a minimum score of 2 (a-b+1 = 1-0+1 = 2)\n    // (assuming mackerels are the first N fish)\n    int best_sum = 0;\n    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n\n    // A single mackerel at index i (0 <= i < N) provides sum 1\n    for (int i = 0; i < N; ++i) {\n        // Since all_fish[0...N-1] are mackerels\n        int xi = lower_bound(all_x.begin(), all_x.end(), all_fish[i].x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), all_fish[i].y) - all_y.begin();\n        if (1 > best_sum) {\n            best_sum = 1;\n            bx1 = xi; bx2 = xi;\n            by1 = yi; by2 = yi;\n        }\n    }\n\n    // O(L^2 + LN) algorithm to find the maximum weight rectangle\n    vector<int> f(K, 0);\n    for (int i = 0; i < L; ++i) {\n        // Reset x-coordinate weights for the new starting y-coordinate\n        fill(f.begin(), f.end(), 0);\n        for (int j = i; j < L; ++j) {\n            // Add fish at current y-coordinate j to the weights\n            for (auto& p : fish_at_y[j]) {\n                f[p.first] += p.second;\n            }\n            \n            // Find maximum subarray sum of weights in f using Kadane's\n            int cur_sum = 0;\n            int start = 0;\n            for (int k = 0; k < K; ++k) {\n                cur_sum += f[k];\n                if (cur_sum > best_sum) {\n                    best_sum = cur_sum;\n                    bx1 = start; bx2 = k;\n                    by1 = i; by2 = j;\n                }\n                if (cur_sum < 0) {\n                    cur_sum = 0;\n                    start = k + 1;\n                }\n            }\n        }\n    }\n\n    // Convert the discrete indices back to actual coordinates\n    int x1 = all_x[bx1], x2 = all_x[bx2];\n    int y1 = all_y[by1], y2 = all_y[by2];\n\n    // Ensure we form a valid non-zero area polygon\n    if (x1 == x2) {\n        if (x1 < 100000) x2 = x1 + 1;\n        else { x1 = x1 - 1; x2 = x1 + 1; }\n    }\n    if (y1 == y2) {\n        if (y1 < 100000) y2 = y1 + 1;\n        else { y1 = y1 - 1; y2 = y1 + 1; }\n    }\n\n    // Output the 4 vertices of the rectangle\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << endl;\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Rectangular packing in a single cardboard box.\n * Goal: Minimize W + H + Sum(unused rectangles' dimensions).\n * Method: Randomized Greedy approach with time-limited iterations.\n * \n * Rules:\n * - Rectangles must be placed in increasing order of indices.\n * - Each can be rotated 90 degrees.\n * - Directions: U (upward, move towards y=0) or L (leftward, move towards x=0).\n * - U with reference b: x_left_new = x_right_b (or 0).\n * - L with reference b: y_top_new = y_bottom_b (or 0).\n * - Movement stops when it hits an edge of a previously placed rectangle or axis.\n */\n\nstruct Rect {\n    int id;\n    long long w, h;\n    long long x, y;\n    long long x_right, y_bottom;\n};\n\nstruct Placement {\n    int p, r, d, b; \n};\n\nstruct State {\n    vector<Rect> placed;\n    vector<Placement> placements;\n    long long W, H;\n    long long score;\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<pair<long long, long long>> measured_wh(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> measured_wh[i].first >> measured_wh[i].second;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Time management to avoid TLE in system tests\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 2.7) break;\n\n        State best_state;\n        best_state.score = 4e18; \n\n        // Perform randomized greedy iterations in batches\n        for (int batch = 0; batch < 100; ++batch) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) break;\n\n            for (int iter = 0; iter < 5; ++iter) {\n                State current_state;\n                current_state.W = 0;\n                current_state.H = 0;\n                long long unused_sum = 0;\n                for (int i = 0; i < N; ++i) unused_sum += (measured_wh[i].first + measured_wh[i].second);\n\n                for (int i = 0; i < N; ++i) {\n                    long long wi = measured_wh[i].first;\n                    long long hi = measured_wh[i].second;\n\n                    struct Option {\n                        int r, d, b;\n                        long long new_W, new_H;\n                    };\n                    static Option options[405];\n                    int opt_count = 0;\n                    long long best_new_W_H = 4e18;\n\n                    for (int r : {0, 1}) {\n                        long long w = (r == 0 ? wi : hi);\n                        long long h = (r == 0 ? hi : wi);\n                        \n                        for (int d : {0, 1}) { // 0 for U, 1 for L\n                            // Try Case 1: Reference rectangle b = -1\n                            long long x_l, x_r, y_t, y_b;\n                            if (d == 0) { // U\n                                x_l = 0; x_r = w; y_t = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                }\n                                y_b = y_t + h;\n                            } else { // L\n                                y_t = 0; y_b = h; x_l = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                }\n                                x_r = x_l + w;\n                            }\n                            long long nw = max(current_state.W, x_r);\n                            long long nh = max(current_state.H, y_b);\n                            if (nw + nh < best_new_W_H) {\n                                best_new_W_H = nw + nh;\n                                opt_count = 0;\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            } else if (nw + nh == best_new_W_H) {\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            }\n\n                            // Try Case 2: Reference rectangle b is a previously placed rectangle\n                            for (const auto& prev : current_state.placed) {\n                                int b_id = prev.id;\n                                if (d == 0) { // U\n                                    x_l = prev.x_right; x_r = x_l + w; y_t = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                    }\n                                    y_b = y_t + h;\n                                } else { // L\n                                    y_t = prev.y_bottom; y_b = y_t + h; x_l = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                    }\n                                    x_r = x_l + w;\n                                }\n                                nw = max(current_state.W, x_r);\n                                nh = max(current_state.H, y_b);\n                                if (nw + nh < best_new_W_H) {\n                                    best_new_W_H = nw + nh;\n                                    opt_count = 0;\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                } else if (nw + nh == best_new_W_H) {\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                }\n                            }\n                        }\n                    }\n\n                    // Greedy decision: Include rectangle i if the score improvement is worth it.\n                    long long delta = best_new_W_H - (current_state.W + current_state.H);\n                    if (delta < wi + hi && opt_count > 0) {\n                        uniform_int_distribution<int> dist(0, opt_count - 1);\n                        Option opt = options[dist(rng)];\n                        long long w = (opt.r == 0 ? wi : hi);\n                        long long h = (opt.r == 0 ? hi : wi);\n                        Rect nr; nr.id = i; nr.w = w; nr.h = h;\n                        if (opt.d == 0) { // Direction U\n                            if (opt.b == -1) nr.x = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.x = p.x_right; break; }\n                            }\n                            nr.x_right = nr.x + w;\n                            long long yt = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.x_right <= p.x || nr.x >= p.x_right)) yt = max(yt, p.y_bottom);\n                            nr.y = yt; nr.y_bottom = yt + h;\n                        } else { // Direction L\n                            if (opt.b == -1) nr.y = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.y = p.y_bottom; break; }\n                            }\n                            nr.y_bottom = nr.y + h;\n                            long long xl = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.y_bottom <= p.y || nr.y >= p.y_bottom)) xl = max(xl, p.x_right);\n                            nr.x = xl; nr.x_right = xl + w;\n                        }\n                        current_state.placed.push_back(nr);\n                        current_state.placements.push_back({i, opt.r, opt.d, opt.b});\n                        current_state.W = max(current_state.W, nr.x_right);\n                        current_state.H = max(current_state.H, nr.y_bottom);\n                        unused_sum -= (wi + hi);\n                    }\n                }\n                current_state.score = current_state.W + current_state.H + unused_sum;\n                if (current_state.score < best_state.score) best_state = current_state;\n            }\n        }\n\n        // Output the best arrangement found for the current turn.\n        cout << best_state.placed.size() << \"\\n\";\n        for (const auto& pl : best_state.placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << (pl.d == 0 ? \"U\" : \"L\") << \" \" << pl.b << \"\\n\";\n        }\n        cout.flush();\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n    }\n\n    return 0;\n}\n","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We have a planar graph. We need to partition the vertices into several rooted trees.\n * The height of each vertex (distance to its root) must be <= H.\n * Maximize attractiveness = Sum over all vertices v: (h_v + 1) * A_v.\n * \n * Strategy:\n * 1. Initial solution: each vertex is its own root.\n * 2. Greedy: for each vertex v, try to make it a child of a neighbor u to maximize gain.\n * 3. Hill climbing: repeatedly pick a random edge (u, v) and try making v a child of u,\n *    if the move is valid and increases total attractiveness.\n * \n * Complexity:\n * Each move involves updating parents, calculating subtree sums, and checking height constraints.\n * With N=1000, O(N) per move is acceptable for thousands of moves within 2 seconds.\n */\n\nconst int MAXN = 1005;\nint N, M, H;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nint depth[MAXN];\n\n// Find all vertices in the subtree of v\nvoid get_subtree(int v, vector<int>& subtree) {\n    subtree.push_back(v);\n    for (int child : children[v]) {\n        get_subtree(child, subtree);\n    }\n}\n\n// Check if u is an ancestor of v\nbool is_ancestor(int u, int v) {\n    int curr = v;\n    while (curr != -1) {\n        if (curr == u) return true;\n        curr = parent[curr];\n    }\n    return false;\n}\n\n// Calculate the current sum of A_v and max depth in the subtree of v\nvoid get_subtree_info(int v, int current_d, long long& sumA, int& max_d) {\n    sumA += A[v];\n    max_d = max(max_d, current_d);\n    for (int child : children[v]) {\n        get_subtree_info(child, current_d + 1, sumA, max_d);\n    }\n}\n\n// Update depth of all nodes in a subtree after a parent change\nvoid update_depths(int v, int new_d) {\n    depth[v] = new_d;\n    for (int child : children[v]) {\n        update_depths(child, new_d + 1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> H)) return 0;\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // Skipping coordinate input as they are not needed for the optimization\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Initial state: every node is a root\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        depth[i] = 0;\n        children[i].clear();\n    }\n\n    // Greedy initial construction\n    vector<int> order(N);\n    for (int i = 0; i < N; ++i) order[i] = i;\n    // Sort nodes by beauty descending to build trees around more valuable nodes\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return A[a] > A[b];\n    });\n\n    for (int v : order) {\n        int best_u = -1;\n        long long best_gain = 0;\n        int best_delta = 0;\n\n        for (int u : adj[v]) {\n            // Try to make v a child of u\n            if (is_ancestor(v, u)) continue;\n\n            long long subA = 0;\n            int max_sub_d = 0;\n            get_subtree_info(v, depth[v], subA, max_sub_d);\n\n            int delta = (depth[u] + 1) - depth[v];\n            if (max_sub_d + delta <= H) {\n                long long gain = (long long)delta * subA;\n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_u = u;\n                    best_delta = delta;\n                }\n            }\n        }\n\n        if (best_u != -1) {\n            if (parent[v] != -1) {\n                auto& old_p_children = children[parent[v]];\n                old_p_children.erase(remove(old_p_children.begin(), old_p_children.end(), v), old_p_children.end());\n            }\n            parent[v] = best_u;\n            children[best_u].push_back(v);\n            update_depths(v, depth[best_u] + 1);\n        }\n    }\n\n    // Hill climbing refinement\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 rng(1337);\n    \n    // Edges list for random selection\n    struct Edge { int u, v; };\n    vector<Edge> edges;\n    for (int u = 0; u < N; ++u) {\n        for (int v : adj[u]) {\n            if (u < v) edges.push_back({u, v});\n        }\n    }\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n\n        int idx = uniform_int_distribution<int>(0, edges.size() - 1)(rng);\n        int u = edges[idx].u;\n        int v = edges[idx].v;\n\n        // Try both directions (u as parent of v, or v as parent of u)\n        for (int dir = 0; dir < 2; ++dir) {\n            int child = (dir == 0) ? v : u;\n            int p_new = (dir == 0) ? u : v;\n\n            if (parent[child] == p_new) continue;\n            if (is_ancestor(child, p_new)) continue;\n\n            long long subA = 0;\n            int max_sub_d = 0;\n            get_subtree_info(child, depth[child], subA, max_sub_d);\n\n            int delta = (depth[p_new] + 1) - depth[child];\n            if (max_sub_d + delta <= H) {\n                long long gain = (long long)delta * subA;\n                if (gain > 0) {\n                    // Apply the move\n                    if (parent[child] != -1) {\n                        auto& old_p_children = children[parent[child]];\n                        old_p_children.erase(remove(old_p_children.begin(), old_p_children.end(), child), old_p_children.end());\n                    }\n                    parent[child] = p_new;\n                    children[p_new].push_back(child);\n                    update_depths(child, depth[p_new] + 1);\n                    break; // Only one move per random edge iteration\n                }\n            }\n            swap(u, v); // Switch direction for next attempt\n        }\n    }\n\n    // Output the final parent array\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: Oni wa Soto, Fuku wa Uchi\n * The objective is to remove all Oni (demons 'x') from an NxN board \n * without removing any Fukunokami (fortune gods 'o').\n * \n * Strategy:\n * The problem provides a guarantee that for each Oni, there's at least one \n * direction (Up, Down, Left, Right) where no Fukunokami are present.\n * \n * We can remove an Oni at (i, j) by shifting the entire row or column in \n * that direction to push the Oni off the board. However, to avoid changing \n * the positions of other Oni and Fukunokami, we can follow the \"Hint\" provided:\n * \n * If shifting a column j upward removes the Oni at (i, j) and all pieces above it, \n * and we ensure all those pieces are either Oni or empty, then shifting \n * column j upward (i+1) times and then downward (i+1) times will remove \n * those pieces and return the remaining pieces (which were below the Oni) \n * to their original positions.\n * \n * Total moves for one Oni: at most 2*N.\n * Total Oni: 2*N.\n * Total moves T: at most 2*N * 2*N = 4*N^2.\n * This fits within the limit T <= 4*N^2.\n */\n\nstruct Move {\n    char d;\n    int p;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    vector<Move> moves;\n\n    // Helper to shift a row to the left and update board\n    auto shift_row_L = [&](int i) {\n        moves.push_back({'L', 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    };\n\n    // Helper to shift a row to the right and update board\n    auto shift_row_R = [&](int i) {\n        moves.push_back({'R', i});\n        for (int j = N - 1; j > 0; --j) {\n            board[i][j] = board[i][j - 1];\n        }\n        board[i][0] = '.';\n    };\n\n    // Helper to shift a column upward and update board\n    auto shift_col_U = [&](int j) {\n        moves.push_back({'U', 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    };\n\n    // Helper to shift a column downward and update board\n    auto shift_col_D = [&](int j) {\n        moves.push_back({'D', j});\n        for (int i = N - 1; i > 0; --i) {\n            board[i][j] = board[i - 1][j];\n        }\n        board[0][j] = '.';\n    };\n\n    // Iterate over all possible squares to find Oni\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                // Check Upward direction for safety (no Fukunokami 'o')\n                bool up_safe = true;\n                for (int k = 0; k < i; ++k) {\n                    if (board[k][j] == 'o') {\n                        up_safe = false;\n                        break;\n                    }\n                }\n                if (up_safe) {\n                    for (int k = 0; k < i + 1; ++k) shift_col_U(j);\n                    for (int k = 0; k < i + 1; ++k) shift_col_D(j);\n                    continue; // Oni is gone, move to next square\n                }\n\n                // Check Downward direction for safety\n                bool down_safe = true;\n                for (int k = i + 1; k < N; ++k) {\n                    if (board[k][j] == 'o') {\n                        down_safe = false;\n                        break;\n                    }\n                }\n                if (down_safe) {\n                    for (int k = 0; k < N - i; ++k) shift_col_D(j);\n                    for (int k = 0; k < N - i; ++k) shift_col_U(j);\n                    continue;\n                }\n\n                // Check Leftward direction for safety\n                bool left_safe = true;\n                for (int k = 0; k < j; ++k) {\n                    if (board[i][k] == 'o') {\n                        left_safe = false;\n                        break;\n                    }\n                }\n                if (left_safe) {\n                    for (int k = 0; k < j + 1; ++k) shift_row_L(i);\n                    for (int k = 0; k < j + 1; ++k) shift_row_R(i);\n                    continue;\n                }\n\n                // Check Rightward direction for safety\n                bool right_safe = true;\n                for (int k = j + 1; k < N; ++k) {\n                    if (board[i][k] == 'o') {\n                        right_safe = false;\n                        break;\n                    }\n                }\n                if (right_safe) {\n                    for (int k = 0; k < N - j; ++k) shift_row_R(i);\n                    for (int k = 0; k < N - j; ++k) shift_row_L(i);\n                    continue;\n                }\n            }\n        }\n    }\n\n    // Output all moves generated\n    for (const auto& m : moves) {\n        cout << m.d << \" \" << m.p << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem: A heuristic optimization problem to minimize error in cleaning duties assignment.\n * Strategy:\n *   The number of times each employee is the 'next' cleaner can be approximated by the \n *   in-degree in a graph where each employee j has two out-edges: a_j (for 1st, 3rd... visit) \n *   and b_j (for 2nd, 4th... visit).\n *   We aim to find a_j and b_j such that in-degree(i) is approximately T_i.\n *   To ensure all employees with T_i > 0 are actually assigned duties, the graph must be \n *   connected from the starting employee 0.\n *   We use Hill Climbing with local search to minimize a cost function: \n *   Cost = Sum|in_degree(i) - T_i| + Large_Penalty * Number_of_Unreachable_Employees.\n */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    vector<long long> u(N), v(N);\n    for (int i = 0; i < N; ++i) {\n        u[i] = (T[i] + 1) / 2;\n        v[i] = T[i] / 2;\n    }\n\n    vector<int> a(N), b(N);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = rng() % N;\n        b[i] = rng() % N;\n    }\n\n    vector<long long> in_deg(N, 0);\n    for (int i = 0; i < N; ++i) {\n        in_deg[a[i]] += u[i];\n        in_deg[b[i]] += v[i];\n    }\n\n    auto get_cost = [&](const vector<int>& cur_a, const vector<int>& cur_b, const vector<long long>& cur_in_deg) {\n        long long error = 0;\n        for (int i = 0; i < N; ++i) {\n            error += abs(cur_in_deg[i] - T[i]);\n        }\n\n        // Reachability check: BFS from node 0\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        int reachable_count = 1;\n        while (!q.empty()) {\n            int curr = q.front();\n            q.pop();\n            int nexts[2] = {cur_a[curr], cur_b[curr]};\n            for (int nxt : nexts) {\n                if (!reachable[nxt]) {\n                    reachable[nxt] = true;\n                    reachable_count++;\n                    q.push(nxt);\n                }\n            }\n        }\n\n        long long penalty = 0;\n        for (int i = 0; i < N; ++i) {\n            if (T[i] > 0 && !reachable[i]) {\n                penalty += T[i] * 1000000LL; // Large penalty for unreachable required nodes\n            }\n        }\n        return error + penalty;\n    };\n\n    long long current_cost = get_cost(a, b, in_deg);\n\n    auto start_time = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        if (iter % 100 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) {\n                break;\n            }\n        }\n        iter++;\n\n        int j = rng() % N;\n        int old_a = a[j], old_b = b[j];\n\n        // Instead of trying all N^2 pairs (which is too slow), we try changing one edge or both.\n        int type = rng() % 3;\n        int new_a = old_a, new_b = old_b;\n        if (type == 0) new_a = rng() % N;\n        else if (type == 1) new_b = rng() % N;\n        else { new_a = rng() % N; new_b = rng() % N; }\n\n        if (new_a == old_a && new_b == old_b) continue;\n\n        // Update in_deg for fast calculation\n        vector<long long> next_in_deg = in_deg;\n        next_in_deg[old_a] -= u[j];\n        next_in_deg[old_b] -= v[j];\n        next_in_deg[new_a] += u[j];\n        next_in_deg[new_b] += v[j];\n\n        // To avoid updating a and b vectors before verification\n        int old_a_saved = a[j], old_b_saved = b[j];\n        a[j] = new_a; b[j] = new_b;\n        long long next_cost = get_cost(a, b, next_in_deg);\n\n        if (next_cost < current_cost) {\n            current_cost = next_cost;\n            in_deg = next_in_deg;\n        } else {\n            a[j] = old_a_saved; b[j] = old_b_saved;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to divide N cities into M groups of fixed sizes G_0, ..., G_{M-1}.\n * - For each group, we need to find a spanning tree of roads.\n * - The total length of roads (Euclidean distance rounded down) should be minimized.\n * - We can use up to Q queries to find the MST of any subset of size [2, L].\n * - We have uncertainty about city coordinates (given as rectangular ranges).\n *\n * Proposed Strategy:\n * 1. Estimate the center of each city's rectangular coordinate range.\n * 2. Use Morton (Z-order) curve sorting on the estimated coordinates to group cities.\n *    This helps in keeping cities that are close in 2D space together in the sorted list.\n * 3. Divide the sorted cities into groups of the given sizes G_i.\n * 4. For each group with size > 1, use queries to find edges to form a connected graph.\n *    A group of size G_k is covered by queries of size L with an overlap of 1 city.\n *    This ensures the resulting set of edges forms a connected path-like structure.\n *    The total number of queries will be at most Sum_{i: G_i>1} ceil((G_i-1)/(L-1)).\n *    Given the constraints (N=800, M=400, L>=3, Q=400), this total is guaranteed to be <= 400.\n * 5. Output the groups and the edges.\n */\n\n// Morton (Z-order) curve encoding for 2D points.\nuint64_t interleave(uint32_t x, uint32_t y) {\n    uint64_t z = 0;\n    for (int i = 0; i < 32; ++i) {\n        z |= (static_cast<uint64_t>((x >> i) & 1) << (2 * i));\n        z |= (static_cast<uint64_t>((y >> i) & 1) << (2 * i + 1));\n    }\n    return z;\n}\n\nstruct City {\n    int id;\n    uint64_t morton;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        int cx = (lx[i] + rx[i]) / 2;\n        int cy = (ly[i] + ry[i]) / 2;\n        cities[i] = {i, interleave((uint32_t)cx, (uint32_t)cy)};\n    }\n\n    // Sort cities based on Morton order to preserve spatial locality.\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        return a.morton < b.morton;\n    });\n\n    // Partition sorted cities into groups of requested sizes.\n    vector<vector<int>> groups(M);\n    int current_city_idx = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[current_city_idx++].id);\n        }\n    }\n\n    vector<vector<pair<int, int>>> edges_in_group(M);\n\n    // Use queries to find edges within each group.\n    for (int i = 0; i < M; ++i) {\n        if (groups[i].size() > 1) {\n            int idx = 0;\n            int G_size = groups[i].size();\n            while (idx < G_size - 1) {\n                // Each query connects a subset of up to L cities.\n                // To ensure connectivity, each query (after the first) overlaps with the previous by 1 city.\n                int subset_size = min(L, G_size - idx);\n                \n                // Perform query.\n                cout << \"? \" << subset_size;\n                for (int k = 0; k < subset_size; ++k) {\n                    cout << \" \" << groups[i][idx + k];\n                }\n                cout << endl;\n\n                // Receive MST edges of the chosen subset.\n                for (int k = 0; k < subset_size - 1; ++k) {\n                    int u, v;\n                    cin >> u >> v;\n                    edges_in_group[i].push_back({u, v});\n                }\n                \n                // Move to the next city for the next query (overlap of one city).\n                idx += (subset_size - 1);\n            }\n        }\n    }\n\n    // Final Output\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // Print cities in the current group.\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            cout << groups[i][j] << (j == (int)groups[i].size() - 1 ? \"\" : \" \");\n        }\n        cout << endl;\n        // Print roads in the current group.\n        for (auto& edge : edges_in_group[i]) {\n            cout << edge.first << \" \" << edge.second << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size: 20x20 (N=20).\n * - Number of target squares: M-1 = 39.\n * - Total squares provided in input: M = 40 (start point + 39 targets).\n * - Allowed actions: Move (M), Slide (S), Alter (A).\n * - Limit of actions: 2 * N * M = 1600.\n * - The primary goal is to visit target squares in the given order with minimal turns.\n * - If all M-1 targets are visited, the score is M + 2NM - T, where T is the number of turns.\n * \n * Strategy:\n * - Using only the 'Move' (M) action is a reliable way to visit each target.\n * - The maximum Manhattan distance between any two squares in a 20x20 grid is (20-1) + (20-1) = 38.\n * - For 39 targets, the total maximum number of moves is 39 * 38 = 1482.\n * - Since 1482 <= 1600, the 'Move' only strategy is guaranteed to be within the action limit.\n * - This strategy also ensures all targets are visited correctly by stepping onto them one by one.\n * - While 'Slide' (S) might reduce T and improve the score, 'Move' provides a safe baseline \n *   that guarantees a valid and reasonably high score.\n */\n\nstruct Point {\n    int r, c;\n};\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M;\n    // Read N and M. N=20, M=40 are constants.\n    if (!(cin >> N >> M)) return 0;\n\n    // Read the initial position (i0, j0)\n    int r0, c0;\n    if (!(cin >> r0 >> c0)) return 0;\n\n    // Read the sequence of M target squares (i1, j1), ..., (iM-1, jM-1)\n    // Note: The input provides M points in total, starting from (i0, j0).\n    vector<Point> targets(M);\n    targets[0] = {r0, c0};\n    for (int i = 1; i < M; ++i) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n\n    // curr_r and curr_c track the current position of the skater.\n    int curr_r = r0;\n    int curr_c = c0;\n\n    // Traverse the targets in the specified order\n    for (int k = 1; k < M; ++k) {\n        int tr = targets[k].r;\n        int tc = targets[k].c;\n\n        // Move vertically to align the current row with the target row.\n        // If tr > curr_r, we move Down (D).\n        // If tr < curr_r, we move Up (U).\n        while (curr_r < tr) {\n            cout << \"M D\\n\";\n            curr_r++;\n        }\n        while (curr_r > tr) {\n            cout << \"M U\\n\";\n            curr_r--;\n        }\n\n        // Move horizontally to align the current column with the target column.\n        // If tc > curr_c, we move Right (R).\n        // If tc < curr_c, we move Left (L).\n        while (curr_c < tc) {\n            cout << \"M R\\n\";\n            curr_c++;\n        }\n        while (curr_c > tc) {\n            cout << \"M L\\n\";\n            curr_c--;\n        }\n    }\n\n    return 0;\n}\n"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to partition a 10000x10000 area into non-overlapping rectangles, each containing\n * one specific point (xi+0.5, yi+0.5), to maximize the sum of satisfaction levels.\n * Satisfaction is maximized when the rectangle's area s_i is close to the desired area r_i.\n * \n * Algorithm Strategy:\n * We use a recursive KD-tree-like partitioning (guillotine cuts). At each step, we choose a\n * vertical or horizontal split line that divides the current rectangle into two. \n * To keep the areas close to the sum of desired areas (r_i), we aim to maintain a constant \n * \"excess area\" ratio. Specifically, if the current rectangle has area A and the sum of\n * desired areas is R, the \"excess area\" is E = A - R. For any split, we try to distribute\n * E between the two new rectangles proportionally to the number of points in them.\n * \n * We use a randomized approach: at each recursive step, we collect all valid splits and\n * pick one of the top-scoring splits randomly. We run the entire process multiple times\n * with different random seeds and select the best overall result.\n */\n\nstruct Point {\n    int x, y, r, id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nint N;\nPoint points_orig[200];\nRect ans[200];\n\nstruct Split {\n    bool vertical;\n    int k;\n    double score;\n    int j; // number of points in the left partition\n};\n\n// Recursive function to partition a rectangle and its associated points\nvoid solve(Rect R, vector<Point> P, mt19937& gen) {\n    if (P.empty()) return;\n    if (P.size() == 1) {\n        ans[P[0].id] = R;\n        return;\n    }\n\n    long long total_r = 0;\n    for (const auto& p : P) total_r += p.r;\n    long long total_area = (long long)(R.x2 - R.x1) * (R.y2 - R.y1);\n    double E = (double)total_area - (double)total_r;\n\n    vector<Split> splits;\n\n    // --- Vertical Splits ---\n    sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n        if (a.x != b.x) return a.x < b.x;\n        return a.y < b.y;\n    });\n\n    int n = P.size();\n    for (int j = 1; j < n; ++j) {\n        // Points in the left partition are P[0...j-1]\n        // A split at x = k is valid if P[j-1].x < k <= P[j].x\n        if (P[j-1].x < P[j].x) {\n            long long R_L = 0;\n            for (int i = 0; i < j; ++i) R_L += P[i].r;\n            \n            double target_E_L = E * (double)j / n;\n            double target_A_L = (double)R_L + target_E_L;\n            int H = R.y2 - R.y1;\n            \n            // Target width is target_A_L / H\n            int k = R.x1 + (int)round(target_A_L / (double)H);\n            // Clamp k within the valid split range for this point partition\n            k = max(P[j-1].x + 1, min(P[j].x, k));\n            \n            long long actual_A_L = (long long)(k - R.x1) * H;\n            double actual_E_L = (double)actual_A_L - (double)R_L;\n            double score = abs(actual_E_L - target_E_L);\n            splits.push_back({true, k, score, j});\n        }\n    }\n\n    // --- Horizontal Splits ---\n    sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n        if (a.y != b.y) return a.y < b.y;\n        return a.x < b.x;\n    });\n\n    for (int j = 1; j < n; ++j) {\n        if (P[j-1].y < P[j].y) {\n            long long R_L = 0;\n            for (int i = 0; i < j; ++i) R_L += P[i].r;\n            \n            double target_E_L = E * (double)j / n;\n            double target_A_L = (double)R_L + target_E_L;\n            int W = R.x2 - R.x1;\n            \n            int k = R.y1 + (int)round(target_A_L / (double)W);\n            k = max(P[j-1].y + 1, min(P[j].y, k));\n\n            long long actual_A_L = (long long)W * (k - R.y1);\n            double actual_E_L = (double)actual_A_L - (double)R_L;\n            double score = abs(actual_E_L - target_E_L);\n            splits.push_back({false, k, score, j});\n        }\n    }\n\n    if (splits.empty()) {\n        // Fallback to avoid empty partitions\n        ans[P[0].id] = {R.x1, R.y1, R.x1 + 1, R.y1 + 1};\n        return;\n    }\n\n    // Sort splits by score (ascending)\n    sort(splits.begin(), splits.end(), [](const Split& a, const Split& b) {\n        return a.score < b.score;\n    });\n\n    // Pick one of the top-scoring splits to introduce randomness\n    int K_options = min((int)splits.size(), 3);\n    uniform_int_distribution<int> dist(0, K_options - 1);\n    Split best = splits[dist(gen)];\n\n    vector<Point> P_L, P_R;\n    Rect R_L, R_R;\n    if (best.vertical) {\n        R_L = {R.x1, R.y1, best.k, R.y2};\n        R_R = {best.k, R.y1, R.x2, R.y2};\n        // To split correctly, P must be sorted by X\n        sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n            if (a.x != b.x) return a.x < b.x;\n            return a.y < b.y;\n        });\n        for (int i = 0; i < best.j; ++i) P_L.push_back(P[i]);\n        for (int i = best.j; i < n; ++i) P_R.push_back(P[i]);\n    } else {\n        R_L = {R.x1, R.y1, R.x2, best.k};\n        R_R = {R.x1, best.k, R.x2, R.y2};\n        // To split correctly, P must be sorted by Y\n        sort(P.begin(), P.end(), [](const Point& a, const Point& b) {\n            if (a.y != b.y) return a.y < b.y;\n            return a.x < b.x;\n        });\n        for (int i = 0; i < best.j; ++i) P_L.push_back(P[i]);\n        for (int i = best.j; i < n; ++i) P_R.push_back(P[i]);\n    }\n\n    solve(R_L, P_L, gen);\n    solve(R_R, P_R, gen);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> points_orig[i].x >> points_orig[i].y >> points_orig[i].r;\n        points_orig[i].id = i;\n    }\n\n    Rect total_rect = {0, 0, 10000, 10000};\n    vector<Point> P_init;\n    for (int i = 0; i < N; ++i) P_init.push_back(points_orig[i]);\n\n    double best_total_sat = -1.0;\n    Rect best_ans_res[200];\n\n    // Perform multiple iterations to improve the final result\n    for (int iter = 0; iter < 120; ++iter) {\n        mt19937 current_gen(iter * 987654321LL);\n        solve(total_rect, P_init, current_gen);\n        \n        double current_sat = 0;\n        for (int i = 0; i < N; ++i) {\n            int xi = points_orig[i].x;\n            int yi = points_orig[i].y;\n            int ri = points_orig[i].r;\n            int a = ans[i].x1, b = ans[i].y1, c = ans[i].x2, d = ans[i].y2;\n            \n            // Check if point is contained in its assigned rectangle\n            if (xi >= a && xi < c && yi >= b && yi < d) {\n                long long si = (long long)(c - a) * (d - b);\n                double x = (double)min((long long)ri, si) / max((long long)ri, si);\n                current_sat += 1.0 - (1.0 - x) * (1.0 - x);\n            }\n        }\n        \n        if (current_sat > best_total_sat) {\n            best_total_sat = current_sat;\n            for (int i = 0; i < N; ++i) best_ans_res[i] = ans[i];\n        }\n    }\n\n    // Final output\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_res[i].x1 << \" \" << best_ans_res[i].y1 << \" \" \n             << best_ans_res[i].x2 << \" \" << best_ans_res[i].y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\n// Constants for the 50x50 grid\nconst int N = 50;\nconst int MAX_TILES = 2500;\nconst int NUM_U64 = (MAX_TILES + 63) / 64;\n\nint si, sj;\nint T[N][N];\nint P[N][N];\n\n// State structure for Beam Search\nstruct State {\n    int r, c;\n    int score;\n    uint64_t visited_tiles[NUM_U64];\n    int prev_idx;\n    char move;\n    double heuristic;\n    int visited_count;\n};\n\n// Movement vectors\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read initial position and grid data\n    if (!(cin >> si >> sj)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> T[i][j];\n        }\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> P[i][j];\n        }\n    }\n\n    // all_states stores all visited states to reconstruct the path later\n    vector<State> all_states;\n    all_states.reserve(1000000);\n\n    // Initialize starting state\n    State start;\n    start.r = si;\n    start.c = sj;\n    start.score = P[si][sj];\n    memset(start.visited_tiles, 0, sizeof(start.visited_tiles));\n    int start_tile = T[si][sj];\n    start.visited_tiles[start_tile / 64] |= (1ULL << (start_tile % 64));\n    start.prev_idx = -1;\n    start.move = ' ';\n    start.visited_count = 1;\n    // Heuristic: current score + potential score from remaining tiles\n    // average P is ~50, so we use a weight of 25 to encourage longer paths.\n    start.heuristic = (double)start.score + (double)(MAX_TILES - 1) * 25.0;\n    all_states.push_back(start);\n\n    // current_beam stores indices of the most promising states from the previous step\n    vector<int> current_beam;\n    current_beam.push_back(0);\n\n    int best_idx = 0;\n\n    // Beam Search Process\n    // The number of steps is limited by the maximum possible tiles in the grid\n    for (int step = 0; step < 2500; ++step) {\n        if (current_beam.empty()) break;\n\n        vector<int> next_beam_candidates;\n        for (int idx : current_beam) {\n            const State& s = all_states[idx];\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i];\n                int nc = s.c + dc[i];\n                \n                // Check grid bounds\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int nt = T[nr][nc];\n                    // Check if the tile of the next square has been visited\n                    if (!(s.visited_tiles[nt / 64] & (1ULL << (nt % 64)))) {\n                        State next_s;\n                        next_s.r = nr;\n                        next_s.c = nc;\n                        next_s.score = s.score + P[nr][nc];\n                        memcpy(next_s.visited_tiles, s.visited_tiles, sizeof(next_s.visited_tiles));\n                        next_s.visited_tiles[nt / 64] |= (1ULL << (nt % 64));\n                        next_s.prev_idx = idx;\n                        next_s.move = move_char[i];\n                        next_s.visited_count = s.visited_count + 1;\n                        // Update heuristic for sorting\n                        next_s.heuristic = (double)next_s.score + (double)(MAX_TILES - next_s.visited_count) * 25.0;\n\n                        next_beam_candidates.push_back(all_states.size());\n                        all_states.push_back(next_s);\n\n                        // Keep track of the state with the highest score found\n                        if (all_states.back().score > all_states[best_idx].score) {\n                            best_idx = (int)all_states.size() - 1;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (next_beam_candidates.empty()) break;\n\n        // Sort all potential next states by their heuristic score\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [&](int a, int b) {\n            return all_states[a].heuristic > all_states[b].heuristic;\n        });\n\n        // Select the top B states to form the new beam\n        current_beam.clear();\n        const int B = 100; // Beam width\n        int num_to_keep = min((int)next_beam_candidates.size(), B);\n        for (int i = 0; i < num_to_keep; ++i) {\n            current_beam.push_back(next_beam_candidates[i]);\n        }\n    }\n\n    // Backtrack from the best state to reconstruct the movement path\n    string path = \"\";\n    int curr = best_idx;\n    while (curr != -1 && all_states[curr].prev_idx != -1) {\n        path += all_states[curr].move;\n        curr = all_states[curr].prev_idx;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Output the resulting path\n    cout << path << endl;\n\n    return 0;\n}\n","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: Estimate unknown edge weights in a 30x30 grid graph through noisy feedback.\n * Strategy: Use Dijkstra's algorithm to find paths based on current estimates,\n * and update those estimates using a relaxed Kaczmarz method (stochastic gradient descent \n * on the error between the reported path length and our current estimated path length).\n * \n * The feedback L_k is a noisy measurement of the true path length b_k: L_k = round(b_k * e_k),\n * where e_k is uniformly random in [0.9, 1.1].\n * To deal with this noise, we use a decaying learning rate (eta).\n */\n\nconst int N = 30;\ndouble h[N][N - 1]; // horizontal edges: h[i][j] connects (i, j) and (i, j+1)\ndouble v[N - 1][N]; // vertical edges: v[i][j] connects (i, j) and (i+1, j)\n\nstruct Node {\n    int r, c;\n    double d;\n    bool operator>(const Node& other) const {\n        return d > other.d;\n    }\n};\n\nstruct Parent {\n    int r, c;\n    char dir;\n};\n\nParent parent[N][N];\ndouble dists[N][N];\n\n// Dijkstra's algorithm to find the shortest path from (sr, sc) to (tr, tc)\n// based on current edge weight estimates.\nvoid dijkstra(int sr, int sc, int tr, int tc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j] = 1e18;\n            parent[i][j] = {-1, -1, ' '};\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[sr][sc] = 0;\n    pq.push({sr, sc, 0.0});\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    while (!pq.empty()) {\n        Node top = pq.top();\n        pq.pop();\n\n        int r = top.r;\n        int c = top.c;\n        double d = top.d;\n\n        if (d > dists[r][c]) continue;\n        if (r == tr && c == tc) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = 0;\n                if (dirs[i] == 'U') weight = v[nr][c];\n                else if (dirs[i] == 'D') weight = v[r][c];\n                else if (dirs[i] == 'L') weight = h[r][nc];\n                else if (dirs[i] == 'R') weight = h[r][c];\n\n                if (dists[nr][nc] > d + weight) {\n                    dists[nr][nc] = d + weight;\n                    parent[nr][nc] = {r, c, dirs[i]};\n                    pq.push({nr, nc, dists[nr][nc]});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Increase speed of standard I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize edge weights to a reasonable middle value (average of expected range).\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Step 1: Compute path using Dijkstra's based on current estimates.\n        dijkstra(si, sj, ti, tj);\n\n        string path = \"\";\n        int cr = ti, cc = tj;\n        // Backtrack from destination to start to build the path string.\n        while (cr != si || cc != sj) {\n            Parent p = parent[cr][cc];\n            path += p.dir;\n            cr = p.r;\n            cc = p.c;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl; // endl ensures standard output is flushed.\n\n        // Step 2: Receive the reported path length (with 10% noise).\n        long long L_k;\n        if (!(cin >> L_k)) break;\n\n        // Step 3: Calculate the current path length according to our estimated weights.\n        double estimated_path_len = 0;\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                estimated_path_len += v[cr - 1][cc];\n                cr--;\n            } else if (d == 'D') {\n                estimated_path_len += v[cr][cc];\n                cr++;\n            } else if (d == 'L') {\n                estimated_path_len += h[cr][cc - 1];\n                cc--;\n            } else if (d == 'R') {\n                estimated_path_len += h[cr][cc];\n                cc++;\n            }\n        }\n\n        // Step 4: Update weights using the error diff = (reported_length - estimated_length).\n        // Using the Relaxed Kaczmarz method: w_e = w_e + (diff / |path|) * eta.\n        double diff = (double)L_k - estimated_path_len;\n        \n        // The learning rate eta decays slowly to manage the 10% noise and achieve convergence.\n        double eta = 0.5 * pow(0.9975, k);\n        double step = (diff / (double)path.size()) * eta;\n\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                v[cr - 1][cc] += step;\n                cr--;\n            } else if (d == 'D') {\n                v[cr][cc] += step;\n                cr++;\n            } else if (d == 'L') {\n                h[cr][cc - 1] += step;\n                cc--;\n            } else if (d == 'R') {\n                h[cr][cc] += step;\n                cc++;\n            }\n        }\n\n        // Step 5: Maintain edge weights within physically reasonable bounds.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) if (h[i][j] < 100.0) h[i][j] = 100.0;\n            if (i < N - 1) {\n                for (int j = 0; j < N; ++j) if (v[i][j] < 100.0) v[i][j] = 100.0;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find an N x N (N=20) matrix of characters A-H or '.' that satisfies \n * as many of M (400-800) given strings as possible. The matrix is a torus.\n * Scoring:\n * - If c < M: 10^8 * (c / M)\n * - If c = M: 10^8 * (2 * N^2 / (2 * N^2 - d)), where d is the number of '.' characters.\n * \n * Strategy:\n * 1. Use Simulated Annealing (SA) to maximize the number of satisfied strings (c).\n *    The state is an N x N matrix of characters A-H.\n *    An efficient way to update c during SA is to maintain a mismatch count for \n *    each possible occurrence of each string.\n * 2. If c = M is achieved, use a greedy approach to maximize the number of '.' characters (d).\n *    Replace characters with '.' as long as no string is lost.\n * \n * Complexity:\n * - SA: O(iterations * (number of occurrences covering a cell) * (strings per length))\n * - Pre-calculation: O(N^2 * M * L)\n */\n\nint N, M;\nstring s[800];\nchar A[20][20];\nint counts[800]; // Number of occurrences of string s[k] currently satisfied\nint c_satisfied = 0;\nvector<int> strings_by_len[13];\nvector<int> mismatch_count[2][20][20][13];\n\nstruct Occ {\n    int t, line, start, len, p, idx, k;\n};\nvector<Occ> cell_occs[20][20];\n\nstruct Change {\n    int t, line, start, len, idx, k;\n    int old_m, old_count_k;\n};\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        strings_by_len[s[i].length()].push_back(i);\n    }\n\n    // Initial random matrix of A-H\n    mt19937 rng(42);\n    string chars = \"ABCDEFGH\";\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = chars[rng() % 8];\n        }\n    }\n\n    // Pre-calculate mismatch counts for each occurrence of each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    mismatch_count[t][i][j][len].resize(strings_by_len[len].size());\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        int k = strings_by_len[len][idx];\n                        int mismatches = 0;\n                        for (int p = 0; p < len; ++p) {\n                            int ni = (t == 0) ? i : (i + p) % N;\n                            int nj = (t == 0) ? (j + p) % N : j;\n                            if (A[ni][nj] != s[k][p]) mismatches++;\n                        }\n                        mismatch_count[t][i][j][len][idx] = mismatches;\n                    }\n                }\n            }\n        }\n    }\n\n    // Calculate the number of satisfied occurrences for each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        if (mismatch_count[t][i][j][len][idx] == 0) {\n                            counts[strings_by_len[len][idx]]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    for (int k = 0; k < M; ++k) if (counts[k] > 0) c_satisfied++;\n\n    // Pre-calculate which occurrences cover which cell (i, j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int t = 0; t < 2; ++t) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int p = 0; p < len; ++p) {\n                        int line = (t == 0) ? i : (i - p + N) % N;\n                        int start = (t == 0) ? (j - p + N) % N : j;\n                        for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                            cell_occs[i][j].push_back({t, line, start, len, p, idx, strings_by_len[len][idx]});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulated Annealing phase\n    auto start_time = chrono::high_resolution_clock::now();\n    int max_iter = 250000;\n    vector<Change> changes;\n    changes.reserve(15000); \n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        if ((iter & 1023) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2600) break;\n        }\n\n        int r = rng() % (N * N);\n        int i = r / N, j = r % N;\n        char old_v = A[i][j];\n        char new_v = chars[rng() % 8];\n        if (old_v == new_v) continue;\n\n        double T = 1.0 * (1.0 - (double)iter / max_iter);\n        int delta_c = 0;\n        changes.clear();\n\n        for (auto& occ : cell_occs[i][j]) {\n            int& m = mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx];\n            int old_m = m;\n            if (old_v != s[occ.k][occ.p] && new_v == s[occ.k][occ.p]) m--;\n            else if (old_v == s[occ.k][occ.p] && new_v != s[occ.k][occ.p]) m++;\n            \n            if (old_m == 0 && m > 0) {\n                if (--counts[occ.k] == 0) delta_c--;\n            } else if (old_m > 0 && m == 0) {\n                if (++counts[occ.k] == 1) delta_c++;\n            }\n            changes.push_back({occ.t, occ.line, occ.start, occ.len, occ.idx, occ.k, old_m, counts[occ.k]});\n        }\n\n        if (delta_c >= 0 || (T > 1e-9 && (double)rng() / rng.max() < exp(delta_c / T))) {\n            A[i][j] = new_v;\n            c_satisfied += delta_c;\n        } else {\n            for (int idx = (int)changes.size() - 1; idx >= 0; --idx) {\n                auto& ch = changes[idx];\n                mismatch_count[ch.t][ch.line][ch.start][ch.len][ch.idx] = ch.old_m;\n                counts[ch.k] = ch.old_count_k;\n            }\n        }\n    }\n\n    // Phase 2: Maximize density (number of '.') if all strings are satisfied\n    if (c_satisfied == M) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (A[i][j] != '.') {\n                    char old_v = A[i][j];\n                    vector<int> matching_occs_using_ij(M, 0);\n                    for (auto& occ : cell_occs[i][j]) {\n                        if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                            matching_occs_using_ij[occ.k]++;\n                        }\n                    }\n                    bool ok = true;\n                    for (int k = 0; k < M; ++k) {\n                        if (matching_occs_using_ij[k] > 0 && counts[k] == matching_occs_using_ij[k]) {\n                            ok = false; \n                            break;\n                        }\n                    }\n                    if (ok) {\n                        A[i][j] = '.';\n                        for (auto& occ : cell_occs[i][j]) {\n                            if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                                counts[occ.k]--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << A[i][j];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a shortest patrol route that visits road squares such that\n * all road squares become \"visible\" at least once.\n * A square is visible if it's in the same row/column and no obstacles are between.\n * \n * Strategy:\n * 1. Represent the map and precompute visibility (which squares can see each other).\n * 2. Use a greedy strategy to pick a subset of road squares (ToVisit) that covers\n *    the most \"uncovered\" road squares with the minimum distance.\n * 3. The greedy heuristic: Pick the \"hardest-to-cover\" square (one with fewest \n *    potential visitors) and then pick the best visitor (maximizing newly covered / distance).\n * 4. Once the set of points to visit is found, solve the Traveling Salesperson Problem (TSP)\n *    on these points using a Nearest Neighbor heuristic followed by 2-opt refinement.\n * 5. Convert the TSP tour into the actual move string (U, D, L, R).\n */\n\nconst int INF = 1e9;\n\nint N, si, sj;\nint grid[70][70];\nvector<int> C[5000], S[5000];\nbool is_road[5000];\nint dists[5000];\nint parent_node[5000];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Standard Dijkstra to find shortest path distances from a source node\nvoid dijkstra(int start, int n_size) {\n    for (int i = 0; i < n_size; ++i) dists[i] = INF;\n    dists[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n\n    while (!pq.empty()) {\n        int d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n\n        if (d > dists[u]) continue;\n\n        int r = u / N, c = u % N;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != -1) {\n                int v = nr * N + nc;\n                if (dists[u] + grid[nr][nc] < dists[v]) {\n                    dists[v] = dists[u] + grid[nr][nc];\n                    parent_node[v] = u;\n                    pq.push({dists[v], v});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> si >> sj)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            if (row[j] == '#') {\n                grid[i][j] = -1;\n                is_road[i * N + j] = false;\n            } else {\n                grid[i][j] = row[j] - '0';\n                is_road[i * N + j] = true;\n            }\n        }\n    }\n\n    // Precompute visibility\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!is_road[i * N + j]) continue;\n            int u = i * N + j;\n            C[u].push_back(u);\n            S[u].push_back(u);\n            // Horizontal\n            for (int k = j - 1; k >= 0 && grid[i][k] != -1; --k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = j + 1; k < N && grid[i][k] != -1; ++k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            // Vertical\n            for (int k = i - 1; k >= 0 && grid[k][j] != -1; --k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = i + 1; k < N && grid[k][j] != -1; ++k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n        }\n    }\n\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            sort(C[i].begin(), C[i].end());\n            C[i].erase(unique(C[i].begin(), C[i].end()), C[i].end());\n            sort(S[i].begin(), S[i].end());\n            S[i].erase(unique(S[i].begin(), S[i].end()), S[i].end());\n        }\n    }\n\n    // Set Cover Greedy\n    vector<bool> is_uncovered(N * N, false);\n    vector<int> uncovered_list;\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            is_uncovered[i] = true;\n            uncovered_list.push_back(i);\n        }\n    }\n\n    vector<int> ToVisit;\n    int curr = si * N + sj;\n    while (!uncovered_list.empty()) {\n        dijkstra(curr, N * N);\n        int best_r = -1;\n        int min_S_r = 1000000;\n        for (int r : uncovered_list) {\n            if ((int)S[r].size() < min_S_r) {\n                min_S_r = S[r].size();\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break;\n\n        int best_v = -1;\n        double best_gain = -1.0;\n        for (int v : S[best_r]) {\n            int gain = 0;\n            for (int road_idx : C[v]) {\n                if (is_uncovered[road_idx]) gain++;\n            }\n            double current_gain = (double)gain / (dists[v] + 1.0);\n            if (current_gain > best_gain) {\n                best_gain = current_gain;\n                best_v = v;\n            }\n        }\n        if (best_v == -1 || best_gain <= 0.0) break;\n\n        ToVisit.push_back(best_v);\n        for (int road_idx : C[best_v]) {\n            is_uncovered[road_idx] = false;\n        }\n        \n        vector<int> next_uncovered;\n        for (int r : uncovered_list) {\n            if (is_uncovered[r]) next_uncovered.push_back(r);\n        }\n        uncovered_list = next_uncovered;\n        curr = best_v;\n    }\n\n    // TSP Step: Nearest Neighbor + 2-opt\n    vector<int> P;\n    P.push_back(si * N + sj);\n    set<int> seen;\n    seen.insert(si * N + sj);\n    for (int v : ToVisit) {\n        if (seen.find(v) == seen.end()) {\n            P.push_back(v);\n            seen.insert(v);\n        }\n    }\n\n    int k_points = P.size();\n    vector<vector<int>> dist_matrix(k_points, vector<int>(k_points, INF));\n    for (int i = 0; i < k_points; ++i) {\n        dijkstra(P[i], N * N);\n        for (int j = 0; j < k_points; ++j) {\n            dist_matrix[i][j] = dists[P[j]];\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited_tsp(k_points, false);\n    int current_idx = 0;\n    tour.push_back(0);\n    visited_tsp[0] = true;\n    for (int step = 1; step < k_points; ++step) {\n        int next_idx = -1;\n        int min_d = INF;\n        for (int j = 0; j < k_points; ++j) {\n            if (!visited_tsp[j] && dist_matrix[current_idx][j] < min_d) {\n                min_d = dist_matrix[current_idx][j];\n                next_idx = j;\n            }\n        }\n        if (next_idx == -1) break;\n        tour.push_back(next_idx);\n        visited_tsp[next_idx] = true;\n        current_idx = next_idx;\n    }\n    tour.push_back(0);\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 1; i < sz - 2; ++i) {\n            for (int j = i + 1; j < sz - 1; ++j) {\n                if (dist_matrix[tour[i - 1]][tour[i]] + dist_matrix[tour[j]][tour[j + 1]] >\n                    dist_matrix[tour[i - 1]][tour[j]] + dist_matrix[tour[i]][tour[j + 1]]) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Final Path Reconstruction\n    string final_route = \"\";\n    for (int i = 0; i < (int)tour.size() - 1; ++i) {\n        int u = P[tour[i]];\n        int v = P[tour[i+1]];\n        if (u == v) continue;\n        dijkstra(u, N * N);\n        vector<int> path_nodes;\n        int curr_node = v;\n        while (curr_node != u) {\n            path_nodes.push_back(curr_node);\n            curr_node = parent_node[curr_node];\n        }\n        reverse(path_nodes.begin(), path_nodes.end());\n        \n        int prev_r = u / N, prev_c = u % N;\n        for (int node : path_nodes) {\n            int nr = node / N, nc = node % N;\n            if (nr == prev_r + 1) final_route += 'D';\n            else if (nr == prev_r - 1) final_route += 'U';\n            else if (nc == prev_c + 1) final_route += 'R';\n            else if (nc == prev_c - 1) final_route += 'L';\n            prev_r = nr;\n            prev_c = nc;\n        }\n    }\n    cout << final_route << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis & Improvements:\n * \n * 1. Skill Estimation:\n *    The previous skill estimation used a very simple update rule. In this version, we use a more \n *    refined Stochastic Gradient Descent (SGD) approach. The expected completion time t_ij is \n *    approximately w_ij = sum_k max(0, d_ik - s_jk). If the observed time actual_t is different \n *    from the estimated w_ij, we update the skill levels s_jk proportionally to their \n *    contribution to the sum.\n *    Update rule: s_jk = s_jk - eta * (actual_t - w_ij_est) * (contribution_of_k),\n *    where contribution_of_k = max(0, d_ik - s_jk) / w_ij_est.\n * \n * 2. Task Priority & Scheduling:\n *    Instead of just using the longest dependency chain (rank), we now consider both the rank \n *    and the number of descendants (tasks that depend on the current task). This helps in \n *    unblocking more tasks sooner.\n *    Priority = rank[i] + 0.01 * descendants[i].\n *    The greedy matching score = Priority[i] / (ExpectedTime(i, j) + 1).\n *    We use a global greedy matching approach each day to find the best (task, member) pair.\n * \n * 3. Computational Complexity:\n *    The algorithm complexity is approximately O(Days * M * N * M) in the worst case per day, \n *    which is around 2000 * 20 * 1000 * 20 = 8 * 10^8 operations. Given the simplicity of \n *    the inner loop, it fits within the 3.0s time limit.\n */\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task requirement skill levels\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    // Task dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // Topological sort to handle the DAG structure\n    vector<int> topo_order;\n    vector<int> temp_in_degree = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (temp_in_degree[i] == 0) q.push(i);\n    }\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        topo_order.push_back(u);\n        for (int v : adj[u]) {\n            if (--temp_in_degree[v] == 0) q.push(v);\n        }\n    }\n\n    // Precalculate reachability using bitsets to find the number of descendants\n    vector<bitset<1000>> reach(N);\n    for (int i = N - 1; i >= 0; --i) {\n        int u = topo_order[i];\n        reach[u].set(u);\n        for (int v : adj[u]) {\n            reach[u] |= reach[v];\n        }\n    }\n\n    // Precalculate rank (length of the longest path) and descendants\n    vector<int> task_rank(N, 0);\n    vector<int> descendants(N, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        int u = topo_order[i];\n        int max_r = 0;\n        for (int v : adj[u]) {\n            max_r = max(max_r, task_rank[v]);\n        }\n        task_rank[u] = 1 + max_r;\n        descendants[u] = (int)reach[u].count() - 1;\n    }\n\n    // Task priority for scheduling\n    vector<double> task_priority(N);\n    for (int i = 0; i < N; ++i) {\n        task_priority[i] = (double)task_rank[i] + (double)descendants[i] * 0.01;\n    }\n\n    // State management\n    vector<vector<double>> s(M, vector<double>(K, 0.0)); // Skill level estimates\n    vector<int> task_status(N, 0);        // 0: not started, 1: in progress, 2: completed\n    vector<int> member_current_task(M, -1); // -1 if idle, else task index\n    vector<int> task_start_day(N, 0);     // Start day of task i\n\n    int current_day = 1;\n    while (current_day <= 2000) {\n        // 1. Identify available tasks (dependencies met) and idle members\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] == 0 && in_degree[i] == 0) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // 2. Greedy matching: find the best (task, member) pair based on priority/expected_time\n        struct Assignment {\n            int m, t;\n        };\n        vector<Assignment> current_day_assignments;\n        vector<bool> task_assigned(N, false);\n        vector<bool> member_used(M, false);\n\n        while (true) {\n            int best_i = -1, best_j = -1;\n            double best_score = -1.0;\n\n            for (int i : available_tasks) {\n                if (task_assigned[i]) continue;\n                for (int j : idle_members) {\n                    if (member_used[j]) continue;\n\n                    // Calculate estimated w_ij\n                    double w_ij = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > s[j][k]) {\n                            w_ij += (double)d[i][k] - s[j][k];\n                        }\n                    }\n                    double expected_t = (w_ij < 1e-7) ? 1.0 : max(1.0, w_ij);\n                    double score = task_priority[i] / (expected_t + 1.0);\n\n                    if (score > best_score) {\n                        best_score = score;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n\n            if (best_i == -1) break;\n\n            task_assigned[best_i] = true;\n            member_used[best_j] = true;\n            current_day_assignments.push_back({best_j, best_i});\n            task_status[best_i] = 1;\n            member_current_task[best_j] = best_i;\n            task_start_day[best_i] = current_day;\n        }\n\n        // 3. Output the assignments\n        cout << current_day_assignments.size();\n        for (auto& assign : current_day_assignments) {\n            cout << \" \" << assign.m + 1 << \" \" << assign.t + 1;\n        }\n        cout << endl;\n\n        // 4. Read feedback on completed tasks\n        int num_completed;\n        if (!(cin >> num_completed)) break;\n        if (num_completed == -1) break;\n\n        // 5. Update skill estimates and dependency graph\n        for (int idx = 0; idx < num_completed; ++idx) {\n            int f;\n            cin >> f;\n            --f; // 0-indexed member\n            int t_idx = member_current_task[f];\n            int actual_t = current_day - task_start_day[t_idx] + 1;\n\n            // Re-estimate current w_ij\n            double w_ij_est = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[t_idx][k] > s[f][k]) {\n                    w_ij_est += (double)d[t_idx][k] - s[f][k];\n                }\n            }\n            if (w_ij_est < 1e-7) w_ij_est = 0.1;\n\n            // Refined SGD update\n            double error = (double)actual_t - w_ij_est;\n            double eta = 0.5 / (1.0 + 0.01 * current_day); // Decaying learning rate\n\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) {\n                    double contribution = diff / w_ij_est;\n                    s[f][k] -= eta * error * contribution;\n                    if (s[f][k] < 0) s[f][k] = 0;\n                }\n            }\n\n            // Mark task as completed and update in-degree of dependents\n            task_status[t_idx] = 2;\n            member_current_task[f] = -1;\n            for (int v : adj[t_idx]) {\n                in_degree[v]--;\n            }\n        }\n        current_day++;\n    }\n\n    return 0;\n}\n","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Structure to represent a single delivery order\nstruct Order {\n    int a, b, c, d, id;\n};\n\n// Structure to represent a single stop in the delivery route\nstruct Point {\n    int x, y, order_idx;\n    bool is_pickup;\n};\n\n// Function to calculate Manhattan distance between two points\ninline int dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Function to calculate the total distance of the route\nint total_dist(const vector<Point>& P) {\n    int d = 0;\n    d += dist(400, 400, P[0].x, P[0].y);\n    for (size_t i = 0; i < P.size() - 1; ++i) {\n        d += dist(P[i].x, P[i].y, P[i + 1].x, P[i + 1].y);\n    }\n    d += dist(P.back().x, P.back().y, 400, 400);\n    return d;\n}\n\n// Function to update the positions of pickups and deliveries in the current sequence\nvoid update_pos(const vector<Point>& P, vector<int>& pos_A, vector<int>& pos_C) {\n    fill(pos_A.begin(), pos_A.end(), -1);\n    fill(pos_C.begin(), pos_C.end(), -1);\n    for (int i = 0; i < (int)P.size(); ++i) {\n        if (P[i].is_pickup) pos_A[P[i].order_idx] = i;\n        else pos_C[P[i].order_idx] = i;\n    }\n}\n\nint main() {\n    // Optimizing I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<Order> all_orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        if (!(cin >> all_orders[i].a >> all_orders[i].b >> all_orders[i].c >> all_orders[i].d)) break;\n        all_orders[i].id = i + 1;\n    }\n\n    // Initial strategy: Pick 50 orders with the smallest individual trip distance\n    vector<pair<int, int>> costs;\n    for (int i = 0; i < 1000; ++i) {\n        int d = dist(400, 400, all_orders[i].a, all_orders[i].b) +\n                dist(all_orders[i].a, all_orders[i].b, all_orders[i].c, all_orders[i].d) +\n                dist(all_orders[i].c, all_orders[i].d, 400, 400);\n        costs.push_back({d, i});\n    }\n    sort(costs.begin(), costs.end());\n\n    vector<int> S, not_S;\n    vector<bool> in_S(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        S.push_back(costs[i].second);\n        in_S[costs[i].second] = true;\n    }\n    for (int i = 0; i < 1000; ++i) {\n        if (!in_S[i]) not_S.push_back(i);\n    }\n\n    // Construct an initial valid delivery route: Alternating pickup and delivery for chosen orders\n    vector<Point> P;\n    for (int idx : S) {\n        P.push_back({all_orders[idx].a, all_orders[idx].b, idx, true});\n        P.push_back({all_orders[idx].c, all_orders[idx].d, idx, false});\n    }\n\n    vector<int> pos_A(1000), pos_C(1000);\n    update_pos(P, pos_A, pos_C);\n\n    int current_dist = total_dist(P);\n    vector<Point> best_P = P;\n    vector<int> best_S = S;\n    int best_dist = current_dist;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 1000.0;\n    double T_end = 1.0;\n\n    int iter = 0;\n    // Simulated Annealing to optimize the set S and the route P\n    while (true) {\n        iter++;\n        if (iter % 1000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n            if (elapsed >= 1.0) break;\n        }\n\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n        double T = T_start * pow(T_end / T_start, elapsed);\n\n        int move_type = rng() % 3;\n\n        if (move_type == 0) { // Move 1: Swap two points in the sequence\n            int i = rng() % 100;\n            int j = rng() % 100;\n            if (i == j) continue;\n\n            int ord_i = P[i].order_idx;\n            int ord_j = P[j].order_idx;\n\n            swap(P[i], P[j]);\n            update_pos(P, pos_A, pos_C);\n\n            // Check validity: pickup must precede delivery for the affected orders\n            bool valid = (pos_A[ord_i] < pos_C[ord_i]) && (pos_A[ord_j] < pos_C[ord_j]);\n\n            if (valid) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    swap(P[i], P[j]); // Undo swap\n                    update_pos(P, pos_A, pos_C);\n                }\n            } else {\n                swap(P[i], P[j]); // Undo invalid swap\n                update_pos(P, pos_A, pos_C);\n            }\n        } else if (move_type == 1) { // Move 2: Reinsert a point in a different position\n            int i = rng() % 100;\n            int j = rng() % 100;\n            if (i == j) continue;\n\n            Point p = P[i];\n            P.erase(P.begin() + i);\n            P.insert(P.begin() + j, p);\n            int ord = p.order_idx;\n            update_pos(P, pos_A, pos_C);\n\n            if (pos_A[ord] < pos_C[ord]) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    P.erase(P.begin() + j);\n                    P.insert(P.begin() + i, p); // Undo insertion\n                    update_pos(P, pos_A, pos_C);\n                }\n            } else {\n                P.erase(P.begin() + j);\n                P.insert(P.begin() + i, p); // Undo invalid insertion\n                update_pos(P, pos_A, pos_C);\n            }\n        } else { // Move 3: Replace an order in the set S with one from not_S\n            int i_idx = rng() % 50;\n            int j_idx = rng() % 950;\n            int old_ord = S[i_idx];\n            int new_ord = not_S[j_idx];\n\n            int pA = pos_A[old_ord];\n            int pC = pos_C[old_ord];\n\n            Point old_pA = P[pA];\n            Point old_pC = P[pC];\n\n            P[pA] = {all_orders[new_ord].a, all_orders[new_ord].b, new_ord, true};\n            P[pC] = {all_orders[new_ord].c, all_orders[new_ord].d, new_ord, false};\n            S[i_idx] = new_ord;\n            not_S[j_idx] = old_ord;\n            update_pos(P, pos_A, pos_C);\n\n            int new_dist = total_dist(P);\n            // Replacement is inherently valid for the new order\n            if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                current_dist = new_dist;\n                if (current_dist < best_dist) {\n                    best_dist = current_dist;\n                    best_P = P;\n                    best_S = S;\n                }\n            } else {\n                P[pA] = old_pA;\n                P[pC] = old_pC;\n                S[i_idx] = old_ord;\n                not_S[j_idx] = new_ord;\n                update_pos(P, pos_A, pos_C);\n            }\n        }\n    }\n\n    // Final output of selected orders and the optimized route\n    cout << 50;\n    for (int idx : best_S) cout << \" \" << all_orders[idx].id;\n    cout << endl;\n    cout << best_P.size() + 2; // Start + 100 points + end\n    cout << \" 400 400\";\n    for (const auto& p : best_P) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \" 400 400\" << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * This is an online minimum spanning tree (MST) problem. We are given edges one by one \n * and must decide whether to include each edge in our spanning set immediately.\n * We know the possible range of each edge's length [d_i, 3*d_i], where d_i is the \n * rounded Euclidean distance.\n * \n * To minimize the total length of our adopted edges (A), we should aim to pick edges \n * that are likely to be in the actual MST. An edge (u, v) with weight l is in the MST \n * if and only if there is no path between u and v using only edges with weights strictly \n * less than l. \n * \n * Since we don't know the true lengths of future edges, we use their minimum possible \n * weights (d_j) as an estimate. This heuristic approach builds an MST of the \"estimated\" \n * graph. If an edge is \"necessary\" to connect components given the estimated future, \n * we adopt it.\n * \n * Complexity:\n * For each of the M edges, we build a temporary DSU of the graph containing already \n * selected edges (with their realized lengths) and future edges (with their minimum \n * estimated lengths) that have weights <= current edge's weight.\n * Time Complexity: O(M^2 * alpha(N)), where N=400 and M=1995.\n * 1995^2 * alpha(400) is roughly 1.6 * 10^7, which fits well within the 2s limit.\n */\n\n// Disjoint Set Union (DSU) structure\nstruct DSU {\n    vector<int> parent;\n    vector<int> rank;\n    DSU(int n) {\n        parent.resize(n);\n        iota(parent.begin(), parent.end(), 0);\n        rank.assign(n, 0);\n    }\n    int find(int i) {\n        if (parent[i] == i) return i;\n        return parent[i] = find(parent[i]);\n    }\n    void unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            if (rank[root_i] < rank[root_j]) {\n                parent[root_i] = root_j;\n            } else if (rank[root_i] > rank[root_j]) {\n                parent[root_j] = root_i;\n            } else {\n                parent[root_i] = root_j;\n                rank[root_j]++;\n            }\n        }\n    }\n};\n\n// Edge structure to store coordinates and weights\nstruct Edge {\n    int u, v, d, l;\n};\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> coords[i].first >> coords[i].second)) break;\n    }\n\n    // Read initial edge information (endpoints and d_i)\n    vector<Edge> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) break;\n        all_edges[i].u = u;\n        all_edges[i].v = v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        all_edges[i].d = (int)round(hypot(dx, dy));\n    }\n\n    // DSU to maintain the connectivity of adopted edges\n    DSU dsu_S(N);\n    // Vector to store the edges we have chosen to adopt\n    vector<Edge> S;\n\n    // Process each edge one by one\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n        all_edges[i].l = l_i;\n\n        // If u and v are already connected in our current forest, adding this edge\n        // would create a cycle and increase the total cost A without decreasing B.\n        if (dsu_S.find(all_edges[i].u) == dsu_S.find(all_edges[i].v)) {\n            cout << 0 << endl;\n        } else {\n            // Heuristic: Decide whether edge i is in the MST of the \"estimated\" graph.\n            // The estimated graph uses realized lengths for S and minimum possible d_j for future edges.\n            // An edge is in the MST if it's required to connect two components using edges <= l_i.\n            DSU dsu_Gprime(N);\n            \n            // Add already selected edges with weight <= l_i\n            for (const auto& e : S) {\n                if (e.l <= l_i) {\n                    dsu_Gprime.unite(e.u, e.v);\n                }\n            }\n            // Add potential future edges with estimated weight d_j <= l_i\n            for (int j = i + 1; j < M; ++j) {\n                if (all_edges[j].d <= l_i) {\n                    dsu_Gprime.unite(all_edges[j].u, all_edges[j].v);\n                }\n            }\n\n            // If edge i is necessary to connect its endpoints in the estimated graph, adopt it.\n            if (dsu_Gprime.find(all_edges[i].u) != dsu_Gprime.find(all_edges[i].v)) {\n                cout << 1 << endl;\n                S.push_back(all_edges[i]);\n                dsu_S.unite(all_edges[i].u, all_edges[i].v);\n            } else {\n                cout << 0 << endl;\n            }\n        }\n        // Flush the output as required by the interactive format\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc008":"","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// Problem constants and global state\nint si, sj, ti, tj;\ndouble p;\nbool wall_h[20][20];\nbool wall_v[20][20];\n\n// Movement directions\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\n/**\n * Finds the shortest path using BFS.\n * This is used as a starting point for the optimization.\n */\nstring get_shortest_path() {\n    queue<pair<pair<int, int>, string>> q;\n    q.push({{si, sj}, \"\"});\n    bool visited[20][20];\n    memset(visited, 0, sizeof(visited));\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto curr = q.front();\n        q.pop();\n        int r = curr.first.first;\n        int c = curr.first.second;\n        string path = curr.second;\n\n        if (r == ti && c == tj) return path;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            if (nr >= 0 && nr < 20 && nc >= 0 && nc < 20 && !visited[nr][nc]) {\n                bool blocked = false;\n                if (dr[i] == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n                if (!blocked) {\n                    visited[nr][nc] = true;\n                    q.push({{nr, nc}, path + dir_char[i]});\n                }\n            }\n        }\n    }\n    return \"\";\n}\n\n/**\n * Calculates the expected value of S = 401 - t using DP.\n * Complexity: O(L * 20 * 20)\n */\ndouble calculate_expected_value(const string& S) {\n    int L = S.length();\n    if (L > 200) return 0;\n    double dp[20][20];\n    memset(dp, 0, sizeof(dp));\n    dp[si][sj] = 1.0;\n    double expected_val = 0;\n    for (int t = 0; t < L; ++t) {\n        double next_dp[20][20];\n        memset(next_dp, 0, sizeof(next_dp));\n        int move_dr = 0, move_dc = 0;\n        if (S[t] == 'U') move_dr = -1;\n        else if (S[t] == 'D') move_dr = 1;\n        else if (S[t] == 'L') move_dc = -1;\n        else if (S[t] == 'R') move_dc = 1;\n\n        for (int r = 0; r < 20; ++r) {\n            for (int c = 0; c < 20; ++c) {\n                if (dp[r][c] <= 1e-18 || (r == ti && c == tj)) continue;\n\n                // Case 1: Forget (stay in place)\n                next_dp[r][c] += dp[r][c] * p;\n\n                // Case 2: Attempt move\n                int nr = r + move_dr;\n                int nc = c + move_dc;\n                bool blocked = false;\n                if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) {\n                    blocked = true;\n                } else if (move_dr == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n\n                if (blocked) {\n                    next_dp[r][c] += dp[r][c] * (1.0 - p);\n                } else {\n                    if (nr == ti && nc == tj) {\n                        expected_val += dp[r][c] * (1.0 - p) * (401 - (t + 1));\n                    } else {\n                        next_dp[nr][nc] += dp[r][c] * (1.0 - p);\n                    }\n                }\n            }\n        }\n        memcpy(dp, next_dp, sizeof(dp));\n    }\n    return expected_val;\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            wall_h[i][j] = (row[j] == '1');\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            wall_v[i][j] = (row[j] == '1');\n        }\n    }\n\n    // Starting string is the shortest path\n    string best_S = get_shortest_path();\n    double best_E = calculate_expected_value(best_S);\n\n    // Use a seeded random number generator\n    mt19937 rng(1337);\n    \n    // Optimization step: Enrichment (repeating moves)\n    // This improves robustness against forgetting moves.\n    for (int k = 2; k <= 5; ++k) {\n        string enriched_S = \"\";\n        for (char c : best_S) {\n            for (int count = 0; count < k; ++count) enriched_S += c;\n        }\n        if (enriched_S.length() <= 200) {\n            double e = calculate_expected_value(enriched_S);\n            if (e > best_E) {\n                best_E = e;\n                best_S = enriched_S;\n            }\n        }\n    }\n\n    // Simulated Annealing to optimize the string\n    string current_S = best_S;\n    double current_E = best_E;\n\n    clock_t start_time = clock();\n    const double max_time = 1.85; // Leave some buffer for safety\n\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > max_time) break;\n\n        // Linear cooling\n        double T = 5.0 * (1.0 - elapsed / max_time); \n\n        string next_S = current_S;\n        int type = uniform_int_distribution<int>(0, 4)(rng);\n\n        // Neighbor generation\n        if (type == 0) { // Add a duplicate character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.insert(i, 1, next_S[i]);\n            } else type = 1;\n        } else if (type == 1) { // Remove a duplicate character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                if (i > 0 && next_S[i] == next_S[i-1]) {\n                    next_S.erase(i, 1);\n                } else if (i < (int)next_S.length() - 1 && next_S[i] == next_S[i+1]) {\n                    next_S.erase(i, 1);\n                } else type = 0;\n            } else type = 0;\n        } else if (type == 2) { // Add a random character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length())(rng);\n                char c = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n                next_S.insert(i, 1, c);\n            } else type = 1;\n        } else if (type == 3) { // Remove a random character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.erase(i, 1);\n            } else type = 2;\n        } else if (type == 4) { // Change a random character\n            int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            next_S[i] = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n        }\n\n        double next_E = calculate_expected_value(next_S);\n        \n        // Acceptance criteria\n        if (next_E > current_E || (T > 1e-9 && exp((next_E - current_E) / T) > uniform_real_distribution<double>(0, 1)(rng))) {\n            current_S = next_S;\n            current_E = next_E;\n            if (current_E > best_E) {\n                best_E = current_E;\n                best_S = current_S;\n            }\n        }\n    }\n\n    // Final output\n    cout << best_S << endl;\n\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// The directions: 0: Left, 1: Up, 2: Right, 3: Down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Initial connectivity table for the 8 types\nint base_to[8][4] = {\n    {1, 0, -1, -1}, // 0: one curve (Left, Up)\n    {3, -1, -1, 0}, // 1: one curve (Up, Down)\n    {-1, -1, 3, 2}, // 2: one curve (Right, Down)\n    {-1, 2, 1, -1}, // 3: one curve (Down, Left)\n    {1, 0, 3, 2},    // 4: two curves (Left-Up, Right-Down)\n    {3, 2, 1, 0},    // 5: two curves (Up-Down, Left-Right)\n    {2, -1, 0, -1}, // 6: one straight (Left, Right)\n    {-1, 3, -1, 1}, // 7: one straight (Up, Down)\n};\n\n// Precomputed rotation connectivity table\n// rot_to[t][r][d] is the direction to the next tile for type t, rotated r times CCW, \n// when entering from direction d.\nint rot_to[8][4][4];\n\n// Function to rotate a direction 90 degrees counterclockwise: \n// 0 (L) -> 3 (D), 3 (D) -> 2 (R), 2 (R) -> 1 (U), 1 (U) -> 0 (L)\ninline int rotate_dir(int d) { return (d + 3) % 4; }\n// Inverse rotation\ninline int inv_rotate_dir(int d) { return (d + 1) % 4; }\n\nvoid precompute() {\n    for (int t = 0; t < 8; ++t) {\n        for (int d = 0; d < 4; ++d) rot_to[t][0][d] = base_to[t][d];\n        for (int r = 1; r < 4; ++r) {\n            for (int d = 0; d < 4; ++d) {\n                int prev_d = inv_rotate_dir(d);\n                int prev_to = rot_to[t][r - 1][prev_d];\n                if (prev_to == -1) rot_to[t][r][d] = -1;\n                else rot_to[t][r][d] = rotate_dir(prev_to);\n            }\n        }\n    }\n}\n\nint current_to[30][30][4];\nint initial_type[30][30];\nint current_rot[30][30];\nint visited[30][30][4];\nint timer = 0;\n\nlong long get_score(int& L1, int& L2) {\n    vector<int> lengths;\n    timer++;\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                if (visited[i][j][d] != timer) {\n                    int ci = i, cj = j, cd = d;\n                    int len = 0;\n                    bool possible = true;\n                    while (visited[ci][cj][cd] != timer) {\n                        visited[ci][cj][cd] = timer;\n                        int cd2 = current_to[ci][cj][cd];\n                        if (cd2 == -1) {\n                            possible = false;\n                            break;\n                        }\n                        int ni = ci + di[cd2];\n                        int nj = cj + dj[cd2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            possible = false;\n                            break;\n                        }\n                        len++;\n                        ci = ni; cj = nj;\n                        cd = (cd2 + 2) % 4;\n                    }\n                    if (possible && len > 0) {\n                        lengths.push_back(len);\n                    }\n                }\n            }\n        }\n    }\n    if (lengths.size() < 2) {\n        L1 = 0; L2 = 0;\n        return 0;\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    L1 = lengths[0];\n    L2 = lengths[1];\n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precompute();\n\n    for (int i = 0; i < 30; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; ++j) {\n            initial_type[i][j] = s[j] - '0';\n            current_rot[i][j] = 0;\n            for (int d = 0; d < 4; ++d) {\n                current_to[i][j][d] = rot_to[initial_type[i][j]][0][d];\n            }\n        }\n    }\n\n    int L1, L2;\n    long long current_score = get_score(L1, L2);\n    \n    mt19937 rng(1337);\n    clock_t start_time = clock();\n    \n    // Use local time limit per test case (roughly 18ms)\n    // For competitive programming, we assume about 100 cases.\n    // We will check time roughly every 100 iterations.\n    int iterations = 0;\n    while (true) {\n        if (++iterations % 100 == 0) {\n            if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n        }\n\n        int ri = rng() % 30;\n        int rj = rng() % 30;\n        int old_r = current_rot[ri][rj];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        // Backup the current connectivity for this tile\n        int backup_to[4];\n        for (int d = 0; d < 4; ++d) backup_to[d] = current_to[ri][rj][d];\n\n        // Update connectivity\n        current_rot[ri][rj] = new_r;\n        for (int d = 0; d < 4; ++d) {\n            current_to[ri][rj][d] = rot_to[initial_type[ri][rj]][new_r][d];\n        }\n\n        int next_L1, next_L2;\n        long long next_score = get_score(next_L1, next_L2);\n\n        if (next_score >= current_score) {\n            current_score = next_score;\n            L1 = next_L1; L2 = next_L2;\n        } else {\n            // Simple Hill Climbing. For higher rank, use Simulated Annealing.\n            // Given the 20ms time limit, let's stick to Hill Climbing.\n            current_rot[ri][rj] = old_r;\n            for (int d = 0; d < 4; ++d) current_to[ri][rj][d] = backup_to[d];\n        }\n    }\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            cout << current_rot[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint N, T_limit;\nint board[10][10];\nint target_board[10][10];\nbool fixed_cell[10][10];\nstruct Pos { int r, c; bool operator==(const Pos& o) const { return r == o.r && c == o.c; } bool operator!=(const Pos& o) const { return !(*this == o); } };\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; // U, D, L, R\nchar dchar[] = {'U', 'D', 'L', 'R'};\n\nbool check_match(int t1, int t2, int dir) {\n    if (dir == 0) return (t1 & 8) && (t2 & 2); // U: t1 is (r,c), t2 is (r-1,c). t1 has U(2), t2 has D(8)\n    if (dir == 1) return (t1 & 2) && (t2 & 8); // D: t1 is (r,c), t2 is (r+1,c). t1 has D(8), t2 has U(2)\n    if (dir == 2) return (t1 & 1) && (t2 & 4); // L: t1 is (r,c), t2 is (r,c-1). t1 has L(1), t2 has R(4)\n    if (dir == 3) return (t1 & 4) && (t2 & 1); // R: t1 is (r,c), t2 is (r,c+1). t1 has R(4), t2 has L(1)\n    return false;\n}\n\n// The dir above is based on: if we move the tile from (r+dr, c+dc) to (r, c).\n// If dir=0 (Up), the tile at (r+1, c) moves to (r, c).\n// Let's just use the directions as: U means tile at (r+1, c) moves to (r, c).\n// D means tile at (r-1, c) moves to (r, c).\n// L means tile at (r, c+1) moves to (r, c).\n// R means tile at (r, c-1) moves to (r, c).\n\nint get_tile_dir(Pos from, Pos to) {\n    if (from.r == to.r + 1 && from.c == to.c) return 0; // Tile moves Up\n    if (from.r == to.r - 1 && from.c == to.c) return 1; // Tile moves Down\n    if (from.c == to.c + 1 && from.r == to.r) return 2; // Tile moves Left\n    if (from.c == to.c - 1 && from.r == to.r) return 3; // Tile moves Right\n    return -1;\n}\n\nint main() {\n    if (!(cin >> N >> T_limit)) return 0;\n    Pos empty_pos;\n    vector<int> all_tiles;\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) {\n            int val = stoi(s, nullptr, 16);\n            if (val == 0) empty_pos = {i, j};\n            else all_tiles.push_back(val);\n            board[i][j] = (val == 0 ? 0 : val);\n            target_board[i][j] = -1;\n        }\n    }\n\n    mt19937 rng(time(0));\n    vector<pair<Pos, Pos>> tree_edges;\n    vector<Pos> bfs_order;\n    while (true) {\n        tree_edges.clear(); bfs_order.clear();\n        vector<pair<Pos, Pos>> all_possible_edges;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (i == N - 1 && j == N - 1) continue;\n            if (i + 1 < N && !(i + 1 == N - 1 && j == N - 1)) all_possible_edges.push_back({{i, j}, {i + 1, j}});\n            if (j + 1 < N && !(i == N - 1 && j + 1 == N - 1)) all_possible_edges.push_back({{i, j}, {i, j + 1}});\n        }\n        shuffle(all_possible_edges.begin(), all_possible_edges.end(), rng);\n        vector<int> parent(N * N); for (int i = 0; i < N * N; ++i) parent[i] = i;\n        auto find = [&](auto self, int i) -> int { return parent[i] == i ? i : parent[i] = self(self, parent[i]); };\n        for (auto& e : all_possible_edges) {\n            int r1 = find(find, e.first.r * N + e.first.c), r2 = find(find, e.second.r * N + e.second.c);\n            if (r1 != r2) { parent[r1] = r2; tree_edges.push_back(e); }\n        }\n        bfs_order.push_back({0, 0});\n        vector<bool> visited(N * N, false); visited[0] = true;\n        queue<Pos> q; q.push({0, 0});\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = u.r + dr[i], nc = u.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !(nr == N - 1 && nc == N - 1) && !visited[nr * N + nc]) {\n                    visited[nr * N + nc] = true; bfs_order.push_back({nr, nc}); q.push({nr, nc});\n                }\n            }\n        }\n        auto backtrack = [&](auto self, int idx, vector<int>& used) -> bool {\n            if (idx == N * N - 1) return true;\n            Pos u = bfs_order[idx];\n            for (int i = 0; i < (int)all_tiles.size(); ++i) {\n                if (used[i]) continue;\n                int tile = all_tiles[i];\n                bool ok = true;\n                for (auto& edge : tree_edges) {\n                    if ((edge.first == u || edge.second == u)) {\n                        Pos other = (edge.first == u) ? edge.second : edge.first;\n                        if (target_board[other.r][other.c] != -1) {\n                            if (!check_match(tile, target_board[other.r][other.c], get_tile_dir(u, other))) { ok = false; break; }\n                        }\n                    }\n                }\n                if (ok) {\n                    target_board[u.r][u.c] = tile; used[i] = 1;\n                    if (self(self, idx + 1, used)) return true;\n                    used[i] = 0; target_board[u.r][u.c] = -1;\n                }\n            }\n            return false;\n        };\n        vector<int> used(all_tiles.size(), 0);\n        if (backtrack(backtrack, 0, used)) break;\n    }\n\n    vector<Pos> order;\n    for (int i = 0; i < N - 1; ++i) for (int j = 0; j < N; ++j) order.push_back({i, j});\n    for (int j = 0; j < N - 1; ++j) order.push_back({N - 1, j});\n\n    string res = \"\";\n    Pos cur_e = empty_pos;\n    for (auto p : order) {\n        int tr = -1, tc = -1;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (board[i][j] == target_board[p.r][p.c] && !fixed_cell[i][j]) { tr = i; tc = j; break; }\n        }\n        if (tr == p.r && tc == p.c) { fixed_cell[p.r][p.c] = true; continue; }\n\n        auto bfs_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            while (!q.empty()) {\n                auto [curr, path] = q.front(); q.pop();\n                if (curr == target) {\n                    res += path; cur_e = target;\n                    for (char c : path) {\n                        // To keep board in sync, we simulate. But easier to just swap.\n                    }\n                    return;\n                }\n                for (int i = 0; i < 4; ++i) {\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !v[nr][nc]) {\n                        v[nr][nc] = true;\n                        // If empty moves from (nr,nc) to (curr.r, curr.c), tile moves from (curr.r, curr.c) to (nr,nc)\n                        // The direction is the direction the TILE moves.\n                        // If empty moves (nr,nc) -> (curr.r, curr.c), tile moves (curr.r, curr.c) -> (nr,nc).\n                        // If nr = curr.r-1, tile moves Down. If nr = curr.r+1, tile moves Up.\n                        // If nc = curr.c-1, tile moves Right. If nc = curr.c+1, tile moves Left.\n                        char move_char;\n                        if (nr == curr.r - 1) move_char = 'D';\n                        else if (nr == curr.r + 1) move_char = 'U';\n                        else if (nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n        \n        // Correcting move: BFS to move empty to (tr, tc)\n        // But we must not move through the tile we are trying to move!\n        // No, we move the empty to (tr,tc) then to (p.r, p.c)? \n        // Let's do: 1. Move empty to (tr, tc) 2. Move empty to (p.r, p.c)\n        // Actually, to move tile from (tr,tc) to (p.r,p.c):\n        // Step 1: Move empty square to (p.r, p.c). Step 2: Move empty square to (tr, tc).\n        // Then the tile at (tr,tc) will be at (p.r, p.c).\n        \n        // Let's re-implement the BFS more simply.\n        auto move_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            // To move a tile to (p.r, p.c), we shouldn't let the empty square pass through (p.r, p.c)\n            // EXCEPT when it's the final step. But it's easier to say:\n            // During BFS, the empty square cannot pass through ANY fixed cell.\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply the moves to the board\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int nr = temp_e.r, nc = temp_e.c;\n                        int tr_idx = -1;\n                        if(c == 'U') tr_idx = 1; else if(c == 'D') tr_idx = 0;\n                        else if(c == 'L') tr_idx = 3; else tr_idx = 2;\n                        // Wait, the directions are for the TILE.\n                        // If tile moves Up, empty moves Down.\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char move_char;\n                        if(nr == curr.r - 1) move_char = 'D';\n                        else if(nr == curr.r + 1) move_char = 'U';\n                        else if(nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n\n        // 1. Move empty to (p.r, p.c)\n        // But we must avoid (tr, tc) during this, because it's the tile we want.\n        // Wait, the empty square can move through (tr, tc) if it's not fixed!\n        // Let's just move empty to (p.r, p.c) then to (tr, tc).\n        // Wait, the order is:\n        // 1. Move empty square to (p.r, p.c)\n        // 2. Move empty square to (tr, tc)\n        // Now the tile that was at (tr, tc) is at (p.r, p.c).\n        \n        // We'll use a slightly different approach: move empty to (tr, tc) and then to (p.r, p.c).\n        // Actually, the simplest: move empty to (p.r, p.c), then to (tr, tc).\n        // Let's use a modified BFS that avoids (tr, tc) if we are moving to (p.r, p.c).\n        // Wait, the current tile is at (tr, tc). The empty square should move to (p.r, p.c) \n        // without using (tr, tc) as an intermediate.\n        \n        // BFS to move empty to (p.r, p.c), avoiding (tr, tc) and all fixed cells.\n        auto bfs_with_avoid = [&](Pos target, Pos avoid) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            if(avoid.r != -1) v[avoid.r][avoid.c] = true;\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply moves\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char m;\n                        if(nr == curr.r - 1) m = 'D'; else if(nr == curr.r + 1) m = 'U';\n                        else if(nc == curr.c - 1) m = 'R'; else m = 'L';\n                        q.push({{nr, nc}, path + m});\n                    }\n                }\n            }\n        };\n\n        bfs_with_avoid(p, {tr, tc});\n        bfs_with_avoid({tr, tc}, {-1, -1});\n        fixed_cell[p.r][p.c] = true;\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <map>\n#include <unordered_map>\n\nusing namespace std;\n\ntypedef __int128_t int128;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long a, b, c;\n    long long px, py, qx, qy;\n};\n\nstruct Signature {\n    uint64_t low, high;\n    bool operator<(const Signature& other) const {\n        if (low != other.low) return low < other.low;\n        return high < other.high;\n    }\n    bool operator==(const Signature& other) const {\n        return low == other.low && high == other.high;\n    }\n};\n\nstruct SignatureHash {\n    size_t operator()(const Signature& s) const {\n        return s.low ^ (s.high + 0x9e3779b9 + (s.low << 6) + (s.low >> 2));\n    }\n};\n\nstruct SigBitset {\n    uint64_t low, high;\n    void set_bit(int idx) {\n        if (idx < 64) low |= (1ULL << idx);\n        else high |= (1ULL << (idx - 64));\n    }\n    void reset_bit(int idx) {\n        if (idx < 64) low &= ~(1ULL << idx);\n        else high &= ~(1ULL << (idx - 64));\n    }\n    Signature to_signature() const {\n        return {low, high};\n    }\n};\n\nint N, K;\nint a[11];\nPoint strawberries[5505];\nLine lines[105];\nSigBitset sigs[5505];\nint on_count[5505];\n\nLine make_line(long long px, long long py, long long qx, long long qy) {\n    Line l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = qy - py;\n    l.b = px - qx;\n    l.c = (int128)px * qy - (int128)qx * py; // Need to be careful about precision here, but int128 is ok.\n    // Wait, the line equation is (qy-py)x - (qx-px)y + (pxqy - qxpy) = 0\n    // So a = qy-py, b = -(qx-px) = px-qx, c = pxqy - qxpy.\n    // Let's re-calculate to be more robust.\n    return l;\n}\n\n// Since c can be very large, we use __int128 for it.\n// Let's change the Line struct.\nstruct RobustLine {\n    int128 a, b, c;\n    long long px, py, qx, qy;\n};\n\nRobustLine make_robust_line(long long px, long long py, long long qx, long long qy) {\n    RobustLine l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = (int128)qy - py;\n    l.b = (int128)px - qx;\n    l.c = (int128)px * qy - (int128)qx * py;\n    return l;\n}\n\nRobustLine robust_lines[105];\n\nint calculate_score() {\n    unordered_map<Signature, int, SignatureHash> counts;\n    for (int i = 0; i < N; ++i) {\n        if (on_count[i] == 0) {\n            counts[sigs[i].to_signature()]++;\n        }\n    }\n    int b[11] = {0};\n    for (auto const& [sig, count] : counts) {\n        if (count <= 10) b[count]++;\n    }\n    int total = 0;\n    for (int d = 1; d <= 10; ++d) {\n        total += min(a[d], b[d]);\n    }\n    return total;\n}\n\nvoid update_line(int idx, RobustLine new_line) {\n    for (int i = 0; i < N; ++i) {\n        int128 val_old = robust_lines[idx].a * strawberries[i].x + robust_lines[idx].b * strawberries[i].y + robust_lines[idx].c;\n        if (val_old == 0) {\n            on_count[i]--;\n        } else {\n            // Bit was already set based on val_old.\n        }\n\n        int128 val_new = new_line.a * strawberries[i].x + new_line.b * strawberries[i].y + new_line.c;\n        if (val_new == 0) {\n            on_count[i]++;\n        } else {\n            if (val_new > 0) sigs[i].set_bit(idx);\n            else sigs[i].reset_bit(idx);\n        }\n    }\n    robust_lines[idx] = new_line;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> K)) return 0;\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    for (int i = 0; i < N; ++i) cin >> strawberries[i].x >> strawberries[i].y;\n\n    mt19937 rng(1337);\n    uniform_int_distribution<long long> dist_coord(-10000, 10000);\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    uniform_int_distribution<int> dist_K(0, K - 1);\n\n    // Dummy line\n    robust_lines[0] = make_robust_line(0, 1000000000, 1, 1000000000); \n    // Wait, the dummy line above is a bit invalid (a=0, b=-1, c=-10^9)\n    // Let's use a more standard dummy: y = -10^9\n    robust_lines[0] = make_robust_line(0, -1000000000, 1, -1000000000);\n    for (int i = 0; i < K; ++i) {\n        robust_lines[i] = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        // Re-initialize sigs and on_count\n    }\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        // Actually we need to initialize sigs and on_count properly\n        // Let's just set everything to 0 then update each line one by one.\n    }\n    // Correct initialization:\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        RobustLine rl = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        update_line(i, rl);\n    }\n\n    int current_score = calculate_score();\n    int best_score = current_score;\n    vector<RobustLine> best_lines(robust_lines, robust_lines + K);\n\n    auto start_time = chrono::steady_clock::now();\n    double T = 1.0;\n    double factor = 0.99995;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 127) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2800) break;\n        }\n        iter++;\n\n        int idx = dist_K(rng);\n        RobustLine old_line = robust_lines[idx];\n        RobustLine new_line;\n        \n        if (rng() % 10 < 7) {\n            new_line = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        } else {\n            int s1 = dist_idx(rng);\n            int s2 = dist_idx(rng);\n            if (s1 == s2) {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s1].x + 1, strawberries[s1].y + 1);\n            } else {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s2].x + (rng() % 3 - 1), strawberries[s2].y + (rng() % 3 - 1));\n            }\n        }\n\n        update_line(idx, new_line);\n        int new_score = calculate_score();\n\n        if (new_score >= current_score || (exp((new_score - current_score) / T) > (double)rng() / mt19937::max())) {\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < K; ++i) best_lines[i] = robust_lines[i];\n            }\n        } else {\n            update_line(idx, old_line);\n        }\n        T *= factor;\n    }\n\n    cout << K << \"\\n\";\n    for (int i = 0; i < K; ++i) {\n        cout << best_lines[i].px << \" \" << best_lines[i].py << \" \" << best_lines[i].qx << \" \" << best_lines[i].qy << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The goal is to maximize the sum of weights of dots placed on an N x N grid.\n * The weight of each point (x, y) is (x-c)^2 + (y-c)^2 + 1, where c is the center of the grid.\n * This means we want to place as many dots as possible, especially those far from the center.\n * We can place a new dot by forming a rectangle (axis-aligned or 45-degree inclined) \n * using three existing dots as corners.\n * \n * STRATEGY:\n * A greedy approach should work well here. In each step, find all possible valid \n * rectangles that can be formed and select the one that adds the point with \n * the highest weight.\n * \n * VALIDITY CONDITIONS:\n * 1. A new dot p1 must not currently have a dot.\n * 2. Three other corners (p2, p3, p4) must have dots.\n * 3. No other dots on the rectangle's perimeter.\n * 4. The perimeter must not share a common segment with any existing rectangle.\n * \n * ALGORITHM COMPLEXITY:\n * The number of existing dots M is up to N^2.\n * Searching for rectangles by iterating through all pairs (p2, p3) of existing dots \n * takes O(M^2) per step. \n * Total complexity across all steps is approximately O(N^5), which fits within the 5-second limit.\n */\n\nstruct Point {\n    int x, y;\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nint N, M;\nbool is_dot[65][65];\nbool used_h[65][65];   // used_h[x][y] represents segment (x, y) to (x+1, y)\nbool used_v[65][65];   // used_v[x][y] represents segment (x, y) to (x, y+1)\nbool used_d1[65][65];  // used_d1[x][y] represents segment (x, y) to (x+1, y+1)\nbool used_d2[65][65];  // used_d2[x][y] represents segment (x, y) to (x+1, y-1)\n\ndouble get_weight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1.0;\n}\n\nbool is_in_grid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Checks if any segment of the rectangle's perimeter is already used.\n// If check_and_use is true, it marks these segments as used.\nbool check_segments(const vector<Point>& rect, bool check_and_use) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x, cur_y = start.y;\n        while (cur_x != end.x || cur_y != end.y) {\n            int next_x = cur_x + dx;\n            int next_y = cur_y + dy;\n            if (dx != 0 && dy == 0) { // Horizontal\n                int min_x = min(cur_x, next_x);\n                if (used_h[min_x][cur_y]) return false;\n                if (check_and_use) used_h[min_x][cur_y] = true;\n            } else if (dx == 0 && dy != 0) { // Vertical\n                int min_y = min(cur_y, next_y);\n                if (used_v[cur_x][min_y]) return false;\n                if (check_and_use) used_v[cur_x][min_y] = true;\n            } else if (dx == 1 && dy == 1) { // Diag 1 (up-right)\n                int min_x = cur_x, min_y = cur_y;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == -1) { // Diag 1 (down-left)\n                int min_x = cur_x - 1, min_y = cur_y - 1;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == 1) { // Diag 2 (up-left)\n                int min_x = cur_x - 1, min_y = cur_y;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            } else if (dx == 1 && dy == -1) { // Diag 2 (down-right)\n                int min_x = cur_x, min_y = cur_y - 1;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            }\n            cur_x = next_x; cur_y = next_y;\n        }\n    }\n    return true;\n}\n\n// Checks if any other dots (not among the rectangle's corners p2, p3, p4) are on the perimeter.\nbool check_no_other_dots(const vector<Point>& rect) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x + dx, cur_y = start.y + dy;\n        while (cur_x != end.x || cur_y != end.y) {\n            if (is_dot[cur_x][cur_y]) {\n                bool is_corner = false;\n                for (int j = 1; j < 4; ++j) { // p2, p3, p4 are corners rect[1], rect[2], rect[3]\n                    if (cur_x == rect[j].x && cur_y == rect[j].y) is_corner = true;\n                }\n                if (!is_corner) return false;\n            }\n            cur_x += dx; cur_y += dy;\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M)) return 0;\n    vector<Point> dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        is_dot[x][y] = true;\n        dots.push_back({x, y});\n    }\n\n    vector<vector<Point>> operations;\n\n    while (true) {\n        double best_val = -1;\n        vector<Point> best_rect;\n\n        for (int i = 0; i < (int)dots.size(); ++i) {\n            for (int j = i + 1; j < (int)dots.size(); ++j) {\n                Point p2 = dots[i];\n                Point p3 = dots[j];\n\n                // Axis-aligned rectangle search\n                if (p2.x != p3.x && p2.y != p3.y) {\n                    // Two potential cases: p2 and p3 are opposite corners.\n                    // The other two corners are (p2.x, p3.y) and (p3.x, p2.y).\n                    // One of these must be the new dot p1, the other must be an existing dot p4.\n                    Point corners[2] = {{p2.x, p3.y}, {p3.x, p2.y}};\n                    for (int k = 0; k < 2; ++k) {\n                        Point p1 = corners[k];\n                        Point p4 = corners[1 - k];\n                        if (is_in_grid(p1.x, p1.y) && is_in_grid(p4.x, p4.y)) {\n                            if (!is_dot[p1.x][p1.y] && is_dot[p4.x][p4.y]) {\n                                vector<Point> rect = {p1, p2, p3, p4};\n                                if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                    double val = get_weight(p1.x, p1.y);\n                                    if (val > best_val) {\n                                        best_val = val;\n                                        best_rect = rect;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // 45-degree rectangle search\n                int dx = p3.x - p2.x;\n                int dy = p3.y - p2.y;\n                if ((dx + dy) % 2 == 0) {\n                    // For 45-degree rectangles, the center of the diagonal p2-p3 is a corner of the grid-dual.\n                    // Use geometric properties to find p1 and p4.\n                    int x12 = p2.x + p3.x + p2.y - p3.y;\n                    int y12 = p2.y + p3.y + p3.x - p2.x;\n                    if (x12 % 2 == 0 && y12 % 2 == 0) {\n                        Point p1_cand = {x12 / 2, y12 / 2};\n                        int x42 = p2.x + p3.x - p2.y + p3.y;\n                        int y42 = p2.y + p3.y - p3.x + p2.x;\n                        if (x42 % 2 == 0 && y42 % 2 == 0) {\n                            Point p4_cand = {x42 / 2, y42 / 2};\n                            if (is_in_grid(p1_cand.x, p1_cand.y) && is_in_grid(p4_cand.x, p4_cand.y)) {\n                                // p1_cand could be p1 (the new dot) and p4_cand could be p4 (an existing dot)\n                                if (!is_dot[p1_cand.x][p1_cand.y] && is_dot[p4_cand.x][p4_cand.y]) {\n                                    vector<Point> rect = {p1_cand, p2, p3, p4_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p1_cand.x, p1_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                                // Or vice versa\n                                if (!is_dot[p4_cand.x][p4_cand.y] && is_dot[p1_cand.x][p1_cand.y]) {\n                                    vector<Point> rect = {p4_cand, p2, p3, p1_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p4_cand.x, p4_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_val > 0) {\n            is_dot[best_rect[0].x][best_rect[0].y] = true;\n            dots.push_back(best_rect[0]);\n            check_segments(best_rect, true); // Commit segments as used\n            operations.push_back(best_rect);\n        } else {\n            break;\n        }\n    }\n\n    // Output results\n    cout << operations.size() << \"\\n\";\n    for (const auto& rect : operations) {\n        cout << rect[0].x << \" \" << rect[0].y << \" \"\n             << rect[1].x << \" \" << rect[1].y << \" \"\n             << rect[2].x << \" \" << rect[2].y << \" \"\n             << rect[3].x << \" \" << rect[3].y << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global grid and flavors to store current state and input\nint grid[10][10];\nint flavors[100];\n\nstruct Point {\n    int r, c;\n};\n\n// Directions for adjacency\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n/**\n * Calculates the connectivity score (sum of n_i^2) for the current grid.\n * n_i is the size of the i-th connected component of the same flavor.\n */\nint calculate_score(int current_grid[10][10]) {\n    bool visited[10][10] = {false};\n    int total_score = 0;\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (current_grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = current_grid[r][c];\n                int size = 0;\n                queue<Point> q;\n                q.push({r, c});\n                visited[r][c] = true;\n                while (!q.empty()) {\n                    Point curr = q.front();\n                    q.pop();\n                    size++;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = curr.r + dr[i];\n                        int nc = curr.c + dc[i];\n                        if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 &&\n                            !visited[nr][nc] && current_grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n/**\n * Simulates the effect of tilting the box in a given direction.\n * F: Front (r decreases), B: Backward (r increases), L: Left (c decreases), R: Right (c increases)\n */\nvoid simulate_tilt(int current_grid[10][10], char dir, int next_grid[10][10]) {\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            next_grid[i][j] = 0;\n\n    if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 0; r < 10; ++r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 9; r >= 0; --r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[9 - count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 0; c < 10; ++c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][count++] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 9; c >= 0; --c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][9 - count++] = current_grid[r][c];\n                }\n            }\n        }\n    }\n}\n\n/**\n * Applies the selected tilt to the current grid.\n */\nvoid apply_tilt(int current_grid[10][10], char dir) {\n    int next_grid[10][10];\n    simulate_tilt(current_grid, dir, next_grid);\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            current_grid[i][j] = next_grid[i][j];\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read the flavors of the 100 candies\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    // Initialize the grid as empty\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            grid[i][j] = 0;\n\n    char directions[] = {'F', 'B', 'L', 'R'};\n\n    // Process each of the 100 candies\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        if (!(cin >> p_t)) break;\n\n        // Locate the p_t-th empty cell (1-indexed)\n        vector<Point> empty_cells;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    empty_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // Place the t-th candy in the determined cell\n        Point pos = empty_cells[p_t - 1];\n        grid[pos.r][pos.c] = flavors[t - 1];\n\n        // Greedy strategy: choose the tilt direction that maximizes the current score\n        int best_score = -1;\n        char best_dir = 'F';\n\n        for (char d : directions) {\n            int next_grid_temp[10][10];\n            simulate_tilt(grid, d, next_grid_temp);\n            int score = calculate_score(next_grid_temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        // Output the chosen direction and flush\n        cout << best_dir << endl;\n        // Apply the move to the actual grid state\n        apply_tilt(grid, best_dir);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis and Improvement Strategy:\n * \n * 1. Insight from Feedback:\n *    The previous score was relatively high but had many failures. The primary \n *    weakness was likely the susceptibility of the clique-based encoding to vertex\n *    shuffling and noise when epsilon is high, or being stuck in local minima \n *    during the permutation search.\n * \n * 2. Encoding Strategy:\n *    Keep the clique-based encoding with N=100. For each index i (0 to M-1), \n *    the graph G_i is a clique of size k = i+1. This maximizes the distinctness \n *    of edge counts and degree distributions.\n * \n * 3. Decoding Strategy (Prediction):\n *    - Candidate Selection: Instead of checking all M, use the edge count of the \n *      received graph H to select the top 35 most likely candidate graphs G_i.\n *    - Permutation Initialization: Use the degree distribution. Sort the \n *      degrees of H and G_i and create an initial permutation P mapping \n *      H's vertices to G_i's vertices.\n *    - Local Search: Use a Hill Climbing approach with many iterations \n *      (1500 iterations per candidate). To avoid local minima, allow \n *      swaps that result in zero change in mismatch count (delta <= 0).\n * \n * 4. Optimization:\n *    - Use a flat 1D array for G_adj to improve cache locality.\n *    - Use a pre-calculated degree array for all G_i.\n *    - Implement a time-limited search to ensure the program runs within the 5s limit.\n *    - The delta calculation in the local search is optimized to O(N) per iteration.\n * \n * 5. Complexity:\n *    Total complexity is approximately O(Queries * Candidates * Iterations * N).\n *    100 * 35 * 1500 * 100 = 5.25 * 10^8 operations, which fits within 5 seconds.\n */\n\n// Global arrays to fit into memory and avoid reallocation\nunsigned char G_adj[100 * 100 * 100]; // G_adj[i][u][v] flattened\nbool H_adj[100][100];\nint Gi_edges[100];\nint G_deg[100][100];\n\nint main() {\n    // Fast I/O setup\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double epsilon;\n    if (!(cin >> M >> epsilon)) return 0;\n\n    const int N = 100;\n    const int L = N * (N - 1) / 2;\n\n    // Encoding step\n    for (int i = 0; i < M; ++i) {\n        int k = i + 1; // Clique size\n        Gi_edges[i] = k * (k - 1) / 2;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (u < k && v < k && u != v) {\n                    G_adj[i * 10000 + u * 100 + v] = 1;\n                } else {\n                    G_adj[i * 10000 + u * 100 + v] = 0;\n                }\n            }\n        }\n    }\n\n    // Pre-calculate degrees for all encoded graphs\n    for (int i = 0; i < M; ++i) {\n        for (int u = 0; u < N; ++u) {\n            int d = 0;\n            for (int v = 0; v < N; ++v) {\n                if (G_adj[i * 10000 + u * 100 + v]) d++;\n            }\n            G_deg[i][u] = d;\n        }\n    }\n\n    // Output encoding\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        string s = \"\";\n        s.reserve(L);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s += (G_adj[i * 10000 + u * 100 + v] ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    mt19937 rng(42);\n    auto start_total = chrono::steady_clock::now();\n\n    // Query processing\n    for (int q = 0; q < 100; ++q) {\n        string H_str;\n        if (!(cin >> H_str)) break;\n\n        int h_edges = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) H_adj[u][v] = false;\n        }\n        int idx = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (H_str[idx++] == '1') {\n                    H_adj[u][v] = H_adj[v][u] = true;\n                    h_edges++;\n                }\n            }\n        }\n\n        // Degree distribution of H\n        vector<int> H_deg(N, 0);\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (H_adj[u][v]) H_deg[u]++;\n            }\n        }\n\n        // Select candidates based on expected edge counts\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < M; ++i) {\n            double expected_h_edges = (double)Gi_edges[i] * (1.0 - 2.0 * epsilon) + (double)L * epsilon;\n            candidates.push_back({abs((double)h_edges - expected_h_edges), i});\n        }\n        sort(candidates.begin(), candidates.end());\n\n        int best_i = 0;\n        int min_mismatches = 2e9;\n\n        // Iterate through candidates\n        for (int c = 0; c < min(M, 35); ++c) {\n            int i = candidates[c].second;\n\n            // Initialize permutation by sorting degrees\n            vector<int> H_idx(N), G_idx(N);\n            for (int j = 0; j < N; ++j) {\n                H_idx[j] = j;\n                G_idx[j] = j;\n            }\n            sort(H_idx.begin(), H_idx.end(), [&](int a, int b) { return H_deg[a] < H_deg[b]; });\n            sort(G_idx.begin(), G_idx.end(), [&](int a, int b) { return G_deg[i][a] < G_deg[i][b]; });\n\n            vector<int> P(N);\n            for (int j = 0; j < N; ++j) P[H_idx[j]] = G_idx[j];\n\n            // Initial mismatch count\n            int cur_mismatches = 0;\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (G_adj[i * 10000 + P[u] * 100 + P[v]] != H_adj[u][v]) cur_mismatches++;\n                }\n            }\n\n            // Hill Climbing optimization\n            for (int iter = 0; iter < 1500; ++iter) {\n                int u = rng() % N;\n                int v = rng() % N;\n                if (u == v) continue;\n\n                // Compute delta in O(N)\n                int delta = 0;\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    // Calculate old and new mismatch contributions for edges (u, k) and (v, k)\n                    int old_uk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[u][k]);\n                    int old_vk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[v][k]);\n                    int new_uk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[u][k]);\n                    int new_vk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[v][k]);\n                    delta += (new_uk + new_vk) - (old_uk + old_vk);\n                }\n\n                // Accept swap if it improves or maintains mismatch count\n                if (delta <= 0) {\n                    cur_mismatches += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n\n            if (cur_mismatches < min_mismatches) {\n                min_mismatches = cur_mismatches;\n                best_i = i;\n            }\n            \n            // Periodic check to avoid TLE\n            if (c % 10 == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration_cast<chrono::milliseconds>(now - start_total).count() > 4700) break;\n            }\n        }\n\n        // Predict and output\n        cout << best_i << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Problem: Minimize the average frustration level caused by repairing roads over D days.\n * Each day, at most K edges can be repaired.\n * Frustration level f_k is the expected increase in shortest distances when edges of day k are removed.\n * \n * Strategy:\n * 1. The objective is to minimize the sum of f_k over all days.\n * 2. f_k depends only on the set of edges repaired on day k.\n * 3. Each edge's contribution to frustration can be estimated by how many shortest paths pass through it.\n * 4. An edge e=(u,v) with weight w is likely to increase distances by at least w if it's on a shortest path.\n * 5. We calculate an impact score for each edge: I(e) = edge_count[e] * weight[e],\n *    where edge_count[e] is the number of (i, j) pairs such that e is on the chosen shortest path from i to j.\n * 6. We sort edges by their impact score in descending order and distribute them across D days\n *    using a round-robin approach to spread out the most \"impactful\" edges.\n * 7. This ensures that no single day carries too many critical edges, thereby minimizing f_k.\n */\n\nconst long long INF = 1e18;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct AdjEdge {\n    int to, w, id;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w, i});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w, i});\n    }\n\n    // Read and skip coordinates (not needed for our strategy)\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // edge_count[i] will store how many shortest paths (for all starting vertices) pass through edge i\n    vector<long long> edge_count(M, 0);\n\n    // Calculate edge_count using Dijkstra and DAG-based counting\n    // Total complexity: O(N * (M + N log N))\n    for (int start = 1; start <= N; ++start) {\n        vector<long long> dist(N + 1, INF);\n        vector<int> parent_node(N + 1, -1);\n        vector<int> parent_edge(N + 1, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n\n        dist[start] = 0;\n        pq.push({0, start});\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& e : adj[u]) {\n                if (dist[e.to] > dist[u] + e.w) {\n                    dist[e.to] = dist[u] + e.w;\n                    parent_node[e.to] = u;\n                    parent_edge[e.to] = e.id;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n\n        // Sort nodes by distance in descending order to propagate counts up the shortest path DAG\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 1);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n\n        // node_count[u] is the number of reachable nodes from 'start' via paths passing through u\n        vector<long long> node_count(N + 1, 1);\n        for (int u : nodes) {\n            if (u != start && parent_edge[u] != -1) {\n                int p = parent_node[u];\n                int id = parent_edge[u];\n                edge_count[id] += node_count[u];\n                node_count[p] += node_count[u];\n            }\n        }\n    }\n\n    // Create an array of edge indices and sort them by the calculated impact score\n    vector<int> edge_indices(M);\n    iota(edge_indices.begin(), edge_indices.end(), 0);\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        // Heuristic impact: (count of shortest paths) * (weight of the edge)\n        return (long long)edge_count[a] * edges[a].w > (long long)edge_count[b] * edges[b].w;\n    });\n\n    // Distribute edges across D days using round-robin to balance the impact\n    vector<int> assignment(M);\n    int current_day = 0;\n    for (int idx : edge_indices) {\n        assignment[idx] = current_day + 1;\n        current_day = (current_day + 1) % D;\n    }\n\n    // Output the assigned day for each edge\n    for (int i = 0; i < M; ++i) {\n        cout << assignment[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem: AHC019 - Silhouette\n * \n * Analysis:\n * We are given two pairs of 2D silhouettes (front and right) for two 3D objects.\n * We need to construct a set of blocks such that the first set of silhouettes can be\n * formed by one subset of blocks, and the second set by another subset.\n * The score is minimized by using large blocks in both objects (as common blocks).\n * \n * Strategy:\n * 1. Identify the set of possible cubic regions (x, y, z) that satisfy the\n *    silhouette for object 1: S1 = {(x, y, z) | f1(z, x) == 1 and r1(z, y) == 1}.\n *    Similarly for S2.\n * 2. A cell (x, y, z) can be part of object 1 if and only if (x, y, z) is in S1.\n *    The set S1 itself satisfies the silhouette f1 and r1.\n * 3. To minimize the score, we maximize the volume of common blocks.\n *    The best common blocks are the connected components of S1 \u2229 S2.\n * 4. To avoid wasting blocks, we cover the remaining cells in S1 (those not in S2)\n *    and the remaining cells in S2 (those not in S1) with their own connected components.\n * 5. Each connected component becomes a single block. Since each block is a component,\n *    it is guaranteed to be connected. Since the components are derived from disjoint\n *    sets of cells (S_common, S_only1, S_only2), they do not overlap.\n * \n * Complexity:\n * O(D^3) time and memory, which is well within limits for D up to 14.\n */\n\nstruct Cell {\n    int x, y, z;\n};\n\nvoid find_components(const vector<vector<vector<bool>>>& S, int type, int D,\n                    vector<vector<vector<int>>>& b1, vector<vector<vector<int>>>& b2,\n                    int& block_id) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    static const int dx[] = {1, -1, 0, 0, 0, 0};\n    static const int dy[] = {0, 0, 1, -1, 0, 0};\n    static const int dz[] = {0, 0, 0, 0, 1, -1};\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S[x][y][z] && !visited[x][y][z]) {\n                    block_id++;\n                    queue<Cell> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    while (!q.empty()) {\n                        Cell curr = q.front();\n                        q.pop();\n                        \n                        if (type == 0) { // block in both objects\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 1) { // block in object 1 only\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 2) { // block in object 2 only\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        }\n\n                        for (int i = 0; i < 6; ++i) {\n                            int nx = curr.x + dx[i];\n                            int ny = curr.y + dy[i];\n                            int nz = curr.z + dz[i];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && \n                                S[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                visited[nx][ny][nz] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n    for (int i = 0; i < D; ++i) cin >> f2[i];\n    for (int i = 0; i < D; ++i) cin >> r2[i];\n\n    // Function to derive the set of valid cells from silhouette arrays\n    auto get_S = [&](const vector<string>& f, const vector<string>& r) {\n        vector<vector<vector<bool>>> S(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x) {\n                for (int y = 0; y < D; ++y) {\n                    if (f[z][x] == '1' && r[z][y] == '1') {\n                        S[x][y][z] = true;\n                    }\n                }\n            }\n        }\n        return S;\n    };\n\n    auto S1 = get_S(f1, r1);\n    auto S2 = get_S(f2, r2);\n\n    // Arrays to store the block ID at each location for each object\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int total_blocks = 0;\n\n    // Pre-calculating the three types of cell sets\n    vector<vector<vector<bool>>> S_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S1[x][y][z] && S2[x][y][z]) {\n                    S_common[x][y][z] = true;\n                } else if (S1[x][y][z]) {\n                    S_only1[x][y][z] = true;\n                } else if (S2[x][y][z]) {\n                    S_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Find all connected components in each of the three sets\n    find_components(S_common, 0, D, b1, b2, total_blocks);\n    find_components(S_only1, 1, D, b1, b2, total_blocks);\n    find_components(S_only2, 2, D, b1, b2, total_blocks);\n\n    // Output the results\n    cout << total_blocks << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b1[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b2[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize a cost function S = sum(P_i^2) + sum(w_j) where P_i is the output strength\n * of station i and w_j is the weight of an activated edge j. All residents must be covered.\n * A resident is covered if it's within distance P_i of some station i reachable from station 1.\n * \n * Algorithm:\n * 1. We use a Steiner Tree approximation approach to ensure connectivity and cover all residents.\n * 2. First, compute all-pairs shortest paths (APSP) using Floyd-Warshall.\n * 3. For each resident, identify its closest vertex in the entire graph. Let this set of vertices be V_target.\n * 4. Construct a metric closure of the graph using only vertices in V_target and find its Minimum Spanning Tree (MST).\n * 5. The union of the shortest paths corresponding to the MST edges forms our connected set of stations (V_prime) and cables (E_prime).\n * 6. For each resident, assign it to its closest vertex in V_prime and calculate the required P_i.\n * 7. Since all residents were within 5000 of some station, a valid configuration exists.\n */\n\nstruct Edge {\n    int u, v;\n    long long w;\n    int id;\n};\n\nstruct Resident {\n    int x, y;\n};\n\nstruct Station {\n    int x, y;\n};\n\nconst long long INF_LL = 1e18;\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n\n    vector<Edge> edges(M);\n    vector<vector<long long>> dist_matrix(N, vector<long long>(N, INF_LL));\n    vector<vector<int>> next_node(N, vector<int>(N, -1));\n    vector<vector<int>> adj_edge_idx(N, vector<int>(N, -1));\n\n    for (int i = 0; i < N; ++i) dist_matrix[i][i] = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        // Standard way to handle weights in adjacency matrices for Floyd-Warshall\n        if (w < dist_matrix[u][v]) {\n            dist_matrix[u][v] = dist_matrix[v][u] = w;\n            next_node[u][v] = v;\n            next_node[v][u] = u;\n            adj_edge_idx[u][v] = adj_edge_idx[v][u] = i;\n        }\n    }\n\n    vector<Resident> residents(K);\n    for (int i = 0; i < K; ++i) {\n        cin >> residents[i].x >> residents[i].y;\n    }\n\n    // Floyd-Warshall for All-Pairs Shortest Paths and reconstruction paths\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (dist_matrix[i][k] != INF_LL && dist_matrix[k][j] != INF_LL && \n                    dist_matrix[i][k] + dist_matrix[k][j] < dist_matrix[i][j]) {\n                    dist_matrix[i][j] = dist_matrix[i][k] + dist_matrix[k][j];\n                    next_node[i][j] = next_node[i][k];\n                }\n            }\n        }\n    }\n\n    // Determine the set of target vertices V_target\n    vector<int> V_target;\n    vector<bool> is_in_target(N, false);\n    V_target.push_back(0); // Station 1 is always a source\n    is_in_target[0] = true;\n\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_sq = 1e20;\n        for (int i = 0; i < N; ++i) {\n            double dx = (double)stations[i].x - residents[k].x;\n            double dy = (double)stations[i].y - residents[k].y;\n            double d2 = dx * dx + dy * dy;\n            if (d2 < min_dist_sq) {\n                min_dist_sq = d2;\n                best_i = i;\n            }\n        }\n        if (best_i != -1 && !is_in_target[best_i]) {\n            is_in_target[best_i] = true;\n            V_target.push_back(best_i);\n        }\n    }\n\n    // Calculate MST of the metric closure of V_target\n    int T_size = (int)V_target.size();\n    struct MSTEdge {\n        int u, v;\n        long long w;\n    };\n    vector<MSTEdge> mst_edges;\n    if (T_size > 1) {\n        // Prim's algorithm for MST on metric closure\n        vector<long long> min_dist_prim(T_size, INF_LL);\n        vector<int> parent(T_size, -1);\n        vector<bool> visited(T_size, false);\n        min_dist_prim[0] = 0;\n        for (int i = 0; i < T_size; ++i) {\n            int u_idx = -1;\n            for (int j = 0; j < T_size; ++j) {\n                if (!visited[j] && (u_idx == -1 || min_dist_prim[j] < min_dist_prim[u_idx])) {\n                    u_idx = j;\n                }\n            }\n            if (u_idx == -1 || min_dist_prim[u_idx] == INF_LL) break;\n            visited[u_idx] = true;\n            if (parent[u_idx] != -1) {\n                mst_edges.push_back({V_target[parent[u_idx]], V_target[u_idx], min_dist_prim[u_idx]});\n            }\n            for (int v_idx = 0; v_idx < T_size; ++v_idx) {\n                if (!visited[v_idx]) {\n                    long long weight_uv = dist_matrix[V_target[u_idx]][V_target[v_idx]];\n                    if (weight_uv < min_dist_prim[v_idx]) {\n                        min_dist_prim[v_idx] = weight_uv;\n                        parent[v_idx] = u_idx;\n                    }\n                }\n            }\n        }\n    }\n\n    // Reconstruct the connected subgraph V_prime and E_prime\n    vector<bool> is_in_prime(N, false);\n    is_in_prime[0] = true;\n    vector<int> B(M, 0);\n\n    for (auto& me : mst_edges) {\n        int u = me.u;\n        int v = me.v;\n        int curr = u;\n        while (curr != v) {\n            int nxt = next_node[curr][v];\n            if (nxt == -1) break;\n            int edge_idx = adj_edge_idx[curr][nxt];\n            if (edge_idx != -1) B[edge_idx] = 1;\n            is_in_prime[nxt] = true;\n            curr = nxt;\n        }\n        is_in_prime[u] = true;\n    }\n\n    // Determine minimal P_i for all i in V_prime to cover all residents\n    vector<int> P(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_val = 1e20;\n        for (int i = 0; i < N; ++i) {\n            if (is_in_prime[i]) {\n                double dx = (double)stations[i].x - residents[k].x;\n                double dy = (double)stations[i].y - residents[k].y;\n                double cur_dist = sqrt(dx * dx + dy * dy);\n                if (cur_dist < min_dist_val) {\n                    min_dist_val = cur_dist;\n                    best_i = i;\n                }\n            }\n        }\n        if (best_i != -1) {\n            // Use ceil to ensure coverage, subtracting epsilon for precision stability\n            int needed_radius = (int)ceil(min_dist_val - 1e-8);\n            if (needed_radius > P[best_i]) P[best_i] = needed_radius;\n        }\n    }\n\n    // Clamp P_i to maximum possible radius\n    for (int i = 0; i < N; ++i) {\n        if (P[i] > 5000) P[i] = 5000;\n    }\n\n    // Output P values\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    // Output B values\n    for (int i = 0; i < M; ++i) {\n        cout << B[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\n/**\n * Problem Analysis:\n * The problem asks to arrange balls in an N-tiered pyramid such that for every ball \n * at (x, y), its value is smaller than the values of its two children at (x+1, y) \n * and (x+1, y+1). This is exactly the min-heap property in a 2D triangular structure.\n * The allowed operation is swapping two adjacent balls in six directions. \n * Since the parent (x, y) and its children (x+1, y) and (x+1, y+1) are \n * already adjacent in the six specified directions, we can use the standard \n * \"heapify\" algorithm (sift-down approach) to satisfy the heap property.\n *\n * Heapify Algorithm:\n * Starting from the last non-leaf node (tier N-2 down to 0), we perform \n * a sift-down operation for each node. A sift-down operation swaps a node \n * with its smallest child if the node's value is larger than the smallest \n * child's value, and repeats this until the heap property is satisfied \n * for that node.\n *\n * Complexity:\n * The number of balls M = N(N+1)/2 = 465 for N = 30.\n * The heapify algorithm's worst-case number of swaps is roughly the sum \n * of the depths of all nodes, which for N=30 is at most 4495. \n * This is well within the 10,000 swap limit.\n * The time complexity is O(M), which is very efficient for the given constraints.\n *\n * Score Optimization:\n * A complete heap (E=0) will yield a score of 100000 - 5K.\n * Since K <= 4495, the minimum score will be at least 77525, \n * which is much higher than the maximum possible score for E > 0 (50000).\n */\n\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    // Speed up I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    vector<vector<int>> pyramid(N, vector<int>(N, 0));\n\n    // Read input: N-tiered pyramid\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> pyramid[i][j])) break;\n        }\n    }\n\n    vector<Swap> swaps;\n\n    // Build the min-heap using the sift-down (heapify) method\n    // Start from the second to last tier and move up to the top tier.\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int curX = x;\n            int curY = y;\n\n            // Sift down the ball at (curX, curY)\n            while (curX < N - 1) {\n                int childX = curX + 1;\n                int childY1 = curY;\n                int childY2 = curY + 1;\n\n                int smallestX = curX;\n                int smallestY = curY;\n                int minVal = pyramid[curX][curY];\n\n                // Compare with child 1: (curX+1, curY)\n                if (childX < N && childY1 <= childX) {\n                    if (pyramid[childX][childY1] < minVal) {\n                        minVal = pyramid[childX][childY1];\n                        smallestX = childX;\n                        smallestY = childY1;\n                    }\n                }\n                // Compare with child 2: (curX+1, curY+1)\n                if (childX < N && childY2 <= childX) {\n                    if (pyramid[childX][childY2] < minVal) {\n                        minVal = pyramid[childX][childY2];\n                        smallestX = childX;\n                        smallestY = childY2;\n                    }\n                }\n\n                // If the smallest of the current node and its children is one of the children, swap.\n                if (smallestX != curX) {\n                    swaps.push_back({curX, curY, smallestX, smallestY});\n                    swap(pyramid[curX][curY], pyramid[smallestX][smallestY]);\n                    // Continue sifting down the ball that was swapped up.\n                    curX = smallestX;\n                    curY = smallestY;\n                } else {\n                    // Heap property satisfied for this subtree.\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output the number of operations and the sequence of swaps.\n    cout << swaps.size() << \"\\n\";\n    for (const auto& s : swaps) {\n        cout << s.x1 << \" \" << s.y1 << \" \" << s.x2 << \" \" << s.y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to store containers such that they can be transported out in an order close to 0, 1, 2, ...\n * The primary constraint is that a container must be reachable from the entrance via empty squares.\n * During storage, \"empty\" means \"has not had a container placed in it yet\".\n * During transportation, \"empty\" means \"has had its container transported out already\".\n *\n * Strategy:\n * 1. Precompute a BFS order of all non-obstacle, non-entrance squares. Let this be v_0, v_1, ..., v_M.\n * 2. When container t_d arrives, try to place it in v_{t_d}. \n *    Check if v_{t_d} is reachable from the entrance using only currently empty (unoccupied) squares.\n *    If v_{t_d} is reachable, place it there.\n *    Otherwise, place it in the first available empty square in the BFS order that is reachable.\n * 3. Once all containers are stored, the transport phase begins. \n *    To minimize inversions, use a greedy strategy: at each step, pick the reachable container with the smallest ID.\n *    A container is reachable if it's adjacent to an empty square (initially only the entrance is empty).\n */\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint D, N;\nbool is_obstacle[9][9];\nbool is_occupied[9][9];\nPos square_of_id[81];\nint id_at_square[9][9];\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D && !is_obstacle[r][c];\n}\n\n// Checks if a square is reachable from the entrance through currently empty squares\nbool is_reachable(Pos target, Pos entrance) {\n    if (target == entrance) return true;\n    if (is_occupied[target.r][target.c]) return false;\n\n    queue<Pos> q;\n    q.push(entrance);\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    visited[entrance.r][entrance.c] = true;\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        if (curr == target) return true;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc) && !is_occupied[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                q.push({nr, nc});\n            }\n        }\n    }\n    // One more check: the target itself might be adjacent to an empty square\n    for (int i = 0; i < 4; ++i) {\n        int nr = target.r + dr[i];\n        int nc = target.c + dc[i];\n        if (nr == entrance.r && nc == entrance.c) return true;\n        if (is_valid(nr, nc) && !is_occupied[nr][nc] && visited[nr][nc]) return true;\n    }\n\n    return false;\n}\n\n// Alternative reachability: is target reachable if it is adjacent to an empty square that is reachable?\nbool is_reachable_final(Pos target, Pos entrance) {\n    queue<Pos> q;\n    q.push(entrance);\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    visited[entrance.r][entrance.c] = true;\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc)) {\n                if (nr == target.r && nc == target.c) return true;\n                if (!is_occupied[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n\n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            is_obstacle[i][j] = false;\n            is_occupied[i][j] = false;\n            id_at_square[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    Pos entrance = {0, (D - 1) / 2};\n    int total_containers = D * D - 1 - N;\n\n    // BFS order to define preferred squares\n    vector<Pos> bfs_order;\n    queue<Pos> q_bfs;\n    vector<vector<bool>> bfs_visited(D, vector<bool>(D, false));\n    q_bfs.push(entrance);\n    bfs_visited[entrance.r][entrance.c] = true;\n\n    while (!q_bfs.empty()) {\n        Pos curr = q_bfs.front();\n        q_bfs.pop();\n        if (!(curr == entrance)) bfs_order.push_back(curr);\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n            if (is_valid(nr, nc) && !bfs_visited[nr][nc]) {\n                bfs_visited[nr][nc] = true;\n                q_bfs.push({nr, nc});\n            }\n        }\n    }\n\n    for (int d = 0; d < total_containers; ++d) {\n        int t_d;\n        cin >> t_d;\n\n        Pos target = (t_d < (int)bfs_order.size()) ? bfs_order[t_d] : bfs_order.back();\n        \n        // If the preferred square isn't reachable, find the first reachable empty square in BFS order\n        if (!is_reachable_final(target, entrance)) {\n            bool found = false;\n            for (auto& p : bfs_order) {\n                if (!is_occupied[p.r][p.c] && is_reachable_final(p, entrance)) {\n                    target = p;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                // Fallback: just pick the first available valid square\n                for (auto& p : bfs_order) {\n                    if (!is_occupied[p.r][p.c]) {\n                        target = p;\n                        break;\n                    }\n                }\n            }\n        }\n\n        is_occupied[target.r][target.c] = true;\n        id_at_square[target.r][target.c] = t_d;\n        square_of_id[t_d] = target;\n        cout << target.r << \" \" << target.c << endl;\n    }\n\n    // Transport phase\n    vector<Pos> transport_order;\n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[entrance.r][entrance.c] = true;\n    \n    // Initially, only the entrance is empty\n    // A container is reachable if it's adjacent to an empty square\n    auto get_reachable_containers = [&]() {\n        vector<pair<int, Pos>> reachable;\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                if (id_at_square[r][c] != -1) {\n                    bool adj_to_empty = false;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r + dr[i], nc = c + dc[i];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && is_empty[nr][nc]) {\n                            adj_to_empty = true;\n                            break;\n                        }\n                    }\n                    if (adj_to_empty) {\n                        reachable.push_back({id_at_square[r][c], {r, c}});\n                    }\n                }\n            }\n        }\n        return reachable;\n    };\n\n    // Greedy transport: pick smallest ID among reachable\n    // Since the number of containers is small (up to 80), we can re-scan every time\n    vector<bool> transported(total_containers, false);\n    for (int i = 0; i < total_containers; ++i) {\n        int best_id = 1e9;\n        Pos best_pos = {-1, -1};\n\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                int id = id_at_square[r][c];\n                if (id != -1 && !transported[id]) {\n                    bool adj_to_empty = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = r + dr[k], nc = c + dc[k];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && is_empty[nr][nc]) {\n                            adj_to_empty = true;\n                            break;\n                        }\n                    }\n                    if (adj_to_empty && id < best_id) {\n                        best_id = id;\n                        best_pos = {r, c};\n                    }\n                }\n            }\n        }\n\n        if (best_id != 1e9) {\n            transported[best_id] = true;\n            is_empty[best_pos.r][best_pos.c] = true;\n            id_at_square[best_pos.r][best_pos.c] = -1; // Mark square as empty\n            transport_order.push_back(best_pos);\n        } else {\n            // If no container is reachable, there's an issue with the storage or path.\n            // In a real contest, we would need to handle this. For this problem, the BFS order\n            // and the logic should prevent this.\n            break;\n        }\n    }\n\n    for (auto& p : transport_order) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to represent a given adjacency graph of colors (wards) on an n x n grid,\n * minimizing the number of tiles used for the wards (maximizing the number of color 0 tiles).\n * The adjacencies between any two colors (including color 0) must be identical to the original.\n * Each color must form a connected set of tiles.\n * \n * Since the adjacency graph is planar (derived from a map), and the grid (50x50) is much larger \n * than the number of colors (100), we can use a greedy approach.\n * We place each color one by one using a BFS-based path construction.\n * To maintain the \"identical adjacency\" property, we use a \"safe cell\" condition:\n * a cell is safe for color c if it is currently color 0 and all its non-zero neighbors \n * are colors that c is actually adjacent to in the original map.\n * \n * Algorithm:\n * 1. Construct the adjacency graph G from the input.\n * 2. Use a BFS order starting from color 0 to decide the order of placing colors.\n * 3. For each color c:\n *    a. Identify the set T of colors already placed that c is adjacent to in G.\n *    b. Find a path of \"safe\" cells that connects c to all colors in T.\n *    c. A cell is safe if it's 0 and all its neighbors in the current grid belong to T.\n *    d. Use BFS to find the shortest paths connecting these target colors.\n *    e. Update the grid by coloring these cells with c.\n * 4. Output the resulting grid.\n */\n\nconst int N = 50;\nint grid[N][N];\nint n, m;\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < n && c >= 0 && c < n;\n}\n\n// A cell is safe for color c if it's 0 and its non-0 neighbors are all in the target set T.\nbool is_safe(int r, int c, const set<int>& T) {\n    if (grid[r][c] != 0) return false;\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (is_valid(nr, nc)) {\n            if (grid[nr][nc] != 0) {\n                if (T.find(grid[nr][nc]) == T.end()) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> original_grid(n, vector<int>(n));\n    set<int> adj[105]; // m can be up to 100\n    \n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> original_grid[i][j];\n        }\n    }\n\n    // Build the adjacency graph from the input map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = original_grid[i][j];\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (is_valid(ni, nj)) {\n                    int nc = original_grid[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                        adj[nc].insert(c);\n                    }\n                } else {\n                    // Adjacent to the outside (represented by color 0)\n                    if (c != 0) {\n                        adj[c].insert(0);\n                        adj[0].insert(c);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initialize the output grid with 0\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            grid[i][j] = 0;\n        }\n    }\n\n    // Determine the order of placement using BFS from color 0\n    vector<int> bfs_order;\n    queue<int> q_bfs;\n    q_bfs.push(0);\n    vector<bool> visited_bfs(m + 1, false);\n    visited_bfs[0] = true;\n    while (!q_bfs.empty()) {\n        int u = q_bfs.front();\n        q_bfs.pop();\n        if (u != 0) bfs_order.push_back(u);\n        for (int v : adj[u]) {\n            if (v <= m && v != 0 && !visited_bfs[v]) {\n                visited_bfs[v] = true;\n                q_bfs.push(v);\n            }\n        }\n    }\n    // Add any unvisited colors just in case\n    for (int i = 1; i <= m; ++i) {\n        if (!visited_bfs[i]) bfs_order.push_back(i);\n    }\n\n    set<int> P = {0}; // Colors already placed in the output grid\n\n    for (int c : bfs_order) {\n        // T is the set of colors already in the grid that c must be adjacent to\n        set<int> T;\n        for (int neighbor : adj[c]) {\n            if (P.count(neighbor)) {\n                T.insert(neighbor);\n            }\n        }\n\n        if (T.empty()) continue;\n\n        vector<Pos> Sc; // Set of cells to be assigned color c\n        Pos start_pos = {-1, -1};\n        bool found_start = false;\n        \n        // Find a starting safe cell adjacent to the first color in T\n        int d_first = *T.begin();\n        if (d_first != 0) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (grid[i][j] == d_first) {\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && is_safe(ni, nj, T)) {\n                                start_pos = {ni, nj};\n                                found_start = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            // If the first color is 0, any safe cell adjacent to 0 works\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        bool adj_to_zero = false;\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && grid[ni][nj] == 0) {\n                                adj_to_zero = true;\n                                break;\n                            }\n                        }\n                        if (adj_to_zero) {\n                            start_pos = {i, j};\n                            found_start = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: if no specifically adjacent start cell is found, pick any safe cell\n        if (!found_start) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        start_pos = {i, j};\n                        found_start = true;\n                    }\n                }\n            }\n        }\n\n        if (found_start) {\n            Sc.push_back(start_pos);\n            // Iteratively connect Sc to every other color in T using BFS\n            for (int d : T) {\n                if (d == d_first) continue;\n                \n                // Check if Sc is already adjacent to color d\n                bool already_adj = false;\n                for (auto p : Sc) {\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = p.r + dr[k], nj = p.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            already_adj = true;\n                            break;\n                        }\n                    }\n                    if (already_adj) break;\n                }\n                if (already_adj) continue;\n\n                // BFS to find the shortest path of safe cells to color d\n                queue<Pos> q;\n                vector<vector<int>> dist(n, vector<int>(n, -1));\n                vector<vector<Pos>> parent(n, vector<Pos>(n, {-1, -1}));\n                for (auto p : Sc) {\n                    q.push(p);\n                    dist[p.r][p.c] = 0;\n                }\n                Pos end_pos = {-1, -1};\n                while (!q.empty()) {\n                    Pos curr = q.front(); q.pop();\n                    bool adj_to_d = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = curr.r + dr[k], nj = curr.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            adj_to_d = true; \n                            break;\n                        }\n                    }\n                    if (adj_to_d) {\n                        end_pos = curr;\n                        break;\n                    }\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = curr.r + dr[k], nc = curr.c + dc[k];\n                        if (is_valid(nr, nc) && dist[nr][nc] == -1 && is_safe(nr, nc, T)) {\n                            dist[nr][nc] = dist[curr.r][curr.c] + 1;\n                            parent[nr][nc] = curr;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                // If a path is found, add it to the set Sc\n                if (end_pos.r != -1) {\n                    Pos curr = end_pos;\n                    while (dist[curr.r][curr.c] != 0) {\n                        Sc.push_back(curr);\n                        curr = parent[curr.r][curr.c];\n                    }\n                }\n            }\n            // Update grid with color c\n            for (auto p : Sc) grid[p.r][p.c] = c;\n            P.insert(c);\n        }\n    }\n\n    // Print the resulting map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc025":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to divide N items into D sets of equal total weight as much as possible, \n * given that item weights are unknown and we can only query the balance.\n * \n * Strategy:\n * 1. Estimate item weights: Use a gradient descent-based approach (specifically, Adam optimizer) \n *    to find weights that satisfy the comparison queries. We use the logarithm of weights \n *    (x_i = log(w_i)) to ensure weights are always positive and to handle potential scale issues.\n * 2. Intelligent Queries: In each step, pick items for the balance that make the sums on both sides \n *    as close as possible. This maximizes information gain when the balance result is unexpected.\n * 3. Partitioning: Once weights are estimated, use a Greedy approach combined with local \n *    search (hill climbing) to minimize the variance of the sums of weights in each set.\n */\n\nstruct Query {\n    vector<int> L, R;\n    char res;\n};\n\nint main() {\n    // Speed up input and output\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // x_i stores the log of the estimated weight w_i\n    vector<double> x(N, 0.0);\n    // Adam optimizer parameters\n    vector<double> m(N, 0.0); // First moment\n    vector<double> v(N, 0.0); // Second moment\n    double beta1 = 0.9, beta2 = 0.999, eps = 1e-8, alpha = 0.01;\n    double lambda = 0.01; // Regularization constant\n    vector<Query> queries;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int t_adam = 0; // Time step for Adam\n\n    for (int q = 0; q < Q; ++q) {\n        // Step 1: Select L and R for the query. \n        // We want |sum(L) - sum(R)| to be small.\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n\n        vector<int> best_L, best_R;\n        double best_diff = 1e18;\n\n        // Try multiple randomized greedy attempts to find good L and R\n        for (int attempt = 0; attempt < 40; ++attempt) {\n            vector<int> L, R;\n            double sumL = 0, sumR = 0;\n\n            // Ensure sets are non-empty\n            int i1 = indices[0], i2 = indices[1];\n            L.push_back(i1); sumL += exp(x[i1]);\n            R.push_back(i2); sumR += exp(x[i2]);\n\n            for (int i = 2; i < N; ++i) {\n                int idx = indices[i];\n                double val = exp(x[idx]);\n                double diff_L = abs(sumL + val - sumR);\n                double diff_R = abs(sumL - (sumR + val));\n                double diff_none = abs(sumL - sumR);\n\n                // Greedily decide to add item to L, R, or skip it\n                if (diff_L < diff_R && diff_L < diff_none) {\n                    L.push_back(idx);\n                    sumL += val;\n                } else if (diff_R < diff_none) {\n                    R.push_back(idx);\n                    sumR += val;\n                }\n            }\n\n            double diff = abs(sumL - sumR);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_L = L;\n                best_R = R;\n            }\n        }\n\n        // Output selected sets for the balance query\n        cout << best_L.size() << \" \" << best_R.size();\n        for (int idx : best_L) cout << \" \" << idx;\n        for (int idx : best_R) cout << \" \" << idx;\n        cout << endl;\n\n        char res;\n        if (!(cin >> res)) break;\n        queries.push_back({best_L, best_R, res});\n\n        // Step 2: Update weight estimates using Adam optimizer on recent queries\n        int M_window = min((int)queries.size(), 150);\n        int K_steps = 4;\n        for (int k_step = 0; k_step < K_steps; ++k_step) {\n            t_adam++;\n            vector<double> g(N, 0.0);\n            for (int i = 0; i < M_window; ++i) {\n                const auto& query = queries[queries.size() - 1 - i];\n                double sumL = 0, sumR = 0;\n                for (int idx : query.L) sumL += exp(x[idx]);\n                for (int idx : query.R) sumR += exp(x[idx]);\n                double d = sumL - sumR;\n\n                // Calculate gradient of squared loss function\n                if (query.res == '<') {\n                    if (d > 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '>') {\n                    if (d < 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '=') {\n                    for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                    for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                }\n            }\n            // Add regularization gradient to prevent x_i from exploding\n            for (int i = 0; i < N; ++i) g[i] += 2 * lambda * x[i];\n\n            // Adam update step\n            for (int i = 0; i < N; ++i) {\n                m[i] = beta1 * m[i] + (1.0 - beta1) * g[i];\n                v[i] = beta2 * v[i] + (1.0 - beta2) * g[i] * g[i];\n                double m_hat = m[i] / (1.0 - pow(beta1, t_adam));\n                double v_hat = v[i] / (1.0 - pow(beta2, t_adam));\n                x[i] -= alpha * m_hat / (sqrt(v_hat) + eps);\n            }\n        }\n    }\n\n    // Step 3: Final Division\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = exp(x[i]);\n\n    vector<int> d(N);\n    vector<double> set_sum(D, 0.0);\n\n    // Initial division using a greedy approach\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    for (int idx : p) {\n        int best_s = 0;\n        for (int s = 1; s < D; ++s) {\n            if (set_sum[s] < set_sum[best_s]) best_s = s;\n        }\n        d[idx] = best_s;\n        set_sum[best_s] += w[idx];\n    }\n\n    // Refine partition using hill climbing to minimize sum of squares (proportional to variance)\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            int old_s = d[i];\n            for (int new_s = 0; new_s < D; ++new_s) {\n                if (old_s == new_s) continue;\n                \n                double old_sum_sq = 0;\n                for (int s = 0; s < D; ++s) old_sum_sq += set_sum[s] * set_sum[s];\n                \n                double temp_sum_old = set_sum[old_s] - w[i];\n                double temp_sum_new = set_sum[new_s] + w[i];\n                double new_sum_sq_val = old_sum_sq - set_sum[old_s]*set_sum[old_s] - set_sum[new_s]*set_sum[new_s] + temp_sum_old*temp_sum_old + temp_sum_new*temp_sum_new;\n                \n                // If moving item i to new_s reduces the sum of squared set weights, accept move\n                if (new_sum_sq_val < old_sum_sq - 1e-7) {\n                    set_sum[old_s] -= w[i];\n                    set_sum[new_s] += w[i];\n                    d[i] = new_s;\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <deque>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to remove boxes in order 1, 2, ..., n.\n * - A box can be removed (Operation 2, cost 0) only if it is at the top of its stack.\n * - If a box v is not at the top, we must move all boxes above it to another stack (Operation 1, cost k+1).\n * - Our goal is to minimize total energy (sum of k+1).\n * \n * Key Insight:\n * - To minimize future costs, we want stacks to be in \"descending order\" from bottom to top.\n * - If a stack is [..., 5, 4, 3, 2, 1] (top is 1), then after removing 1, 2 becomes the top, then 3, etc.\n * - This way, many boxes can be removed using Operation 2 (cost 0) instead of Operation 1.\n * - A \"violation\" is defined as a pair (x, y) where x is below y but x < y.\n * - We use a greedy approach: when moving boxes above v to another stack, we pick the stack\n *   that minimizes the number of violations in the resulting stack, with a tie-breaker\n *   of minimizing the total stack size.\n * \n * Complexity:\n * - n=200, m=10.\n * - For each of the n boxes, we check m-1 possible target stacks.\n * - Each check takes O(n) to count violations.\n * - Total complexity: O(n^2 * m), which is ~400,000 operations. Well within 2.0s.\n */\n\n// Function to count the number of violations (x < y where x is below y) in a stack\nint count_violations(const deque<int>& s) {\n    int violations = 0;\n    for (size_t i = 0; i + 1 < s.size(); ++i) {\n        if (s[i] < s[i + 1]) {\n            violations++;\n        }\n    }\n    return violations;\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    // stacks[i] stores the boxes in stack i (bottom to top)\n    vector<deque<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n\n    // Record all operations to output at the end\n    // (v, 0) for Operation 2, (v, i) for Operation 1 (i is 1-indexed)\n    vector<pair<int, int>> operations;\n\n    for (int v = 1; v <= n; ++v) {\n        int current_stack_idx = -1;\n        int v_pos = -1;\n\n        // Step 1: Find the current position and stack of box v\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                    current_stack_idx = i;\n                    v_pos = j;\n                    break;\n                }\n            }\n            if (current_stack_idx != -1) break;\n        }\n\n        // Step 2: If v is not at the top, move all boxes above it to another stack\n        if (v_pos < (int)stacks[current_stack_idx].size() - 1) {\n            // The box immediately above v is our target for Operation 1\n            int u_idx = v_pos + 1;\n            int u = stacks[current_stack_idx][u_idx];\n\n            // Collect all boxes to be moved (from u to the current top)\n            vector<int> to_move;\n            for (int k = u_idx; k < (int)stacks[current_stack_idx].size(); ++k) {\n                to_move.push_back(stacks[current_stack_idx][k]);\n            }\n\n            // Greedy decision: Which stack to move these boxes to?\n            int best_target_idx = -1;\n            long long min_cost = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == current_stack_idx) continue;\n\n                // Simulate adding the moved part to stack i\n                deque<int> simulated_stack = stacks[i];\n                for (int val : to_move) {\n                    simulated_stack.push_back(val);\n                }\n\n                // Cost function: prioritize minimizing violations, then minimize stack size\n                // Large weight for violations to ensure it is the primary objective\n                long long cost = (long long)count_violations(simulated_stack) * 10000LL + (long long)simulated_stack.size();\n\n                if (best_target_idx == -1 || cost < min_cost) {\n                    min_cost = cost;\n                    best_target_idx = i;\n                }\n            }\n\n            // Perform the chosen move\n            // Remove the moved boxes from the current stack\n            for (size_t k = 0; k < to_move.size(); ++k) {\n                stacks[current_stack_idx].pop_back();\n            }\n            // Add the moved boxes to the target stack\n            for (int val : to_move) {\n                stacks[best_target_idx].push_back(val);\n            }\n\n            // Record Operation 1 (u, target_stack_1_indexed)\n            operations.push_back({u, best_target_idx + 1});\n        }\n\n        // Step 3: v is now at the top of its stack, remove it using Operation 2\n        operations.push_back({v, 0});\n        stacks[current_stack_idx].pop_back();\n    }\n\n    // Step 4: Output the operations\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem analysis:\n * The goal is to minimize the average dirtiness of an N x N grid by finding a cleaning route\n * of length L (L <= 10^5) that visits every square at least once and returns to (0,0).\n * The dirtiness of square (i, j) is (time since last visit) * d_{i,j}.\n * In the steady state (after repeating the cycle), the average dirtiness of square (i, j) \n * is approximately d_{i,j} * (gap_{i,j} - 1) / 2, where gap_{i,j} is the average interval\n * between visits to square (i, j).\n * To minimize sum(d_{i,j} * (gap_{i,j} - 1) / 2) subject to sum(1 / gap_{i,j}) = 1,\n * the optimal visit frequency f_{i,j} = 1/gap_{i,j} should be proportional to sqrt(d_{i,j}).\n * This suggests that squares with higher susceptibility should be visited more frequently.\n * \n * Algorithm:\n * 1. Generate an initial cleaning route that visits all reachable squares using DFS.\n *    In a DFS traversal of the grid, each edge is traversed twice, ensuring we visit all nodes.\n * 2. Calculate the target visit frequency for each square: m_{i,j} proportional to sqrt(d_{i,j}).\n * 3. To increase the visit frequency of certain squares, add \"detours\" to the DFS route.\n *    For any edge (u, v) in the DFS route, a detour consists of moving u -> v -> u -> v,\n *    which increases the visit counts of both u and v by 1 and increases the total length L by 2.\n * 4. Greedily add detours to the edges that provide the most benefit towards reaching the target \n *    visit counts, using a priority queue to efficiently select the best edge.\n * 5. Output the resulting sequence of moves.\n */\n\nint N;\nvector<string> h_walls;\nvector<string> v_walls;\nvector<vector<int>> d;\n\nstruct Square {\n    int r, c;\n};\n\nvector<Square> path;\nvector<char> move_chars;\nbool visited[40][40];\n\n// DFS to generate a route that visits all squares and returns to (0,0)\nvoid dfs_correct(int r, int c) {\n    visited[r][c] = true;\n\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n    char move_c[] = {'R', 'D', 'L', 'U'};\n    char back_c[] = {'L', 'U', 'R', 'D'};\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {\n            bool wall = false;\n            if (i == 0) wall = (v_walls[r][c] == '1');\n            else if (i == 1) wall = (h_walls[r][c] == '1');\n            else if (i == 2) wall = (v_walls[nr][nc] == '1');\n            else if (i == 3) wall = (h_walls[nr][nc] == '1');\n\n            if (!wall) {\n                move_chars.push_back(move_c[i]);\n                path.push_back({nr, nc});\n                dfs_correct(nr, nc);\n                move_chars.push_back(back_c[i]);\n                path.push_back({r, c});\n            }\n        }\n    }\n}\n\nint main() {\n    // Standard optimizations for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[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    }\n\n    // Reset visited array\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited[i][j] = false;\n        }\n    }\n\n    // Generate initial DFS route\n    path.push_back({0, 0});\n    dfs_correct(0, 0);\n\n    int L_dfs = move_chars.size();\n    vector<int> m(N * N, 0);\n    for (const auto& sq : path) {\n        m[sq.r * N + sq.c]++;\n    }\n\n    // Calculate target visit frequency constant C\n    double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((double)d[i][j]);\n        }\n    }\n    // L_max is 10^5. Total visits = L + 1\n    double C = 100001.0 / sum_sqrt_d;\n\n    // Function to calculate the benefit of adding a detour to the k-th edge\n    auto get_benefit = [&](int k) -> double {\n        int r1 = path[k].r, c1 = path[k].c;\n        int r2 = path[k+1].r, c2 = path[k+1].c;\n        double b1 = max(0.0, C * sqrt((double)d[r1][c1]) - m[r1 * N + c1]);\n        double b2 = max(0.0, C * sqrt((double)d[r2][c2]) - m[r2 * N + c2]);\n        return b1 + b2;\n    };\n\n    // Greedy selection of edges for detours\n    priority_queue<pair<double, int>> pq;\n    for (int k = 0; k < L_dfs; ++k) {\n        pq.push({get_benefit(k), k});\n    }\n\n    vector<int> count(L_dfs, 0);\n    int L_current = L_dfs;\n\n    while (L_current + 2 <= 100000 && !pq.empty()) {\n        pair<double, int> top = pq.top();\n        pq.pop();\n\n        int k = top.second;\n        double b = top.first;\n\n        // If benefit is near zero or the benefit value is stale, skip\n        if (b < 1e-7) break;\n        if (abs(b - get_benefit(k)) > 1e-7) continue;\n\n        // Apply detour\n        count[k]++;\n        L_current += 2;\n        m[path[k].r * N + path[k].c]++;\n        m[path[k+1].r * N + path[k+1].c]++;\n        \n        // Re-push updated edge to priority queue\n        pq.push({get_benefit(k), k});\n    }\n\n    // Build and output the final route string\n    string final_moves = \"\";\n    final_moves.reserve(L_current);\n    for (int k = 0; k < L_dfs; ++k) {\n        final_moves += move_chars[k];\n        if (count[k] > 0) {\n            char m_k = move_chars[k];\n            char rev_m_k;\n            if (m_k == 'R') rev_m_k = 'L';\n            else if (m_k == 'L') rev_m_k = 'R';\n            else if (m_k == 'U') rev_m_k = 'D';\n            else rev_m_k = 'U';\n\n            for (int i = 0; i < count[k]; ++i) {\n                final_moves += rev_m_k;\n                final_moves += m_k;\n            }\n        }\n    }\n\n    cout << final_moves << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Kakizome Taikai\n * Goal: Create a \"lucky string\" containing all M target strings (each of length 5)\n * as substrings, while minimizing the movement cost.\n * \n * Strategy:\n * 1. Pre-calculate the Manhattan distance + 1 between any two squares.\n * 2. Use a greedy strategy to build the lucky string:\n *    a. At each step, find the target string not yet covered that can be added\n *       with the minimum \"cost per new string covered\" ratio.\n *    b. To add a target string t_k, find the maximum overlap between its prefix\n *       and the current string's suffix.\n *    c. Use DP to find the minimum cost to add the remaining characters of t_k\n *       from the current finger position.\n *    d. Update the finger position, the current string, and the set of covered strings.\n * 3. Repeat until all strings are covered or the length limit (5000) is reached.\n */\n\nconst int MAX_N = 15;\nconst int MAX_M = 200;\n\nint N, M;\nint si, sj;\nstring A[MAX_N];\nstring t[MAX_M];\n\nstruct Pos {\n    int r, c;\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dist(Pos a, Pos b) {\n    return abs(a.r - b.r) + abs(a.c - b.c) + 1;\n}\n\nstruct Result {\n    int cost;\n    vector<Pos> path;\n    string added_chars;\n};\n\nResult get_min_cost_to_add(Pos last_pos, const string& target, int p) {\n    int len = target.length() - p;\n    if (len <= 0) return {0, {}, \"\"};\n\n    // dp[i][r][c] = min cost to add first i characters of target[p:], ending at (r, c)\n    // i from 1 to len\n    vector<vector<vector<int>>> dp(len + 1, vector<vector<int>>(N, vector<int>(N, 1e9)));\n    vector<vector<vector<Pos>>> parent(len + 1, vector<vector<Pos>>(N, vector<Pos>(N, {-1, -1})));\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (A[r][c] == target[p]) {\n                dp[1][r][c] = dist(last_pos, {r, c});\n                parent[1][r][c] = last_pos;\n            }\n        }\n    }\n\n    for (int i = 2; i <= len; ++i) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (A[r][c] == target[p + i - 1]) {\n                    for (int pr = 0; pr < N; ++pr) {\n                        for (int pc = 0; pc < N; ++pc) {\n                            if (dp[i - 1][pr][pc] != 1e9) {\n                                int d = dp[i - 1][pr][pc] + dist({pr, pc}, {r, c});\n                                if (d < dp[i][r][c]) {\n                                    dp[i][r][c] = d;\n                                    parent[i][r][c] = {pr, pc};\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    int min_cost = 1e9;\n    Pos best_end = {-1, -1};\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[len][r][c] < min_cost) {\n                min_cost = dp[len][r][c];\n                best_end = {r, c};\n            }\n        }\n    }\n\n    if (min_cost == 1e9) return {1000000, {}, \"\"};\n\n    vector<Pos> path;\n    string added = \"\";\n    Pos curr = best_end;\n    for (int i = len; i >= 1; --i) {\n        path.push_back(curr);\n        added += target[p + i - 1];\n        curr = parent[i][curr.r][curr.c];\n    }\n    reverse(path.begin(), path.end());\n    reverse(added.begin(), added.end());\n\n    return {min_cost, path, added};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    string S = \"\";\n    Pos current_pos = {si, sj};\n    vector<bool> covered(M, false);\n    int covered_count = 0;\n    vector<Pos> final_path;\n\n    while (covered_count < M && S.length() < 5000) {\n        int best_k = -1;\n        Result best_res = {1000000, {}, \"\"};\n        double best_ratio = 1e18;\n\n        // Identify current suffix for overlap checking (up to 4 characters)\n        string suffix = \"\";\n        if (S.length() >= 4) {\n            suffix = S.substr(S.length() - 4);\n        } else {\n            suffix = S;\n        }\n\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n\n            // Find max overlap p between suffix and t[k].prefix(p)\n            int p = 0;\n            for (int len = min((int)suffix.length(), 4); len >= 1; --len) {\n                if (suffix.substr(suffix.length() - len) == t[k].substr(0, len)) {\n                    p = len;\n                    break;\n                }\n            }\n\n            // The target string could already be a substring if p=5 (not possible here)\n            // or if we already covered it.\n            Result res = get_min_cost_to_add(current_pos, t[k], p);\n            if (res.cost >= 1000000) continue;\n\n            // Calculate how many new strings are covered by adding this t[k]\n            string next_S = S + res.added_chars;\n            int new_covered = 0;\n            for (int j = 0; j < M; ++j) {\n                if (!covered[j] && next_S.find(t[j]) != string::npos) {\n                    new_covered++;\n                }\n            }\n\n            double ratio = (double)res.cost / (new_covered + 1e-9);\n            if (ratio < best_ratio) {\n                best_ratio = ratio;\n                best_k = k;\n                best_res = res;\n            }\n        }\n\n        if (best_k == -1) break; // Should not happen given problem constraints\n\n        // Apply the best choice\n        S += best_res.added_chars;\n        for (auto p : best_res.path) {\n            final_path.push_back(p);\n        }\n        current_pos = best_res.path.back();\n\n        // Re-check all strings for coverage\n        for (int j = 0; j < M; ++j) {\n            if (!covered[j] && S.find(t[j]) != string::npos) {\n                covered[j] = true;\n                covered_count++;\n            }\n        }\n    }\n\n    // Output the sequence of operations\n    for (const auto& p : final_path) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct Polyomino {\n    int d;\n    vector<pair<int, int>> shape;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> fields;\nvector<vector<pair<int, int>>> field_positions;\nvector<vector<double>> field_probs;\ndouble Q1[20][20][20];\n\nbool is_valid(int r, int c, const Polyomino& poly) {\n    for (auto& p : poly.shape) {\n        int nr = r + p.first;\n        int nc = c + p.second;\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> fields[i].d;\n        for (int j = 0; j < fields[i].d; ++j) {\n            int r, c;\n            cin >> r >> c;\n            fields[i].shape.push_back({r, c});\n        }\n    }\n\n    field_positions.resize(M);\n    for (int i = 0; i < M; ++i) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_valid(r, c, fields[i])) {\n                    field_positions[i].push_back({r, c});\n                }\n            }\n        }\n    }\n\n    field_probs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        field_probs[i].assign(field_positions[i].size(), 1.0 / (double)field_positions[i].size());\n    }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            for (int m = 0; m < M; ++m)\n                Q1[i][j][m] = 0.0;\n\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n            for (auto& coord : fields[m].shape) {\n                int r = field_positions[m][p].first + coord.first;\n                int c = field_positions[m][p].second + coord.second;\n                if (r >= 0 && r < N && c >= 0 && c < N) {\n                    Q1[r][c][m] += field_probs[m][p];\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> v_known(N, vector<int>(N, -1));\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n\n    for (int step = 0; step < N * N; ++step) {\n        vector<vector<double>> p_ij(N, vector<double>(N, 0.0));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double prob_zero = 1.0;\n                for (int m = 0; m < M; ++m) {\n                    prob_zero *= (1.0 - Q1[i][j][m]);\n                }\n                p_ij[i][j] = 1.0 - prob_zero;\n            }\n        }\n\n        bool all_certain = true;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j] && p_ij[i][j] > 1e-4 && p_ij[i][j] < (1.0 - 1e-4)) {\n                    all_certain = false;\n                    break;\n                }\n            }\n            if (!all_certain) break;\n        }\n\n        if (all_certain) {\n            vector<pair<int, int>> ans;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (v_known[i][j] > 0 || p_ij[i][j] > 0.5) {\n                        ans.push_back({i, j});\n                    }\n                }\n            }\n            cout << \"a \" << ans.size();\n            for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n            cout << endl;\n            int resp; cin >> resp;\n            return 0;\n        }\n\n        int best_i = -1, best_j = -1;\n        double max_unc = -1.0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j]) {\n                    double unc = p_ij[i][j] * (1.0 - p_ij[i][j]);\n                    if (unc > max_unc) {\n                        max_unc = unc;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n\n        if (best_i == -1) break;\n\n        cout << \"q 1 \" << best_i << \" \" << best_j << endl;\n        int V;\n        if (!(cin >> V)) break;\n        v_known[best_i][best_j] = V;\n        drilled[best_i][best_j] = true;\n\n        for (int m = 0; m < M; ++m) {\n            vector<double> dp(M + 1, 0.0);\n            dp[0] = 1.0;\n            for (int mp = 0; mp < M; ++mp) {\n                if (mp == m) continue;\n                double q1 = Q1[best_i][best_j][mp];\n                double q0 = 1.0 - q1;\n                for (int s = M; s >= 0; --s) {\n                    dp[s] = dp[s] * q0 + (s > 0 ? dp[s - 1] * q1 : 0.0);\n                }\n            }\n\n            vector<double> old_probs = field_probs[m];\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                bool covered = false;\n                for (auto& coord : fields[m].shape) {\n                    if (field_positions[m][p].first + coord.first == best_i &&\n                        field_positions[m][p].second + coord.second == best_j) {\n                        covered = true;\n                        break;\n                    }\n                }\n                int target = V - (covered ? 1 : 0);\n                if (target >= 0 && target < M) field_probs[m][p] *= dp[target];\n                else field_probs[m][p] = 0.0;\n            }\n\n            double sum_p = 0;\n            for (double pr : field_probs[m]) sum_p += pr;\n            if (sum_p > 1e-18) {\n                for (double& pr : field_probs[m]) pr /= sum_p;\n            } else {\n                field_probs[m].assign(field_positions[m].size(), 1.0 / field_positions[m].size());\n            }\n\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                double diff = field_probs[m][p] - old_probs[p];\n                if (abs(diff) > 1e-18) {\n                    for (auto& coord : fields[m].shape) {\n                        int r = field_positions[m][p].first + coord.first;\n                        int c = field_positions[m][p].second + coord.second;\n                        if (r >= 0 && r < N && c >= 0 && c < N) {\n                            Q1[r][c][m] += diff;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If we reach here, guess everything we know\n    vector<pair<int, int>> ans;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (v_known[i][j] > 0) ans.push_back({i, j});\n        }\n    }\n    cout << \"a \" << ans.size();\n    for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int resp; cin >> resp;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * 1. The goal is to minimize the total cost, which consists of area shortfall cost and partition cost.\n *    Area shortfall cost: 100 * (desired_area - actual_area).\n *    Partition cost: Total length of partition segments that change between consecutive days.\n * 2. Area shortfall cost is very expensive (100x), so we should prioritize meeting area requirements.\n * 3. Partition cost is proportional to the number of changing horizontal/vertical segments. \n *    If we use horizontal strips (rectangles spanning the full width W), only horizontal partitions exist.\n *    A change in boundary at y-coordinate y costs W (for each of the W horizontal segments at that height).\n * 4. Let the y-coordinates of the boundaries on day d be 0 = y_{d,0} < y_{d,1} < ... < y_{d,N} = W.\n *    The k-th rectangle (k=0...N-1) has height (y_{d,k+1} - y_{d,k}) and area W * (y_{d,k+1} - y_{d,k}).\n *    We ensure the area requirement by setting y_{d,k+1} - y_{d,k} >= ceil(a_{d,k} / W).\n * 5. To minimize partition cost, we want the boundaries y_{d,k} on day d to be the same as day d-1\n *    as much as possible. This can be modeled as maximizing the number of shared boundary coordinates.\n * 6. We can use Dynamic Programming (DP) for each day to find the best set of boundaries.\n *    dp[k][y] = maximum number of boundaries in {y_{d,1}, ..., y_{d,k}} that are in S_{d-1}, \n *    where y_{d,k} = y.\n *    Complexity: O(D * N * W), which is roughly 50 * 50 * 1000 = 2.5 * 10^6 operations.\n */\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i][j];\n        }\n    }\n\n    // y_vals[d][k] is the y-coordinate of the boundary after the (k-1)-th rectangle.\n    // y_vals[d][0] = 0, y_vals[d][N] = W.\n    vector<vector<int>> y_vals(D, vector<int>(N + 1));\n\n    for (int d = 0; d < D; ++d) {\n        // H[k] is the minimum height (integer) required for the k-th rectangle to satisfy area a[d][k].\n        vector<int> H(N);\n        for (int k = 0; k < N; ++k) {\n            H[k] = (a[d][k] + W - 1) / W;\n            if (H[k] < 1) H[k] = 1;\n        }\n\n        // Pre-calculate cumulative minimum heights to define valid ranges for y_vals[d][k].\n        vector<int> PreH(N + 1, 0);\n        for (int k = 0; k < N; ++k) PreH[k + 1] = PreH[k] + H[k];\n\n        vector<int> SufH(N + 1, 0);\n        for (int k = N - 1; k >= 0; --k) SufH[k] = SufH[k + 1] + H[k];\n\n        if (d == 0) {\n            // First day partition installation cost is 0, so just satisfy requirements.\n            y_vals[d][0] = 0;\n            for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n            y_vals[d][N] = W;\n        } else {\n            // Identify which boundary y-coordinates were used on the previous day.\n            vector<bool> is_in_S_prev(W + 1, false);\n            for (int k = 1; k < N; ++k) {\n                is_in_S_prev[y_vals[d - 1][k]] = true;\n            }\n\n            // dp[k][y] = max common boundaries in {y_{d,1}, ..., y_{d,k}} with y_{d,k} = y.\n            // k ranges from 1 to N-1.\n            vector<vector<int>> dp(N, vector<int>(W + 1, -1000000));\n            vector<vector<int>> parent(N, vector<int>(W + 1, -1));\n\n            // Base case: k=0, y_{d,0}=0.\n            dp[0][0] = 0;\n\n            for (int k = 1; k < N; ++k) {\n                // Use prefix maximum optimization to speed up the DP transition to O(1) per state.\n                vector<int> pref_max(W + 1, -1000000);\n                vector<int> pref_max_idx(W + 1, -1);\n                int cur_max = -1000000;\n                int cur_idx = -1;\n                for (int i = 0; i <= W; ++i) {\n                    if (dp[k - 1][i] > cur_max) {\n                        cur_max = dp[k - 1][i];\n                        cur_idx = i;\n                    }\n                    pref_max[i] = cur_max;\n                    pref_max_idx[i] = cur_idx;\n                }\n\n                // Iterate over valid y-coordinates for the k-th boundary.\n                for (int y = PreH[k]; y <= W - SufH[k]; ++y) {\n                    int max_y_prev = y - H[k - 1];\n                    if (max_y_prev >= 0) {\n                        int val = pref_max[max_y_prev];\n                        if (val >= 0) {\n                            dp[k][y] = val + (is_in_S_prev[y] ? 1 : 0);\n                            parent[k][y] = pref_max_idx[max_y_prev];\n                        }\n                    }\n                }\n            }\n\n            // Backtrack to find the optimal boundaries.\n            int best_y = -1;\n            int max_val = -1000000;\n            for (int y = PreH[N - 1]; y <= W - SufH[N - 1]; ++y) {\n                if (dp[N - 1][y] > max_val) {\n                    max_val = dp[N - 1][y];\n                    best_y = y;\n                }\n            }\n\n            y_vals[d][N] = W;\n            y_vals[d][0] = 0;\n            if (best_y != -1) {\n                y_vals[d][N - 1] = best_y;\n                for (int k = N - 1; k >= 1; --k) {\n                    y_vals[d][k - 1] = parent[k][y_vals[d][k]];\n                }\n            } else {\n                // Safety fallback if the DP failed (should not occur).\n                for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n                y_vals[d][0] = 0;\n                y_vals[d][N] = W;\n            }\n        }\n    }\n\n    // Output the rectangles in the required format.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            // Rectangle for k-th reservation on day d.\n            // Top-left (y_vals[d][k], 0), Bottom-right (y_vals[d][k+1], W).\n            cout << y_vals[d][k] << \" \" << 0 << \" \" << y_vals[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\nlong long a[N][N];\nlong long s[M][3][3];\nlong long b[N][N];\n\nstruct Operation {\n    int m, p, q;\n};\n\nOperation slots[K];\nbool occupied[K];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in, k_in;\n    if (!(cin >> n_in >> m_in >> k_in)) return 0;\n\n    // Input initial board\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    // Input stamps\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 >> s[m][i][j];\n\n    // Initialize board and current score\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            b[i][j] = a[i][j];\n\n    long long current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            current_score += b[i][j] % P;\n\n    mt19937_64 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    long long best_score = current_score;\n    vector<Operation> best_ops;\n    for (int i = 0; i < K; ++i) occupied[i] = false;\n\n    // SA parameters\n    double T_start = 1e9;\n    double T_end = 1e-1;\n\n    // Pre-allocate buffers to speed up loop\n    bool is_aff[N][N];\n    pair<int, int> affected[18];\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.85) break; // Leave time for final output\n\n        double T = T_start * pow(T_end / T_start, elapsed / 1.85);\n\n        int i = rng() % K;\n\n        if (occupied[i]) {\n            // Decide between REMOVE or MODIFY\n            int move_type = rng() % 100;\n            if (move_type < 30) { // REMOVE move\n                int m = slots[i].m;\n                int p = slots[i].p;\n                int q = slots[i].q;\n\n                long long delta = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v - s[m][di][dj];\n                        delta += (new_v % P) - (old_v % P);\n                    }\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int r = p + di, c = q + dj;\n                            b[r][c] -= s[m][di][dj];\n                        }\n                    }\n                    occupied[i] = false;\n                    current_score += delta;\n                }\n            } else { // MODIFY move\n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n                int m_old = slots[i].m;\n                int p_old = slots[i].p;\n                int q_old = slots[i].q;\n\n                if (m_new == m_old && p_new == p_old && q_new == q_old) continue;\n\n                // Identify union of cells affected by old and new stamp\n                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) is_aff[r][c] = false;\n                int aff_cnt = 0;\n\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_old + di, c = q_old + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n\n                long long delta = 0;\n                for (int k = 0; k < aff_cnt; ++k) {\n                    int r = affected[k].first, c = affected[k].second;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v;\n                    if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                        new_v -= s[m_old][r - p_old][c - q_old];\n                    if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                        new_v += s[m_new][r - p_new][c - q_new];\n                    delta += (new_v % P) - (old_v % P);\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int k = 0; k < aff_cnt; ++k) {\n                        int r = affected[k].first, c = affected[k].second;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v;\n                        if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                            new_v -= s[m_old][r - p_old][c - q_old];\n                        if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                            new_v += s[m_new][r - p_new][c - q_new];\n                        b[r][c] = new_v;\n                    }\n                    slots[i] = {m_new, p_new, q_new};\n                    current_score += delta;\n                }\n            }\n        } else { // ADD move\n            int m_new = rng() % M;\n            int p_new = rng() % (N - 2);\n            int q_new = rng() % (N - 2);\n\n            long long delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int r = p_new + di, c = q_new + dj;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v + s[m_new][di][dj];\n                    delta += (new_v % P) - (old_v % P);\n                }\n            }\n\n            if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        b[r][c] += s[m_new][di][dj];\n                    }\n                }\n                slots[i] = {m_new, p_new, q_new};\n                occupied[i] = true;\n                current_score += delta;\n            }\n        }\n\n        // Update best known solution\n        if (current_score > best_score) {\n            best_score = current_score;\n            best_ops.clear();\n            for (int k = 0; k < K; ++k) {\n                if (occupied[k]) best_ops.push_back(slots[k]);\n            }\n        }\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/*\nProblem Analysis:\n- The goal is to dispatch N^2 = 25 containers from specific Dispatch Gates.\n- Containers must be dispatched in a specific order: 0, 1, ..., 24.\n- The scoring favors minimizing the total turns (M0), the number of inversions (M1),\n  wrong dispatch gates (M2), and undispatched containers (M3).\n- To minimize M1, M2, and M3, the most important thing is to dispatch containers\n  in the correct order 0, 1, ..., 24 at their respective correct gates (c/N, N-1).\n- We use a single large crane (crane 0) to pick up each container one by one in \n  increasing order.\n- All other cranes are immediately bombed to ensure they don't block the path.\n- The large crane is capable of moving through squares with other containers.\n- BFS is used to find the shortest path for the large crane between target locations.\n*/\n\nint N;\nint A[5][5];\nint grid[5][5];\nint arrival_idx[5];\nint crane_x[5], crane_y[5];\nint crane_holding[5];\nbool container_on_grid[25];\nint container_pos_x[25], container_pos_y[25];\nbool container_dispatched[25];\nint target_c = 0;\n\n// Returns the direction char to move from (sx, sy) to (nx, ny)\nchar get_move_char(int sx, int sy, int nx, int ny) {\n    if (nx < sx) return 'U';\n    if (nx > sx) return 'D';\n    if (ny < sy) return 'L';\n    if (ny > sy) return 'R';\n    return '.';\n}\n\n// BFS to find the next step towards (tx, ty) on a 5x5 grid\npair<int, int> get_next_step(int sx, int sy, int tx, int ty) {\n    if (sx == tx && sy == ty) return {sx, sy};\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    queue<pair<int, int>> q;\n    q.push({sx, sy});\n    int dist[5][5];\n    pair<int, int> parent[5][5];\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    dist[sx][sy] = 0;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        if (curr.first == tx && curr.second == ty) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.first + dx[i];\n            int ny = curr.second + dy[i];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n\n    if (dist[tx][ty] == -1) return {sx, sy};\n\n    // Backtrack to find the first step along the path from (sx, sy)\n    int cx = tx, cy = ty;\n    while (parent[cx][cy].first != sx || parent[cx][cy].second != sy) {\n        pair<int, int> p = parent[cx][cy];\n        cx = p.first;\n        cy = p.second;\n    }\n    return {cx, cy};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            grid[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        arrival_idx[i] = 0;\n        crane_x[i] = i;\n        crane_y[i] = 0;\n        crane_holding[i] = -1;\n    }\n    crane_x[0] = 0;\n    crane_y[0] = 0;\n    for (int i = 0; i < 25; ++i) {\n        container_on_grid[i] = false;\n        container_dispatched[i] = false;\n    }\n\n    // Pre-allocate strings for outputs\n    vector<string> actions(N, string(10000, '.'));\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // 1. Arrivals (Step 1)\n        for (int i = 0; i < N; ++i) {\n            bool crane_holding_at_gate = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_holding[k] != -1 && crane_x[k] == i && crane_y[k] == 0) {\n                    crane_holding_at_gate = true;\n                    break;\n                }\n            }\n            if (arrival_idx[i] < N && grid[i][0] == -1 && !crane_holding_at_gate) {\n                int c = A[i][arrival_idx[i]];\n                grid[i][0] = c;\n                container_on_grid[c] = true;\n                container_pos_x[c] = i;\n                container_pos_y[c] = 0;\n                arrival_idx[i]++;\n            }\n        }\n\n        // 2. Crane Actions (Step 2)\n        // First turn: Bomb all small cranes to clear paths\n        if (turn == 1) {\n            for (int i = 1; i < N; ++i) {\n                actions[i][0] = 'B';\n                // Small cranes are effectively removed from the simulation now\n            }\n        }\n\n        // Decision for the large crane (crane 0)\n        if (crane_holding[0] == -1) {\n            if (target_c < 25) {\n                // Check if target container is on the grid\n                if (container_on_grid[target_c]) {\n                    int rx = container_pos_x[target_c];\n                    int ry = container_pos_y[target_c];\n                    if (crane_x[0] == rx && crane_y[0] == ry) {\n                        // If at the container, pick it up\n                        actions[0][turn - 1] = 'P';\n                        crane_holding[0] = target_c;\n                        grid[rx][ry] = -1;\n                        container_on_grid[target_c] = false;\n                    } else {\n                        // Otherwise, move towards it\n                        pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                        actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                        crane_x[0] = next_pos.first;\n                        crane_y[0] = next_pos.second;\n                    }\n                } else {\n                    // Target container hasn't arrived yet\n                    actions[0][turn - 1] = '.';\n                }\n            } else {\n                actions[0][turn - 1] = '.';\n            }\n        } else {\n            // Large crane is holding a container\n            int c = crane_holding[0];\n            int rx = c / N, ry = N - 1;\n            if (crane_x[0] == rx && crane_y[0] == ry) {\n                // If at target dispatch gate, release it\n                actions[0][turn - 1] = 'Q';\n                grid[rx][ry] = c;\n                crane_holding[0] = -1;\n                target_c++;\n            } else {\n                // Move towards the dispatch gate\n                pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                crane_x[0] = next_pos.first;\n                crane_y[0] = next_pos.second;\n            }\n        }\n\n        // 3. Dispatches (Step 3)\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][N - 1] != -1) {\n                int c = grid[i][N - 1];\n                grid[i][N - 1] = -1;\n                container_on_grid[c] = false;\n                container_dispatched[c] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - The goal is to make all h[i][j] = 0 by loading and unloading soil.\n * - Costs: \n *   - Loading/unloading d units: d.\n *   - Moving to an adjacent square: 100 + current_load.\n * - Strategy:\n *   1. At the current square (r, c), if h[r][c] > 0, we load all the soil (d = h[r][c]).\n *   2. If h[r][c] < 0 and we have soil (cur_load > 0), we unload as much as possible (d = min(cur_load, |h[r][c]|)).\n *   3. If neither is possible (e.g., h[r][c] is 0 or we don't have soil to unload), we move towards:\n *      - The nearest sink (h[i][j] < 0) if we currently have soil (cur_load > 0).\n *      - The nearest source (h[i][j] > 0) if we currently have no soil (cur_load == 0).\n *   4. Repeat until all h[i][j] are 0 and cur_load is 0.\n * - The sum of h[i][j] is guaranteed to be 0, ensuring that we can always find a source or a sink\n *   unless all heights are 0.\n * - The number of turns will be well within the limit of 100,000 because there are N^2 = 400 squares\n *   and the distance between any two squares is at most 40.\n */\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n\n    int cur_r = 0, cur_c = 0, cur_load = 0;\n    vector<string> ops;\n\n    while (true) {\n        if (h[cur_r][cur_c] > 0) {\n            // Step 1: Load soil from the current source\n            int d = h[cur_r][cur_c];\n            h[cur_r][cur_c] = 0;\n            cur_load += d;\n            ops.push_back(\"+\" + to_string(d));\n        } else if (h[cur_r][cur_c] < 0 && cur_load > 0) {\n            // Step 2: Unload soil to the current sink\n            int d = min(cur_load, -h[cur_r][cur_c]);\n            h[cur_r][cur_c] += d;\n            cur_load -= d;\n            ops.push_back(\"-\" + to_string(d));\n        } else {\n            // Step 3: Find the nearest target to move towards\n            int target_r = -1, target_c = -1;\n            int min_dist = 1000000;\n\n            // Greedy search for the nearest relevant square\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (cur_load > 0) {\n                        // If carrying soil, look for a sink\n                        if (h[i][j] < 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    } else {\n                        // If empty, look for a source\n                        if (h[i][j] > 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // If no valid target square is found, we are finished.\n            if (target_r == -1) break;\n\n            // Step 4: Move one step toward the target square\n            if (target_r < cur_r) {\n                ops.push_back(\"U\");\n                cur_r--;\n            } else if (target_r > cur_r) {\n                ops.push_back(\"D\");\n                cur_r++;\n            } else if (target_c < cur_c) {\n                ops.push_back(\"L\");\n                cur_c--;\n            } else if (target_c > cur_c) {\n                ops.push_back(\"R\");\n                cur_c++;\n            } else {\n                // This part should ideally not be reached given the logic above.\n                break;\n            }\n        }\n        \n        // Safety limit for the number of operations\n        if (ops.size() >= 100000) break;\n    }\n\n    // Output the list of operations\n    for (const string& s : ops) {\n        cout << s << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to maximize the maximum sum of evaluation criteria for a single seed after T operations.\n * In each operation, we place 36 seeds on a 6x6 grid. Adjacent pairs (60 pairs in total) generate \n * new seeds where each criterion is inherited from one of the two parents.\n * \n * Heuristic Approach:\n * To maximize the sum, we want to have a single pair of seeds where, for many criteria, one seed\n * has a very high value. The potential of a pair (k, k') can be estimated by the maximum possible\n * sum it could produce: V_max(k, k') = sum_{l=0}^{M-1} max(x_{k,l}, x_{k',l}).\n * We use Simulated Annealing (SA) to find a placement of seeds on the grid that maximizes \n * a function related to these potential values.\n * \n * The objective function for SA is: max_{p in Pairs} V_max(p) + 0.01 * sum_{p in Pairs} V_max(p).\n * This encourages both a single very good pair and many moderately good pairs.\n */\n\n// Fixed problem parameters based on constraints\nconst int MAX_N = 6;\nconst int MAX_M = 15;\nconst int MAX_SEEDS = 60;\nconst int MAX_PAIRS = 60;\n\nint N, M, T;\nint seed_count;\nint grid_size;\n\nstruct Seed {\n    int x[MAX_M];\n    int v;\n};\n\nSeed seeds[MAX_SEEDS];\nint grid[MAX_N][MAX_N];\nint pos[MAX_SEEDS]; // Position of seed k in the grid (0-35) or -1\n\nstruct Pair {\n    int r1, c1, r2, c2;\n};\nPair adj_pairs[MAX_PAIRS];\nint cell_to_pairs[MAX_N][MAX_N][8];\nint cell_to_pairs_size[MAX_N][MAX_N];\ndouble pair_scores[MAX_PAIRS];\n\n// Calculate the maximum possible value of a new seed from a pair of seeds\ndouble calculate_pair_vmax(int k1, int k2) {\n    double vmax = 0;\n    for (int l = 0; l < M; ++l) {\n        vmax += max(seeds[k1].x[l], seeds[k2].x[l]);\n    }\n    return vmax;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial input\n    if (!(cin >> N >> M >> T)) return 0;\n\n    seed_count = 2 * N * (N - 1);\n    grid_size = N * N;\n\n    for (int i = 0; i < seed_count; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> seeds[i].x[j];\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    // Precompute grid adjacency\n    int pair_idx = 0;\n    for (int i = 0; i < MAX_N; ++i) {\n        for (int j = 0; j < MAX_N; ++j) {\n            cell_to_pairs_size[i][j] = 0;\n        }\n    }\n\n    // Horizontal adjacent pairs\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            adj_pairs[pair_idx] = {i, j, i, j + 1};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i][j + 1][cell_to_pairs_size[i][j + 1]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    // Vertical adjacent pairs\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            adj_pairs[pair_idx] = {i, j, i + 1, j};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i + 1][j][cell_to_pairs_size[i + 1][j]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Reset grid for the current turn\n        for (int i = 0; i < seed_count; ++i) pos[i] = -1;\n        for (int i = 0; i < grid_size; ++i) {\n            grid[i / N][i % N] = i;\n            pos[i] = i;\n        }\n\n        // Initial score setup\n        for (int i = 0; i < pair_idx; ++i) {\n            pair_scores[i] = calculate_pair_vmax(grid[adj_pairs[i].r1][adj_pairs[i].c1], grid[adj_pairs[i].r2][adj_pairs[i].c2]);\n        }\n\n        auto get_current_score = [&]() {\n            double max_v = 0;\n            double sum_v = 0;\n            for (int i = 0; i < pair_idx; ++i) {\n                if (pair_scores[i] > max_v) max_v = pair_scores[i];\n                sum_v += pair_scores[i];\n            }\n            return max_v + 0.01 * sum_v;\n        };\n\n        double current_score = get_current_score();\n        auto start_time = chrono::steady_clock::now();\n\n        int iter = 0;\n        // Simulated Annealing core loop\n        while (true) {\n            // Periodically check for the time limit (each turn gets ~0.15 seconds)\n            if ((iter & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start_time).count() > 0.16) break;\n            }\n            iter++;\n\n            int r = uniform_int_distribution<int>(0, N - 1)(rng);\n            int c = uniform_int_distribution<int>(0, N - 1)(rng);\n            int s = uniform_int_distribution<int>(0, seed_count - 1)(rng);\n\n            int r2 = -1, c2 = -1;\n            if (pos[s] != -1) {\n                r2 = pos[s] / N;\n                c2 = pos[s] % N;\n            }\n\n            if (r == r2 && c == c2) continue;\n\n            int old_seed_rc = grid[r][c];\n            int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n\n            int changed_pairs[10];\n            double old_pair_scores[10];\n            int cp_cnt = 0;\n\n            // Lambda to record affected pairs and their scores for undoing moves\n            auto record_affected_pairs = [&](int row, int col) {\n                for (int i = 0; i < cell_to_pairs_size[row][col]; ++i) {\n                    int p_idx = cell_to_pairs[row][col][i];\n                    bool already_recorded = false;\n                    for (int k = 0; k < cp_cnt; ++k) {\n                        if (changed_pairs[k] == p_idx) {\n                            already_recorded = true;\n                            break;\n                        }\n                    }\n                    if (!already_recorded) {\n                        changed_pairs[cp_cnt] = p_idx;\n                        old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                        cp_cnt++;\n                    }\n                }\n            };\n\n            record_affected_pairs(r, c);\n            if (r2 != -1) record_affected_pairs(r2, c2);\n\n            // Apply the potential move (either swap or replace)\n            if (r2 != -1) {\n                // Swap\n                grid[r][c] = s;\n                grid[r2][c2] = old_seed_rc;\n                pos[s] = r * N + c;\n                pos[old_seed_rc] = r2 * N + c2;\n            } else {\n                // Replace\n                grid[r][c] = s;\n                pos[old_seed_rc] = -1;\n                pos[s] = r * N + c;\n            }\n\n            // Recalculate pair scores for the updated grid\n            for (int i = 0; i < cp_cnt; ++i) {\n                int p_idx = changed_pairs[i];\n                pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n            }\n\n            double next_score = get_current_score();\n            \n            // Time-based temperature reduction\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double temp = 10.0 * (1.0 - elapsed / 0.16);\n            if (temp < 0.01) temp = 0.01;\n\n            // Metropolis criterion\n            if (next_score > current_score || exp((next_score - current_score) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_score = next_score;\n            } else {\n                // Revert the move\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc;\n                    grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2;\n                    pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc;\n                    pos[s] = -1;\n                    pos[old_seed_rc] = r * N + c;\n                }\n                for (int i = 0; i < cp_cnt; ++i) {\n                    pair_scores[changed_pairs[i]] = old_pair_scores[i];\n                }\n            }\n        }\n\n        // Output current placement\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // Read newly generated seeds from the judge\n        for (int i = 0; i < seed_count; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                cin >> seeds[i].x[j];\n                seeds[i].v += seeds[i].x[j];\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We need to move M takoyaki from initial positions S to target positions T.\n * We can design a robotic arm as a tree with up to V vertices.\n * A star-like tree with a single fingertip (leaf) and the root at the center is a good choice.\n * Let's use V'=2 (one root and one fingertip) with an edge length L=1.\n * The fingertip (vertex 1) can reach any cell (sx, sy) if the root (vertex 0) is placed\n * at an adjacent cell (sx+/-1, sy) or (sx, sy+/-1).\n * The movements involve moving the root (U, D, L, R) and rotating the fingertip (L, R).\n * \n * The score is based on the number of turns. Moving one takoyaki at a time\n * from its current position to its target position should be efficient.\n */\n\nstruct State {\n    int rx, ry, dir_idx;\n};\n\nint N, M, V;\nvector<string> s_grid, t_grid;\nint curr_rx, curr_ry, curr_dir_idx;\n\n// Directions for dir_idx: 0: Down (1,0), 1: Right (0,1), 2: Up (-1,0), 3: Left (0,-1)\nint dx[] = {1, 0, -1, 0};\nint dy[] = {0, 1, 0, -1};\n\nvoid move_to(int target_rx, int target_ry, int target_dir_idx, bool is_last) {\n    int dist = abs(curr_rx - target_rx) + abs(curr_ry - target_ry);\n    int rot_ccw = (target_dir_idx - curr_dir_idx + 4) % 4;\n    int rot_cw = (curr_dir_idx - target_dir_idx + 4) % 4;\n\n    int turns, rot_needed;\n    char rot_char;\n    if (max(dist, rot_ccw) <= max(dist, rot_cw)) {\n        turns = max(dist, rot_ccw);\n        rot_needed = rot_ccw;\n        rot_char = 'L';\n    } else {\n        turns = max(dist, rot_cw);\n        rot_needed = rot_cw;\n        rot_char = 'R';\n    }\n\n    // If already at the target position and direction, we still need one turn to pick/place.\n    if (turns == 0) turns = 1;\n\n    int temp_rx = curr_rx, temp_ry = curr_ry;\n    int temp_dir = curr_dir_idx;\n    int rotations_done = 0;\n\n    for (int i = 1; i <= turns; ++i) {\n        char move_char = '.';\n        if (temp_rx < target_rx) { move_char = 'D'; temp_rx++; }\n        else if (temp_rx > target_rx) { move_char = 'U'; temp_rx--; }\n        else if (temp_ry < target_ry) { move_char = 'R'; temp_ry++; }\n        else if (temp_ry > target_ry) { move_char = 'L'; temp_ry--; }\n\n        char cur_rot_char = '.';\n        if (rotations_done < rot_needed) {\n            cur_rot_char = rot_char;\n            if (rot_char == 'L') temp_dir = (temp_dir + 1) % 4;\n            else temp_dir = (temp_dir + 3) % 4;\n            rotations_done++;\n        }\n\n        char action_char = (is_last && i == turns) ? 'P' : '.';\n        // Turn format: S[0] (move), S[1] (rotation of vertex 1), S[2] (action of root), S[3] (action of leaf)\n        cout << move_char << cur_rot_char << '.' << action_char << \"\\n\";\n    }\n    curr_rx = target_rx;\n    curr_ry = target_ry;\n    curr_dir_idx = target_dir_idx;\n}\n\nState find_state(int sx, int sy, int n) {\n    for (int d = 0; d < 4; ++d) {\n        int rx = sx - dx[d];\n        int ry = sy - dy[d];\n        if (rx >= 0 && rx < n && ry >= 0 && ry < n) {\n            return {rx, ry, d};\n        }\n    }\n    return {0, 0, 0};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    s_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Design the tree: V'=2, vertex 0 is root, vertex 1 is leaf. Edge (0,1) length 1.\n    cout << 2 << \"\\n\";\n    cout << \"0 1\" << \"\\n\";\n    // Initial root position (0, 0)\n    cout << \"0 0\" << \"\\n\";\n\n    // Initial robotic arm state (root at 0,0 and all edges extend to the right: dir_idx = 1)\n    curr_rx = 0;\n    curr_ry = 0;\n    curr_dir_idx = 1;\n\n    // Identify takoyaki that need to be moved\n    vector<pair<int, int>> s_only, t_only;\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                s_only.push_back({i, j});\n            }\n            if (s_grid[i][j] == '0' && t_grid[i][j] == '1') {\n                t_only.push_back({i, j});\n            }\n        }\n    }\n\n    // Each takoyaki in s_only must be moved to a position in t_only\n    for (size_t i = 0; i < s_only.size(); ++i) {\n        // 1. Pick up from current s_only[i]\n        State pick_state = find_state(s_only[i].first, s_only[i].second, N);\n        move_to(pick_state.rx, pick_state.ry, pick_state.dir_idx, true);\n\n        // 2. Drop at target t_only[i]\n        State drop_state = find_state(t_only[i].first, t_only[i].second, N);\n        move_to(drop_state.rx, drop_state.ry, drop_state.dir_idx, true);\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We are given N mackerels (weight +1) and N sardines (weight -1).\n * We need to find an axis-parallel polygon that maximizes the sum of weights of fish inside it.\n * The polygon must have at most 1000 vertices, edge length at most 4*10^5, \n * and coordinates between 0 and 10^5. It must not self-intersect.\n * \n * The maximum weight rectangle problem can be solved in O(N^2) by iterating \n * through all pairs of y-coordinates and using Kadane's algorithm on x-coordinates.\n * With N = 5000, O(N^2) is approximately 2.5 * 10^7, which fits within the 2-second limit.\n * Specifically, if we collect unique x and y coordinates, the complexity becomes O(L^2 + LN),\n * where L is the number of unique y-coordinates and N is the total number of fish.\n */\n\nstruct Fish {\n    int x, y, weight;\n};\n\nint main() {\n    // Speed up I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Fish> all_fish;\n    vector<int> all_x, all_y;\n\n    // Read mackerels\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    // Read sardines\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Pre-process unique coordinates for compression\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n\n    int K = all_x.size();\n    int L = all_y.size();\n\n    // Group fish by their unique y-coordinate index\n    vector<vector<pair<int, int>>> fish_at_y(L);\n    for (const auto& f : all_fish) {\n        int xi = lower_bound(all_x.begin(), all_x.end(), f.x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), f.y) - all_y.begin();\n        fish_at_y[yi].push_back({xi, f.weight});\n    }\n\n    // Initialize with a single mackerel to ensure a minimum score of 2 (a-b+1 = 1-0+1 = 2)\n    // (assuming mackerels are the first N fish)\n    int best_sum = 0;\n    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n\n    // A single mackerel at index i (0 <= i < N) provides sum 1\n    for (int i = 0; i < N; ++i) {\n        // Since all_fish[0...N-1] are mackerels\n        int xi = lower_bound(all_x.begin(), all_x.end(), all_fish[i].x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), all_fish[i].y) - all_y.begin();\n        if (1 > best_sum) {\n            best_sum = 1;\n            bx1 = xi; bx2 = xi;\n            by1 = yi; by2 = yi;\n        }\n    }\n\n    // O(L^2 + LN) algorithm to find the maximum weight rectangle\n    vector<int> f(K, 0);\n    for (int i = 0; i < L; ++i) {\n        // Reset x-coordinate weights for the new starting y-coordinate\n        fill(f.begin(), f.end(), 0);\n        for (int j = i; j < L; ++j) {\n            // Add fish at current y-coordinate j to the weights\n            for (auto& p : fish_at_y[j]) {\n                f[p.first] += p.second;\n            }\n            \n            // Find maximum subarray sum of weights in f using Kadane's\n            int cur_sum = 0;\n            int start = 0;\n            for (int k = 0; k < K; ++k) {\n                cur_sum += f[k];\n                if (cur_sum > best_sum) {\n                    best_sum = cur_sum;\n                    bx1 = start; bx2 = k;\n                    by1 = i; by2 = j;\n                }\n                if (cur_sum < 0) {\n                    cur_sum = 0;\n                    start = k + 1;\n                }\n            }\n        }\n    }\n\n    // Convert the discrete indices back to actual coordinates\n    int x1 = all_x[bx1], x2 = all_x[bx2];\n    int y1 = all_y[by1], y2 = all_y[by2];\n\n    // Ensure we form a valid non-zero area polygon\n    if (x1 == x2) {\n        if (x1 < 100000) x2 = x1 + 1;\n        else { x1 = x1 - 1; x2 = x1 + 1; }\n    }\n    if (y1 == y2) {\n        if (y1 < 100000) y2 = y1 + 1;\n        else { y1 = y1 - 1; y2 = y1 + 1; }\n    }\n\n    // Output the 4 vertices of the rectangle\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << endl;\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Rectangular packing in a single cardboard box.\n * Goal: Minimize W + H + Sum(unused rectangles' dimensions).\n * Method: Randomized Greedy approach with time-limited iterations.\n * \n * Rules:\n * - Rectangles must be placed in increasing order of indices.\n * - Each can be rotated 90 degrees.\n * - Directions: U (upward, move towards y=0) or L (leftward, move towards x=0).\n * - U with reference b: x_left_new = x_right_b (or 0).\n * - L with reference b: y_top_new = y_bottom_b (or 0).\n * - Movement stops when it hits an edge of a previously placed rectangle or axis.\n */\n\nstruct Rect {\n    int id;\n    long long w, h;\n    long long x, y;\n    long long x_right, y_bottom;\n};\n\nstruct Placement {\n    int p, r, d, b; \n};\n\nstruct State {\n    vector<Rect> placed;\n    vector<Placement> placements;\n    long long W, H;\n    long long score;\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<pair<long long, long long>> measured_wh(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> measured_wh[i].first >> measured_wh[i].second;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Time management to avoid TLE in system tests\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 2.7) break;\n\n        State best_state;\n        best_state.score = 4e18; \n\n        // Perform randomized greedy iterations in batches\n        for (int batch = 0; batch < 100; ++batch) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) break;\n\n            for (int iter = 0; iter < 5; ++iter) {\n                State current_state;\n                current_state.W = 0;\n                current_state.H = 0;\n                long long unused_sum = 0;\n                for (int i = 0; i < N; ++i) unused_sum += (measured_wh[i].first + measured_wh[i].second);\n\n                for (int i = 0; i < N; ++i) {\n                    long long wi = measured_wh[i].first;\n                    long long hi = measured_wh[i].second;\n\n                    struct Option {\n                        int r, d, b;\n                        long long new_W, new_H;\n                    };\n                    static Option options[405];\n                    int opt_count = 0;\n                    long long best_new_W_H = 4e18;\n\n                    for (int r : {0, 1}) {\n                        long long w = (r == 0 ? wi : hi);\n                        long long h = (r == 0 ? hi : wi);\n                        \n                        for (int d : {0, 1}) { // 0 for U, 1 for L\n                            // Try Case 1: Reference rectangle b = -1\n                            long long x_l, x_r, y_t, y_b;\n                            if (d == 0) { // U\n                                x_l = 0; x_r = w; y_t = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                }\n                                y_b = y_t + h;\n                            } else { // L\n                                y_t = 0; y_b = h; x_l = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                }\n                                x_r = x_l + w;\n                            }\n                            long long nw = max(current_state.W, x_r);\n                            long long nh = max(current_state.H, y_b);\n                            if (nw + nh < best_new_W_H) {\n                                best_new_W_H = nw + nh;\n                                opt_count = 0;\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            } else if (nw + nh == best_new_W_H) {\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            }\n\n                            // Try Case 2: Reference rectangle b is a previously placed rectangle\n                            for (const auto& prev : current_state.placed) {\n                                int b_id = prev.id;\n                                if (d == 0) { // U\n                                    x_l = prev.x_right; x_r = x_l + w; y_t = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                    }\n                                    y_b = y_t + h;\n                                } else { // L\n                                    y_t = prev.y_bottom; y_b = y_t + h; x_l = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                    }\n                                    x_r = x_l + w;\n                                }\n                                nw = max(current_state.W, x_r);\n                                nh = max(current_state.H, y_b);\n                                if (nw + nh < best_new_W_H) {\n                                    best_new_W_H = nw + nh;\n                                    opt_count = 0;\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                } else if (nw + nh == best_new_W_H) {\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                }\n                            }\n                        }\n                    }\n\n                    // Greedy decision: Include rectangle i if the score improvement is worth it.\n                    long long delta = best_new_W_H - (current_state.W + current_state.H);\n                    if (delta < wi + hi && opt_count > 0) {\n                        uniform_int_distribution<int> dist(0, opt_count - 1);\n                        Option opt = options[dist(rng)];\n                        long long w = (opt.r == 0 ? wi : hi);\n                        long long h = (opt.r == 0 ? hi : wi);\n                        Rect nr; nr.id = i; nr.w = w; nr.h = h;\n                        if (opt.d == 0) { // Direction U\n                            if (opt.b == -1) nr.x = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.x = p.x_right; break; }\n                            }\n                            nr.x_right = nr.x + w;\n                            long long yt = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.x_right <= p.x || nr.x >= p.x_right)) yt = max(yt, p.y_bottom);\n                            nr.y = yt; nr.y_bottom = yt + h;\n                        } else { // Direction L\n                            if (opt.b == -1) nr.y = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.y = p.y_bottom; break; }\n                            }\n                            nr.y_bottom = nr.y + h;\n                            long long xl = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.y_bottom <= p.y || nr.y >= p.y_bottom)) xl = max(xl, p.x_right);\n                            nr.x = xl; nr.x_right = xl + w;\n                        }\n                        current_state.placed.push_back(nr);\n                        current_state.placements.push_back({i, opt.r, opt.d, opt.b});\n                        current_state.W = max(current_state.W, nr.x_right);\n                        current_state.H = max(current_state.H, nr.y_bottom);\n                        unused_sum -= (wi + hi);\n                    }\n                }\n                current_state.score = current_state.W + current_state.H + unused_sum;\n                if (current_state.score < best_state.score) best_state = current_state;\n            }\n        }\n\n        // Output the best arrangement found for the current turn.\n        cout << best_state.placed.size() << \"\\n\";\n        for (const auto& pl : best_state.placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << (pl.d == 0 ? \"U\" : \"L\") << \" \" << pl.b << \"\\n\";\n        }\n        cout.flush();\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n    }\n\n    return 0;\n}\n","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Partition a planar graph into rooted trees to maximize sum (h_v + 1) * A_v,\n * subject to height constraint h_v <= H.\n * \n * Strategy:\n * 1. Initial Solution: Greedy approach. Sort nodes by beauty ascending.\n *    For each node, attach it to a neighbor that is already in a tree and has the maximum depth < H.\n *    This puts high-beauty nodes at deeper levels of the trees.\n * 2. Optimization: Simulated Annealing (SA).\n *    Moves: Change the parent of a node v to a neighbor u (or -1 for root).\n *    Checking validity: \n *      - Ensure no cycles (u is not in v's subtree).\n *      - Ensure height constraint is maintained (new_depth_v + max_rel_depth_v <= H).\n *    Efficiency:\n *      - Depth and ancestor check in O(H).\n *      - Maintain subtree_sum_A and max_rel_depth for each node.\n *      - Updating these values takes O(H * degree) by walking up the ancestors.\n *    This allows for many SA iterations within the 2-second time limit.\n */\n\nconst int MAXN = 1005;\nint N, M, H;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_rel_depth[MAXN];\nbool visited[MAXN];\n\nint get_depth(int v) {\n    int d = 0;\n    while (v != -1 && parent[v] != -1) {\n        v = parent[v];\n        d++;\n    }\n    return d;\n}\n\nbool is_ancestor(int v, int u) { // is v an ancestor of u?\n    int curr = u;\n    for (int i = 0; i <= H + 1; ++i) {\n        if (curr == v) return true;\n        if (curr == -1) break;\n        curr = parent[curr];\n    }\n    return false;\n}\n\nvoid update_ancestors(int v) {\n    int curr = v;\n    while (curr != -1) {\n        // Update subtree_sum_A[curr]\n        long long new_sum = A[curr];\n        for (int c : children[curr]) {\n            new_sum += subtree_sum_A[c];\n        }\n        subtree_sum_A[curr] = new_sum;\n\n        // Update max_rel_depth[curr]\n        int new_md = 0;\n        for (int c : children[curr]) {\n            new_md = max(new_md, max_rel_depth[c] + 1);\n        }\n        max_rel_depth[curr] = new_md;\n\n        curr = parent[curr];\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> H)) return 0;\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Initial state: all nodes are roots\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_rel_depth[i] = 0;\n        visited[i] = false;\n    }\n\n    // Greedy initial construction\n    vector<int> order(N);\n    for (int i = 0; i < N; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return A[a] < A[b];\n    });\n\n    for (int v : order) {\n        int best_u = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (visited[u]) {\n                int d = get_depth(u);\n                if (d < H && d > max_d) {\n                    max_d = d;\n                    best_u = u;\n                }\n            }\n        }\n        if (best_u != -1) {\n            parent[v] = best_u;\n            children[best_u].push_back(v);\n            visited[v] = true;\n            // v's depth is already 0 relative to its parent, but we calculate depth(v) as depth(u)+1\n            // We need to update v's subtree info and its ancestors.\n            // To start, v is a leaf, so max_rel_depth[v] = 0 and subtree_sum_A[v] = A[v].\n            max_rel_depth[v] = 0;\n            subtree_sum_A[v] = A[v];\n            update_ancestors(v);\n        } else {\n            parent[v] = -1;\n            visited[v] = true;\n            max_rel_depth[v] = 0;\n            subtree_sum_A[v] = A[v];\n        }\n    }\n\n    // Simulated Annealing\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 rng(42);\n    \n    double T_start = 100.0;\n    double T_end = 0.01;\n    int iterations = 800000;\n\n    for (int iter = 0; iter < iterations; ++iter) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n\n        double T = T_start * pow(T_end / T_start, (double)iter / iterations);\n\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int u_idx = uniform_int_distribution<int>(-1, (int)adj[v].size() - 1)(rng);\n        int u = (u_idx == -1) ? -1 : adj[v][u_idx];\n\n        if (u == parent[v]) continue;\n        if (u != -1 && is_ancestor(v, u)) continue;\n\n        int old_p = parent[v];\n        int new_p = u;\n        int old_depth_v = get_depth(v);\n        int new_depth_v = (new_p == -1) ? 0 : get_depth(new_p) + 1;\n\n        if (new_depth_v + max_rel_depth[v] > H) continue;\n\n        long long delta = (long long)(new_depth_v - old_depth_v) * subtree_sum_A[v];\n\n        if (delta > 0 || uniform_real_distribution<double>(0, 1)(rng) < exp((double)delta / T)) {\n            // Accept the move\n            if (old_p != -1) {\n                children[old_p].erase(remove(children[old_p].begin(), children[old_p].end(), v), children[old_p].end());\n                update_ancestors(old_p);\n            }\n            parent[v] = new_p;\n            if (new_p != -1) {\n                children[new_p].push_back(v);\n            }\n            update_ancestors(v);\n        }\n    }\n\n    // Output results\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i] << (i == N - 1 ? \"\" : \" \");\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\n/**\n * Problem: Oni wa Soto, Fuku wa Uchi\n * Objective: Remove all Oni ('x') from an NxN board without removing any Fukunokami ('o').\n * Strategy:\n * 1. Identify all Oni positions.\n * 2. Identify all possible \"efficient\" moves:\n *    - For each row/column, if a contiguous sequence of squares from an edge does not contain 'o', \n *      we can remove all 'x' in that sequence using a single group of shifts and a restoration sequence.\n *    - For example, shifting row i Left k times and then Right k times removes all 'x' in (i, 0) to (i, k-1)\n *      and restores the remaining pieces to their original positions.\n * 3. Use a Greedy Set Cover heuristic to select the minimum-cost set of moves that covers all 'x'.\n * 4. Output the sequence of moves.\n */\n\nstruct Oni {\n    int r, c;\n};\n\nstruct Move {\n    char d;\n    int p;\n    int k;\n    vector<int> covered_indices; // Indices in the initial Oni list\n    int cost;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> board(N);\n    vector<Oni> oni_list;\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_list.push_back({i, j});\n            }\n        }\n    }\n\n    vector<Move> all_possible_moves;\n\n    // Generate possible moves for each column (Up and Down)\n    for (int j = 0; j < N; ++j) {\n        // Up moves\n        int max_up = 0;\n        while (max_up < N && board[max_up][j] != 'o') {\n            max_up++;\n        }\n        for (int k = 1; k <= max_up; ++k) {\n            Move m;\n            m.d = 'U'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Down moves\n        int max_down = 0;\n        while (max_down < N && board[N - 1 - max_down][j] != 'o') {\n            max_down++;\n        }\n        for (int k = 1; k <= max_down; ++k) {\n            Move m;\n            m.d = 'D'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Generate possible moves for each row (Left and Right)\n    for (int i = 0; i < N; ++i) {\n        // Left moves\n        int max_left = 0;\n        while (max_left < N && board[i][max_left] != 'o') {\n            max_left++;\n        }\n        for (int k = 1; k <= max_left; ++k) {\n            Move m;\n            m.d = 'L'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Right moves\n        int max_right = 0;\n        while (max_right < N && board[i][N - 1 - max_right] != 'o') {\n            max_right++;\n        }\n        for (int k = 1; k <= max_right; ++k) {\n            Move m;\n            m.d = 'R'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Greedy Set Cover\n    vector<bool> uncovered(oni_list.size(), true);\n    int remaining_oni = oni_list.size();\n    vector<Move> chosen_moves;\n\n    while (remaining_oni > 0) {\n        int best_m_idx = -1;\n        double best_ratio = -1.0;\n\n        for (int i = 0; i < (int)all_possible_moves.size(); ++i) {\n            int count = 0;\n            for (int idx : all_possible_moves[i].covered_indices) {\n                if (uncovered[idx]) count++;\n            }\n            if (count > 0) {\n                double ratio = (double)count / all_possible_moves[i].cost;\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_m_idx = i;\n                }\n            }\n        }\n\n        if (best_m_idx == -1) break; // Should not happen given problem guarantees\n\n        chosen_moves.push_back(all_possible_moves[best_m_idx]);\n        for (int idx : all_possible_moves[best_m_idx].covered_indices) {\n            if (uncovered[idx]) {\n                uncovered[idx] = false;\n                remaining_oni--;\n            }\n        }\n    }\n\n    // Output moves\n    for (const auto& m : chosen_moves) {\n        char d1 = m.d, d2 = (m.d == 'U' ? 'D' : (m.d == 'D' ? 'U' : (m.d == 'L' ? 'R' : 'L')));\n        for (int step = 0; step < m.k; ++step) cout << d1 << \" \" << m.p << \"\\n\";\n        for (int step = 0; step < m.k; ++step) cout << d2 << \" \" << m.p << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem: A heuristic optimization problem to minimize error in cleaning duties assignment.\n * Strategy:\n *   The number of times each employee is the 'next' cleaner can be approximated by the \n *   in-degree in a graph where each employee j has two out-edges: a_j (for 1st, 3rd... visit) \n *   and b_j (for 2nd, 4th... visit).\n *   We aim to find a_j and b_j such that in-degree(i) is approximately T_i.\n *   To ensure all employees with T_i > 0 are actually assigned duties, the graph must be \n *   connected from the starting employee 0.\n *   We use Hill Climbing with local search to minimize a cost function: \n *   Cost = Sum|in_degree(i) - T_i| + Large_Penalty * Number_of_Unreachable_Employees.\n */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n\n    vector<long long> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    vector<long long> u(N), v(N);\n    for (int i = 0; i < N; ++i) {\n        u[i] = (T[i] + 1) / 2;\n        v[i] = T[i] / 2;\n    }\n\n    vector<int> a(N), b(N);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = rng() % N;\n        b[i] = rng() % N;\n    }\n\n    vector<long long> in_deg(N, 0);\n    for (int i = 0; i < N; ++i) {\n        in_deg[a[i]] += u[i];\n        in_deg[b[i]] += v[i];\n    }\n\n    auto get_cost = [&](const vector<int>& cur_a, const vector<int>& cur_b, const vector<long long>& cur_in_deg) {\n        long long error = 0;\n        for (int i = 0; i < N; ++i) {\n            error += abs(cur_in_deg[i] - T[i]);\n        }\n\n        // Reachability check: BFS from node 0\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        int reachable_count = 1;\n        while (!q.empty()) {\n            int curr = q.front();\n            q.pop();\n            int nexts[2] = {cur_a[curr], cur_b[curr]};\n            for (int nxt : nexts) {\n                if (!reachable[nxt]) {\n                    reachable[nxt] = true;\n                    reachable_count++;\n                    q.push(nxt);\n                }\n            }\n        }\n\n        long long penalty = 0;\n        for (int i = 0; i < N; ++i) {\n            if (T[i] > 0 && !reachable[i]) {\n                penalty += T[i] * 1000000LL; // Large penalty for unreachable required nodes\n            }\n        }\n        return error + penalty;\n    };\n\n    long long current_cost = get_cost(a, b, in_deg);\n\n    auto start_time = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        if (iter % 100 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) {\n                break;\n            }\n        }\n        iter++;\n\n        int j = rng() % N;\n        int old_a = a[j], old_b = b[j];\n\n        // Instead of trying all N^2 pairs (which is too slow), we try changing one edge or both.\n        int type = rng() % 3;\n        int new_a = old_a, new_b = old_b;\n        if (type == 0) new_a = rng() % N;\n        else if (type == 1) new_b = rng() % N;\n        else { new_a = rng() % N; new_b = rng() % N; }\n\n        if (new_a == old_a && new_b == old_b) continue;\n\n        // Update in_deg for fast calculation\n        vector<long long> next_in_deg = in_deg;\n        next_in_deg[old_a] -= u[j];\n        next_in_deg[old_b] -= v[j];\n        next_in_deg[new_a] += u[j];\n        next_in_deg[new_b] += v[j];\n\n        // To avoid updating a and b vectors before verification\n        int old_a_saved = a[j], old_b_saved = b[j];\n        a[j] = new_a; b[j] = new_b;\n        long long next_cost = get_cost(a, b, next_in_deg);\n\n        if (next_cost < current_cost) {\n            current_cost = next_cost;\n            in_deg = next_in_deg;\n        } else {\n            a[j] = old_a_saved; b[j] = old_b_saved;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to divide N cities into M groups of fixed sizes G_0, ..., G_{M-1}.\n * - For each group, we need to find a spanning tree of roads.\n * - The total length of roads (Euclidean distance rounded down) should be minimized.\n * - We can use up to Q queries to find the MST of any subset of size [2, L].\n * - We have uncertainty about city coordinates (given as rectangular ranges).\n *\n * Proposed Strategy:\n * 1. Estimate the center of each city's rectangular coordinate range.\n * 2. Use Morton (Z-order) curve sorting on the estimated coordinates to group cities.\n *    This helps in keeping cities that are close in 2D space together in the sorted list.\n * 3. Divide the sorted cities into groups of the given sizes G_i.\n * 4. For each group with size > 1, use queries to find edges to form a connected graph.\n *    A group of size G_k is covered by queries of size L with an overlap of 1 city.\n *    This ensures the resulting set of edges forms a connected path-like structure.\n *    The total number of queries will be at most Sum_{i: G_i>1} ceil((G_i-1)/(L-1)).\n *    Given the constraints (N=800, M=400, L>=3, Q=400), this total is guaranteed to be <= 400.\n * 5. Output the groups and the edges.\n */\n\n// Morton (Z-order) curve encoding for 2D points.\nuint64_t interleave(uint32_t x, uint32_t y) {\n    uint64_t z = 0;\n    for (int i = 0; i < 32; ++i) {\n        z |= (static_cast<uint64_t>((x >> i) & 1) << (2 * i));\n        z |= (static_cast<uint64_t>((y >> i) & 1) << (2 * i + 1));\n    }\n    return z;\n}\n\nstruct City {\n    int id;\n    uint64_t morton;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        int cx = (lx[i] + rx[i]) / 2;\n        int cy = (ly[i] + ry[i]) / 2;\n        cities[i] = {i, interleave((uint32_t)cx, (uint32_t)cy)};\n    }\n\n    // Sort cities based on Morton order to preserve spatial locality.\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        return a.morton < b.morton;\n    });\n\n    // Partition sorted cities into groups of requested sizes.\n    vector<vector<int>> groups(M);\n    int current_city_idx = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[current_city_idx++].id);\n        }\n    }\n\n    vector<vector<pair<int, int>>> edges_in_group(M);\n\n    // Use queries to find edges within each group.\n    for (int i = 0; i < M; ++i) {\n        if (groups[i].size() > 1) {\n            int idx = 0;\n            int G_size = groups[i].size();\n            while (idx < G_size - 1) {\n                // Each query connects a subset of up to L cities.\n                // To ensure connectivity, each query (after the first) overlaps with the previous by 1 city.\n                int subset_size = min(L, G_size - idx);\n                \n                // Perform query.\n                cout << \"? \" << subset_size;\n                for (int k = 0; k < subset_size; ++k) {\n                    cout << \" \" << groups[i][idx + k];\n                }\n                cout << endl;\n\n                // Receive MST edges of the chosen subset.\n                for (int k = 0; k < subset_size - 1; ++k) {\n                    int u, v;\n                    cin >> u >> v;\n                    edges_in_group[i].push_back({u, v});\n                }\n                \n                // Move to the next city for the next query (overlap of one city).\n                idx += (subset_size - 1);\n            }\n        }\n    }\n\n    // Final Output\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        // Print cities in the current group.\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            cout << groups[i][j] << (j == (int)groups[i].size() - 1 ? \"\" : \" \");\n        }\n        cout << endl;\n        // Print roads in the current group.\n        for (auto& edge : edges_in_group[i]) {\n            cout << edge.first << \" \" << edge.second << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size: 20x20.\n * - Number of target squares: M-1 = 39.\n * - Total turns allowed: 1600.\n * - Score formula: M + 2NM - T, where T is the number of turns.\n * - Goals: Visit all targets in order and minimize T.\n * \n * Insights from Initial Approach:\n * - The 'Move' (M) only strategy achieves a score of ~1100.\n * - A better strategy should utilize 'Slide' (S) to reduce the number of turns T.\n * - 'Slide' is useful when it can cover a large distance by hitting a boundary or a block.\n * - Boundary sliding can be used to jump from (r, c) to (0, c) or (N-1, c) in one turn.\n * \n * Refined Strategy:\n * - Use Dijkstra's algorithm to find the shortest path between consecutive target squares.\n * - The state for Dijkstra will be the current (row, col) position.\n * - Transitions include:\n *   1. Move (M) in 4 cardinal directions (cost 1, only if the cell is in bounds and not a block).\n *   2. Slide (S) in 4 cardinal directions (cost 1, stops at the first block or boundary encountered).\n * - This approach naturally optimizes both 'Move' and 'Slide' actions, including boundary jumps.\n * - Since the grid is small (20x20), Dijkstra is computationally efficient.\n */\n\nconst int INF = 1e9;\n\n// State for Dijkstra\nstruct State {\n    int d, r, c;\n    bool operator>(const State& other) const {\n        return d > other.d;\n    }\n};\n\n// Parent pointer to reconstruct the path\nstruct Parent {\n    int r, c;\n    char action;\n    int dir;\n};\n\nint N, M;\nbool G[20][20]; // Grid representing block positions\nint dr[] = {-1, 1, 0, 0}; // Directions: Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar dir_chars[] = {'U', 'D', 'L', 'R'};\n\nvoid solve() {\n    // Input N and M\n    if (!(cin >> N >> M)) return;\n    int r0, c0;\n    if (!(cin >> r0 >> c0)) return;\n    \n    // Read the sequence of target squares\n    vector<pair<int, int>> targets(M);\n    targets[0] = {r0, c0};\n    for (int i = 1; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    // Initialize grid (initially no blocks)\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            G[i][j] = false;\n\n    int curr_r = r0, curr_c = c0;\n\n    // Iterate through target squares in order\n    for (int k = 1; k < M; ++k) {\n        int tr = targets[k].first;\n        int tc = targets[k].second;\n\n        // Dijkstra algorithm to find the shortest path from curr to target\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<Parent>> parent(N, vector<Parent>(N, {-1, -1, ' ', -1}));\n\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[curr_r][curr_c] = 0;\n        pq.push({0, curr_r, curr_c});\n\n        while (!pq.empty()) {\n            State top = pq.top();\n            pq.pop();\n            int d = top.d, r = top.r, c = top.c;\n\n            if (d > dist[r][c]) continue;\n            if (r == tr && c == tc) break;\n\n            for (int i = 0; i < 4; ++i) {\n                // Action 1: Move (M)\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !G[nr][nc]) {\n                    if (dist[nr][nc] > d + 1) {\n                        dist[nr][nc] = d + 1;\n                        parent[nr][nc] = {r, c, 'M', i};\n                        pq.push({dist[nr][nc], nr, nc});\n                    }\n                }\n\n                // Action 2: Slide (S)\n                int sr = r, sc = c;\n                while (true) {\n                    int next_r = sr + dr[i], next_c = sc + dc[i];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                // A Slide is only considered if it actually results in a movement\n                if (sr != r || sc != c) {\n                    if (dist[sr][sc] > d + 1) {\n                        dist[sr][sc] = d + 1;\n                        parent[sr][sc] = {r, c, 'S', i};\n                        pq.push({dist[sr][sc], sr, sc});\n                    }\n                }\n            }\n        }\n\n        // Reconstruct the sequence of actions taken to reach target (tr, tc)\n        vector<pair<char, int>> path;\n        if (dist[tr][tc] == INF) {\n            // Safety fallback: manual Manhattan movement if Dijkstra fails\n            int temp_r = curr_r, temp_c = curr_c;\n            while (temp_r != tr) {\n                int d_dir = (tr > temp_r) ? 1 : 0;\n                path.push_back({'M', d_dir});\n                temp_r += dr[d_dir];\n            }\n            while (temp_c != tc) {\n                int d_dir = (tc > temp_c) ? 3 : 2;\n                path.push_back({'M', d_dir});\n                temp_c += dc[d_dir];\n            }\n        } else {\n            int pr = tr, pc = tc;\n            while (pr != curr_r || pc != curr_c) {\n                Parent p = parent[pr][pc];\n                path.push_back({p.action, p.dir});\n                pr = p.r; pc = p.c;\n            }\n            reverse(path.begin(), path.end());\n        }\n\n        // Output the actions and update current position\n        for (auto& step : path) {\n            cout << step.first << \" \" << dir_chars[step.second] << \"\\n\";\n            if (step.first == 'M') {\n                curr_r += dr[step.second];\n                curr_c += dc[step.second];\n            } else if (step.first == 'S') {\n                int sr = curr_r, sc = curr_c;\n                while (true) {\n                    int next_r = sr + dr[step.second], next_c = sc + dc[step.second];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                curr_r = sr; curr_c = sc;\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    solve();\n    return 0;\n}\n"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    int x, y, r, id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const {\n        return (ll)(x2 - x1) * (y2 - y1);\n    }\n};\n\nstruct RectTask {\n    Rect R;\n    vector<Point> P;\n    ll sum_r;\n    ll error;\n\n    // Max-priority queue to pick the rectangle with the largest error\n    bool operator<(const RectTask& other) const {\n        return error < other.error;\n    }\n};\n\nstruct SplitResult {\n    bool vertical;\n    int k;\n    int j; \n    double score;\n    ll sum_r_L;\n};\n\nint N;\nPoint points_orig[205];\nRect ans[205];\n\nvoid solve() {\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 gen(42);\n\n    double best_total_sat = -1.0;\n    Rect best_ans_res[205];\n\n    // Main loop: perform multiple randomized greedy constructions\n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 4500) break;\n\n        priority_queue<RectTask> pq;\n        ll total_r = 0;\n        vector<Point> P_init;\n        for (int i = 0; i < N; ++i) {\n            total_r += points_orig[i].r;\n            P_init.push_back(points_orig[i]);\n        }\n\n        // Initial task: the entire 10000x10000 area\n        pq.push({ {0, 0, 10000, 10000}, P_init, total_r, abs(100000000LL - total_r) });\n\n        Rect current_ans[205];\n\n        while (!pq.empty()) {\n            RectTask curr = pq.top();\n            pq.pop();\n\n            if (curr.P.size() == 1) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            int n = curr.P.size();\n            ll area_R = curr.R.area();\n            ll sum_r_P = curr.sum_r;\n            vector<SplitResult> possible_splits;\n\n            // Vertical splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.x < b.x;\n            });\n            ll sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].x < curr.P[j].x) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int H = curr.R.y2 - curr.R.y1;\n                    int target_k = curr.R.x1 + (int)round((double)target_area_L / H);\n                    int k = max(curr.P[j - 1].x + 1, min(curr.P[j].x, target_k));\n                    \n                    ll area_L = (ll)(k - curr.R.x1) * H;\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ true, k, j, score, sum_r_L });\n                }\n            }\n\n            // Horizontal splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.y < b.y;\n            });\n            sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].y < curr.P[j].y) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int W = curr.R.x2 - curr.R.x1;\n                    int target_k = curr.R.y1 + (int)round((double)target_area_L / W);\n                    int k = max(curr.P[j - 1].y + 1, min(curr.P[j].y, target_k));\n\n                    ll area_L = (ll)W * (k - curr.R.y1);\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ false, k, j, score, sum_r_L });\n                }\n            }\n\n            if (possible_splits.empty()) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            // Randomized selection from the best splits\n            sort(possible_splits.begin(), possible_splits.end(), [](const SplitResult& a, const SplitResult& b) {\n                return a.score < b.score;\n            });\n\n            int top_count = min((int)possible_splits.size(), 3);\n            uniform_int_distribution<int> dist(0, top_count - 1);\n            SplitResult best = possible_splits[dist(gen)];\n\n            // Re-sort points to correctly divide them\n            if (best.vertical) {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.x < b.x;\n                });\n            } else {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.y < b.y;\n                });\n            }\n\n            vector<Point> P_L, P_R;\n            for (int i = 0; i < best.j; ++i) P_L.push_back(curr.P[i]);\n            for (int i = best.j; i < n; ++i) P_R.push_back(curr.P[i]);\n\n            Rect R_L, R_R;\n            if (best.vertical) {\n                R_L = { curr.R.x1, curr.R.y1, best.k, curr.R.y2 };\n                R_R = { best.k, curr.R.y1, curr.R.x2, curr.R.y2 };\n            } else {\n                R_L = { curr.R.x1, curr.R.y1, curr.R.x2, best.k };\n                R_R = { curr.R.x1, best.k, curr.R.x2, curr.R.y2 };\n            }\n\n            ll sum_r_R = sum_r_P - best.sum_r_L;\n            pq.push({ R_L, P_L, best.sum_r_L, abs(R_L.area() - best.sum_r_L) });\n            pq.push({ R_R, P_R, sum_r_R, abs(R_R.area() - sum_r_R) });\n        }\n\n        // Evaluate the total satisfaction level\n        double current_sat = 0;\n        for (int i = 0; i < N; ++i) {\n            int xi = points_orig[i].x, yi = points_orig[i].y, ri = points_orig[i].r;\n            Rect r = current_ans[i];\n            if (xi >= r.x1 && xi < r.x2 && yi >= r.y1 && yi < r.y2) {\n                ll si = r.area();\n                double x = (double)min((ll)ri, si) / max((ll)ri, si);\n                current_sat += 1.0 - (1.0 - x) * (1.0 - x);\n            }\n        }\n\n        if (current_sat > best_total_sat) {\n            best_total_sat = current_sat;\n            for (int i = 0; i < N; ++i) best_ans_res[i] = current_ans[i];\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_res[i].x1 << \" \" << best_ans_res[i].y1 << \" \"\n             << best_ans_res[i].x2 << \" \" << best_ans_res[i].y2 << \"\\n\";\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> points_orig[i].x >> points_orig[i].y >> points_orig[i].r;\n        points_orig[i].id = i;\n    }\n    solve();\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a path in a 50x50 grid that maximizes the sum of values of visited squares.\n * The key constraint is that each tile (1x1, 1x2, or 2x1) can be stepped on at most once.\n * This implies that once we enter a square belonging to a certain tile, we cannot enter\n * any other square belonging to the same tile later in the path.\n *\n * Algorithm Choice:\n * This is a variation of the Longest Path problem, which is NP-hard. A robust way to \n * approach this in a competitive programming context is using a Randomized Beam Search.\n * \n * Improved Strategy:\n * 1. Multi-start Beam Search: Instead of a single search, we run multiple iterations of \n *    Beam Search with different parameters to explore diverse parts of the solution space.\n * 2. Intelligent Heuristic: For each potential next state, we calculate a heuristic \n *    that considers:\n *    - The current path score.\n *    - The estimated future potential (approximated by the number of unvisited tiles).\n *    - Connectivity (the number of unvisited adjacent tiles to the current square).\n * 3. Parameter Randomization: In each run, we randomly vary the beam width and the \n *    weights assigned to the score, remaining tiles, and connectivity.\n * 4. Efficient State Management: We use bitsets (represented by uint64_t arrays) to \n *    track visited tiles and pre-allocate memory for state management to maximize speed.\n */\n\n// Constants for the 50x50 grid\nconst int N = 50;\nconst int MAX_TILES = 2505;\nconst int NUM_U64 = (MAX_TILES + 63) / 64;\n\nint si, sj;\nint T[N][N];\nint P[N][N];\n\n// State structure for Beam Search\nstruct State {\n    int r, c;\n    int score;\n    uint64_t visited_tiles[NUM_U64];\n    int prev_idx;\n    char move;\n    float heuristic;\n    int visited_count;\n};\n\n// Movement vectors\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\n// Global best result found across all runs\nstring global_best_path = \"\";\nint global_best_score = -1;\n\n/**\n * solve_beam performs a single Beam Search iteration.\n * @param weight_tiles Weight for the estimated remaining score potential.\n * @param weight_neighbors Weight for the connectivity of the current square.\n * @param beam_width Number of paths to maintain in the beam at each step.\n * @param all_states Memory pool for all states visited in this iteration.\n */\nvoid solve_beam(int weight_tiles, int weight_neighbors, int beam_width, vector<State>& all_states) {\n    all_states.clear();\n    \n    // Initialize the starting state\n    State start;\n    start.r = si;\n    start.c = sj;\n    start.score = P[si][sj];\n    memset(start.visited_tiles, 0, sizeof(start.visited_tiles));\n    int start_tile = T[si][sj];\n    start.visited_tiles[start_tile / 64] |= (1ULL << (start_tile % 64));\n    start.prev_idx = -1;\n    start.move = ' ';\n    start.visited_count = 1;\n    start.heuristic = 0.0f;\n    all_states.push_back(start);\n\n    // current_beam stores indices of the most promising states from the previous step\n    vector<int> current_beam;\n    current_beam.push_back(0);\n\n    int best_idx_in_this_run = 0;\n\n    // Expand the path step-by-step\n    for (int step = 0; step < 2500; ++step) {\n        if (current_beam.empty()) break;\n\n        vector<int> next_beam_candidates;\n        next_beam_candidates.reserve(current_beam.size() * 4);\n\n        for (int idx : current_beam) {\n            const State& s = all_states[idx];\n\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i];\n                int nc = s.c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int nt = T[nr][nc];\n                    // Check if the tile of the target square has not been visited\n                    if (!(s.visited_tiles[nt / 64] & (1ULL << (nt % 64)))) {\n                        State next_s;\n                        next_s.r = nr;\n                        next_s.c = nc;\n                        next_s.score = s.score + P[nr][nc];\n                        memcpy(next_s.visited_tiles, s.visited_tiles, sizeof(next_s.visited_tiles));\n                        next_s.visited_tiles[nt / 64] |= (1ULL << (nt % 64));\n                        next_s.prev_idx = idx;\n                        next_s.move = move_char[i];\n                        next_s.visited_count = s.visited_count + 1;\n\n                        // Connectivity heuristic: count unvisited neighbors of the new square\n                        int next_neighbors = 0;\n                        for (int j = 0; j < 4; ++j) {\n                            int nnr = nr + dr[j];\n                            int nnc = nc + dc[j];\n                            if (nnr >= 0 && nnr < N && nnc >= 0 && nnc < N) {\n                                int nnt = T[nnr][nnc];\n                                if (!(next_s.visited_tiles[nnt / 64] & (1ULL << (nnt % 64)))) {\n                                    next_neighbors++;\n                                }\n                            }\n                        }\n\n                        // Heuristic = Current Score + Weight_Tiles * Remaining Potential + Weight_Neighbors * Connectivity\n                        next_s.heuristic = (float)next_s.score + \n                                           (float)weight_tiles * (MAX_TILES - next_s.visited_count) + \n                                           (float)weight_neighbors * next_neighbors;\n\n                        next_beam_candidates.push_back(all_states.size());\n                        all_states.push_back(next_s);\n\n                        if (all_states.back().score > all_states[best_idx_in_this_run].score) {\n                            best_idx_in_this_run = (int)all_states.size() - 1;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (next_beam_candidates.empty()) break;\n\n        // Sort candidates by heuristic for the next step of the beam search\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [&](int a, int b) {\n            return all_states[a].heuristic > all_states[b].heuristic;\n        });\n\n        // Update the beam with the top B candidates\n        current_beam.clear();\n        int num_to_keep = min((int)next_beam_candidates.size(), beam_width);\n        for (int i = 0; i < num_to_keep; ++i) {\n            current_beam.push_back(next_beam_candidates[i]);\n        }\n    }\n\n    // Update global best if this run found a superior path\n    if (all_states[best_idx_in_this_run].score > global_best_score) {\n        global_best_score = all_states[best_idx_in_this_run].score;\n        string path = \"\";\n        int curr = best_idx_in_this_run;\n        while (curr != -1 && all_states[curr].prev_idx != -1) {\n            path += all_states[curr].move;\n            curr = all_states[curr].prev_idx;\n        }\n        reverse(path.begin(), path.end());\n        global_best_path = path;\n    }\n}\n\nint main() {\n    // Optimization for standard input and output\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Parse input grid and tile data\n    if (!(cin >> si >> sj)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cin >> T[i][j];\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cin >> P[i][j];\n    }\n\n    clock_t start_time = clock();\n    mt19937 rng(42); // Seeded generator\n    \n    // Parameter distributions for randomized beam search\n    uniform_int_distribution<int> dist_w1(10, 120);\n    uniform_int_distribution<int> dist_w2(1, 40);\n    uniform_int_distribution<int> dist_bw(40, 100);\n\n    // Pre-allocate large pool for state memory management\n    vector<State> all_states;\n    all_states.reserve(500000);\n\n    // Continuously run randomized beam search as long as time permits\n    while (true) {\n        // Stop searching roughly 150ms before the 2.0s limit\n        if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n\n        int w1 = dist_w1(rng);\n        int w2 = dist_w2(rng);\n        int bw = dist_bw(rng);\n        \n        solve_beam(w1, w2, bw, all_states);\n    }\n\n    // Output the best path found\n    cout << global_best_path << endl;\n\n    return 0;\n}\n","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: Estimate unknown edge weights in a 30x30 grid graph through noisy feedback.\n * Strategy: Use Dijkstra's algorithm to find paths based on current estimates,\n * and update those estimates using a relaxed Kaczmarz method (stochastic gradient descent \n * on the error between the reported path length and our current estimated path length).\n * \n * The feedback L_k is a noisy measurement of the true path length b_k: L_k = round(b_k * e_k),\n * where e_k is uniformly random in [0.9, 1.1].\n * To deal with this noise, we use a decaying learning rate (eta).\n */\n\nconst int N = 30;\ndouble h[N][N - 1]; // horizontal edges: h[i][j] connects (i, j) and (i, j+1)\ndouble v[N - 1][N]; // vertical edges: v[i][j] connects (i, j) and (i+1, j)\n\nstruct Node {\n    int r, c;\n    double d;\n    bool operator>(const Node& other) const {\n        return d > other.d;\n    }\n};\n\nstruct Parent {\n    int r, c;\n    char dir;\n};\n\nParent parent[N][N];\ndouble dists[N][N];\n\n// Dijkstra's algorithm to find the shortest path from (sr, sc) to (tr, tc)\n// based on current edge weight estimates.\nvoid dijkstra(int sr, int sc, int tr, int tc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j] = 1e18;\n            parent[i][j] = {-1, -1, ' '};\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[sr][sc] = 0;\n    pq.push({sr, sc, 0.0});\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    while (!pq.empty()) {\n        Node top = pq.top();\n        pq.pop();\n\n        int r = top.r;\n        int c = top.c;\n        double d = top.d;\n\n        if (d > dists[r][c]) continue;\n        if (r == tr && c == tc) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = 0;\n                if (dirs[i] == 'U') weight = v[nr][c];\n                else if (dirs[i] == 'D') weight = v[r][c];\n                else if (dirs[i] == 'L') weight = h[r][nc];\n                else if (dirs[i] == 'R') weight = h[r][c];\n\n                if (dists[nr][nc] > d + weight) {\n                    dists[nr][nc] = d + weight;\n                    parent[nr][nc] = {r, c, dirs[i]};\n                    pq.push({nr, nc, dists[nr][nc]});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Increase speed of standard I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize edge weights to a reasonable middle value (average of expected range).\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Step 1: Compute path using Dijkstra's based on current estimates.\n        dijkstra(si, sj, ti, tj);\n\n        string path = \"\";\n        int cr = ti, cc = tj;\n        // Backtrack from destination to start to build the path string.\n        while (cr != si || cc != sj) {\n            Parent p = parent[cr][cc];\n            path += p.dir;\n            cr = p.r;\n            cc = p.c;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl; // endl ensures standard output is flushed.\n\n        // Step 2: Receive the reported path length (with 10% noise).\n        long long L_k;\n        if (!(cin >> L_k)) break;\n\n        // Step 3: Calculate the current path length according to our estimated weights.\n        double estimated_path_len = 0;\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                estimated_path_len += v[cr - 1][cc];\n                cr--;\n            } else if (d == 'D') {\n                estimated_path_len += v[cr][cc];\n                cr++;\n            } else if (d == 'L') {\n                estimated_path_len += h[cr][cc - 1];\n                cc--;\n            } else if (d == 'R') {\n                estimated_path_len += h[cr][cc];\n                cc++;\n            }\n        }\n\n        // Step 4: Update weights using the error diff = (reported_length - estimated_length).\n        // Using the Relaxed Kaczmarz method: w_e = w_e + (diff / |path|) * eta.\n        double diff = (double)L_k - estimated_path_len;\n        \n        // The learning rate eta decays slowly to manage the 10% noise and achieve convergence.\n        double eta = 0.5 * pow(0.9975, k);\n        double step = (diff / (double)path.size()) * eta;\n\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                v[cr - 1][cc] += step;\n                cr--;\n            } else if (d == 'D') {\n                v[cr][cc] += step;\n                cr++;\n            } else if (d == 'L') {\n                h[cr][cc - 1] += step;\n                cc--;\n            } else if (d == 'R') {\n                h[cr][cc] += step;\n                cc++;\n            }\n        }\n\n        // Step 5: Maintain edge weights within physically reasonable bounds.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) if (h[i][j] < 100.0) h[i][j] = 100.0;\n            if (i < N - 1) {\n                for (int j = 0; j < N; ++j) if (v[i][j] < 100.0) v[i][j] = 100.0;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find an N x N (N=20) matrix of characters A-H or '.' that satisfies \n * as many of M (400-800) given strings as possible. The matrix is a torus.\n * Scoring:\n * - If c < M: 10^8 * (c / M)\n * - If c = M: 10^8 * (2 * N^2 / (2 * N^2 - d)), where d is the number of '.' characters.\n * \n * Strategy:\n * 1. Use Simulated Annealing (SA) to maximize the number of satisfied strings (c).\n *    The state is an N x N matrix of characters A-H.\n *    An efficient way to update c during SA is to maintain a mismatch count for \n *    each possible occurrence of each string.\n * 2. If c = M is achieved, use a greedy approach to maximize the number of '.' characters (d).\n *    Replace characters with '.' as long as no string is lost.\n * \n * Complexity:\n * - SA: O(iterations * (number of occurrences covering a cell) * (strings per length))\n * - Pre-calculation: O(N^2 * M * L)\n */\n\nint N, M;\nstring s[800];\nchar A[20][20];\nint counts[800]; // Number of occurrences of string s[k] currently satisfied\nint c_satisfied = 0;\nvector<int> strings_by_len[13];\nvector<int> mismatch_count[2][20][20][13];\n\nstruct Occ {\n    int t, line, start, len, p, idx, k;\n};\nvector<Occ> cell_occs[20][20];\n\nstruct Change {\n    int t, line, start, len, idx, k;\n    int old_m, old_count_k;\n};\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        strings_by_len[s[i].length()].push_back(i);\n    }\n\n    // Initial random matrix of A-H\n    mt19937 rng(42);\n    string chars = \"ABCDEFGH\";\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = chars[rng() % 8];\n        }\n    }\n\n    // Pre-calculate mismatch counts for each occurrence of each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    mismatch_count[t][i][j][len].resize(strings_by_len[len].size());\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        int k = strings_by_len[len][idx];\n                        int mismatches = 0;\n                        for (int p = 0; p < len; ++p) {\n                            int ni = (t == 0) ? i : (i + p) % N;\n                            int nj = (t == 0) ? (j + p) % N : j;\n                            if (A[ni][nj] != s[k][p]) mismatches++;\n                        }\n                        mismatch_count[t][i][j][len][idx] = mismatches;\n                    }\n                }\n            }\n        }\n    }\n\n    // Calculate the number of satisfied occurrences for each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        if (mismatch_count[t][i][j][len][idx] == 0) {\n                            counts[strings_by_len[len][idx]]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    for (int k = 0; k < M; ++k) if (counts[k] > 0) c_satisfied++;\n\n    // Pre-calculate which occurrences cover which cell (i, j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int t = 0; t < 2; ++t) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int p = 0; p < len; ++p) {\n                        int line = (t == 0) ? i : (i - p + N) % N;\n                        int start = (t == 0) ? (j - p + N) % N : j;\n                        for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                            cell_occs[i][j].push_back({t, line, start, len, p, idx, strings_by_len[len][idx]});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulated Annealing phase\n    auto start_time = chrono::high_resolution_clock::now();\n    int max_iter = 250000;\n    vector<Change> changes;\n    changes.reserve(15000); \n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        if ((iter & 1023) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2600) break;\n        }\n\n        int r = rng() % (N * N);\n        int i = r / N, j = r % N;\n        char old_v = A[i][j];\n        char new_v = chars[rng() % 8];\n        if (old_v == new_v) continue;\n\n        double T = 1.0 * (1.0 - (double)iter / max_iter);\n        int delta_c = 0;\n        changes.clear();\n\n        for (auto& occ : cell_occs[i][j]) {\n            int& m = mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx];\n            int old_m = m;\n            if (old_v != s[occ.k][occ.p] && new_v == s[occ.k][occ.p]) m--;\n            else if (old_v == s[occ.k][occ.p] && new_v != s[occ.k][occ.p]) m++;\n            \n            if (old_m == 0 && m > 0) {\n                if (--counts[occ.k] == 0) delta_c--;\n            } else if (old_m > 0 && m == 0) {\n                if (++counts[occ.k] == 1) delta_c++;\n            }\n            changes.push_back({occ.t, occ.line, occ.start, occ.len, occ.idx, occ.k, old_m, counts[occ.k]});\n        }\n\n        if (delta_c >= 0 || (T > 1e-9 && (double)rng() / rng.max() < exp(delta_c / T))) {\n            A[i][j] = new_v;\n            c_satisfied += delta_c;\n        } else {\n            for (int idx = (int)changes.size() - 1; idx >= 0; --idx) {\n                auto& ch = changes[idx];\n                mismatch_count[ch.t][ch.line][ch.start][ch.len][ch.idx] = ch.old_m;\n                counts[ch.k] = ch.old_count_k;\n            }\n        }\n    }\n\n    // Phase 2: Maximize density (number of '.') if all strings are satisfied\n    if (c_satisfied == M) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (A[i][j] != '.') {\n                    char old_v = A[i][j];\n                    vector<int> matching_occs_using_ij(M, 0);\n                    for (auto& occ : cell_occs[i][j]) {\n                        if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                            matching_occs_using_ij[occ.k]++;\n                        }\n                    }\n                    bool ok = true;\n                    for (int k = 0; k < M; ++k) {\n                        if (matching_occs_using_ij[k] > 0 && counts[k] == matching_occs_using_ij[k]) {\n                            ok = false; \n                            break;\n                        }\n                    }\n                    if (ok) {\n                        A[i][j] = '.';\n                        for (auto& occ : cell_occs[i][j]) {\n                            if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                                counts[occ.k]--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << A[i][j];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a shortest patrol route that visits road squares such that\n * all road squares become \"visible\" at least once.\n * A square is visible if it's in the same row/column and no obstacles are between.\n * \n * Strategy:\n * 1. Represent the map and precompute visibility (which squares can see each other).\n * 2. Use a greedy strategy to pick a subset of road squares (ToVisit) that covers\n *    the most \"uncovered\" road squares with the minimum distance.\n * 3. The greedy heuristic: Pick the \"hardest-to-cover\" square (one with fewest \n *    potential visitors) and then pick the best visitor (maximizing newly covered / distance).\n * 4. Once the set of points to visit is found, solve the Traveling Salesperson Problem (TSP)\n *    on these points using a Nearest Neighbor heuristic followed by 2-opt refinement.\n * 5. Convert the TSP tour into the actual move string (U, D, L, R).\n */\n\nconst int INF = 1e9;\n\nint N, si, sj;\nint grid[70][70];\nvector<int> C[5000], S[5000];\nbool is_road[5000];\nint dists[5000];\nint parent_node[5000];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Standard Dijkstra to find shortest path distances from a source node\nvoid dijkstra(int start, int n_size) {\n    for (int i = 0; i < n_size; ++i) dists[i] = INF;\n    dists[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n\n    while (!pq.empty()) {\n        int d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n\n        if (d > dists[u]) continue;\n\n        int r = u / N, c = u % N;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != -1) {\n                int v = nr * N + nc;\n                if (dists[u] + grid[nr][nc] < dists[v]) {\n                    dists[v] = dists[u] + grid[nr][nc];\n                    parent_node[v] = u;\n                    pq.push({dists[v], v});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> si >> sj)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            if (row[j] == '#') {\n                grid[i][j] = -1;\n                is_road[i * N + j] = false;\n            } else {\n                grid[i][j] = row[j] - '0';\n                is_road[i * N + j] = true;\n            }\n        }\n    }\n\n    // Precompute visibility\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!is_road[i * N + j]) continue;\n            int u = i * N + j;\n            C[u].push_back(u);\n            S[u].push_back(u);\n            // Horizontal\n            for (int k = j - 1; k >= 0 && grid[i][k] != -1; --k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = j + 1; k < N && grid[i][k] != -1; ++k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            // Vertical\n            for (int k = i - 1; k >= 0 && grid[k][j] != -1; --k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = i + 1; k < N && grid[k][j] != -1; ++k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n        }\n    }\n\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            sort(C[i].begin(), C[i].end());\n            C[i].erase(unique(C[i].begin(), C[i].end()), C[i].end());\n            sort(S[i].begin(), S[i].end());\n            S[i].erase(unique(S[i].begin(), S[i].end()), S[i].end());\n        }\n    }\n\n    // Set Cover Greedy\n    vector<bool> is_uncovered(N * N, false);\n    vector<int> uncovered_list;\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            is_uncovered[i] = true;\n            uncovered_list.push_back(i);\n        }\n    }\n\n    vector<int> ToVisit;\n    int curr = si * N + sj;\n    while (!uncovered_list.empty()) {\n        dijkstra(curr, N * N);\n        int best_r = -1;\n        int min_S_r = 1000000;\n        for (int r : uncovered_list) {\n            if ((int)S[r].size() < min_S_r) {\n                min_S_r = S[r].size();\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break;\n\n        int best_v = -1;\n        double best_gain = -1.0;\n        for (int v : S[best_r]) {\n            int gain = 0;\n            for (int road_idx : C[v]) {\n                if (is_uncovered[road_idx]) gain++;\n            }\n            double current_gain = (double)gain / (dists[v] + 1.0);\n            if (current_gain > best_gain) {\n                best_gain = current_gain;\n                best_v = v;\n            }\n        }\n        if (best_v == -1 || best_gain <= 0.0) break;\n\n        ToVisit.push_back(best_v);\n        for (int road_idx : C[best_v]) {\n            is_uncovered[road_idx] = false;\n        }\n        \n        vector<int> next_uncovered;\n        for (int r : uncovered_list) {\n            if (is_uncovered[r]) next_uncovered.push_back(r);\n        }\n        uncovered_list = next_uncovered;\n        curr = best_v;\n    }\n\n    // TSP Step: Nearest Neighbor + 2-opt\n    vector<int> P;\n    P.push_back(si * N + sj);\n    set<int> seen;\n    seen.insert(si * N + sj);\n    for (int v : ToVisit) {\n        if (seen.find(v) == seen.end()) {\n            P.push_back(v);\n            seen.insert(v);\n        }\n    }\n\n    int k_points = P.size();\n    vector<vector<int>> dist_matrix(k_points, vector<int>(k_points, INF));\n    for (int i = 0; i < k_points; ++i) {\n        dijkstra(P[i], N * N);\n        for (int j = 0; j < k_points; ++j) {\n            dist_matrix[i][j] = dists[P[j]];\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited_tsp(k_points, false);\n    int current_idx = 0;\n    tour.push_back(0);\n    visited_tsp[0] = true;\n    for (int step = 1; step < k_points; ++step) {\n        int next_idx = -1;\n        int min_d = INF;\n        for (int j = 0; j < k_points; ++j) {\n            if (!visited_tsp[j] && dist_matrix[current_idx][j] < min_d) {\n                min_d = dist_matrix[current_idx][j];\n                next_idx = j;\n            }\n        }\n        if (next_idx == -1) break;\n        tour.push_back(next_idx);\n        visited_tsp[next_idx] = true;\n        current_idx = next_idx;\n    }\n    tour.push_back(0);\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 1; i < sz - 2; ++i) {\n            for (int j = i + 1; j < sz - 1; ++j) {\n                if (dist_matrix[tour[i - 1]][tour[i]] + dist_matrix[tour[j]][tour[j + 1]] >\n                    dist_matrix[tour[i - 1]][tour[j]] + dist_matrix[tour[i]][tour[j + 1]]) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Final Path Reconstruction\n    string final_route = \"\";\n    for (int i = 0; i < (int)tour.size() - 1; ++i) {\n        int u = P[tour[i]];\n        int v = P[tour[i+1]];\n        if (u == v) continue;\n        dijkstra(u, N * N);\n        vector<int> path_nodes;\n        int curr_node = v;\n        while (curr_node != u) {\n            path_nodes.push_back(curr_node);\n            curr_node = parent_node[curr_node];\n        }\n        reverse(path_nodes.begin(), path_nodes.end());\n        \n        int prev_r = u / N, prev_c = u % N;\n        for (int node : path_nodes) {\n            int nr = node / N, nc = node % N;\n            if (nr == prev_r + 1) final_route += 'D';\n            else if (nr == prev_r - 1) final_route += 'U';\n            else if (nc == prev_c + 1) final_route += 'R';\n            else if (nc == prev_c - 1) final_route += 'L';\n            prev_r = nr;\n            prev_c = nc;\n        }\n    }\n    cout << final_route << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis & Improvements:\n * \n * 1. Skill Estimation:\n *    - We use Stochastic Gradient Descent (SGD) to update the skill level estimates.\n *    - The expected time E[t_{i,j}] is approx max(1, w_{i,j}), where w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k}).\n *    - If the actual time T_{i,j} differs from the estimated E[t_{i,j}], we update the skill s_{j,k}\n *      for all k where d_{i,k} > s_{j,k}.\n *    - Update rule: s_{j,k} = s_{j,k} - eta * (T_{i,j} - E[t_{i,j}]) * ( (d_{i,k} - s_{j,k}) / w_{i,j} ).\n * \n * 2. Task Prioritization (Critical Path Method):\n *    - Instead of a static rank, we use a dynamic Critical Path (CP) estimate.\n *    - CP(i) = AvgT(i) + max_{v in adj(i)} CP(v), where AvgT(i) is the average expected time for task i across all members.\n *    - This CP is recalculated every day to reflect our current understanding of the members' skills.\n * \n * 3. Greedy Scheduling Strategy:\n *    - We sort the available tasks by their dynamic CP value in descending order.\n *    - For each task in the sorted list, we assign it to the currently idle member who can complete it most quickly.\n *    - This ensures that critical tasks are prioritized and assigned to the most efficient available members.\n * \n * 4. Computational Efficiency:\n *    - Calculating CP and expected times takes O(N*M*K) per day.\n *    - Sorting and greedy matching take O(N*log N + N*M*K).\n *    - Total complexity is O(Days * N * M * K), which is roughly 2000 * 1000 * 20 * 20 = 8e8 operations.\n *    - This fits within the 3.0s time limit in C++.\n */\n\nint main() {\n    // Fast I/O for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task requirement skill levels\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    // Task dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // Topological sort to calculate CP in correct order\n    vector<int> topo_order;\n    vector<int> temp_in_degree = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (temp_in_degree[i] == 0) q.push(i);\n    }\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        topo_order.push_back(u);\n        for (int v : adj[u]) {\n            if (--temp_in_degree[v] == 0) q.push(v);\n        }\n    }\n\n    // State management\n    vector<vector<double>> s(M, vector<double>(K, 0.0)); // Skill level estimates\n    vector<int> task_status(N, 0);        // 0: not started, 1: in progress, 2: completed\n    vector<int> member_current_task(M, -1); // -1 if idle, else task index\n    vector<int> task_start_day(N, 0);     // Start day of task i\n    vector<vector<double>> E_t(N, vector<double>(M)); // Expected time for task i by member j\n    vector<double> avg_t(N);              // Average expected time for task i\n    vector<double> cp(N);                 // Critical path value for task i\n\n    int current_day = 1;\n    while (current_day <= 2000) {\n        // 1. Recalculate expected times and average task time\n        for (int i = 0; i < N; ++i) {\n            double sum_e = 0;\n            for (int j = 0; j < M; ++j) {\n                double w_ij = 0;\n                for (int k = 0; k < K; ++k) {\n                    double diff = (double)d[i][k] - s[j][k];\n                    if (diff > 0) w_ij += diff;\n                }\n                E_t[i][j] = (w_ij < 1.0 ? 1.0 : w_ij);\n                sum_e += E_t[i][j];\n            }\n            avg_t[i] = sum_e / M;\n        }\n\n        // 2. Recalculate Critical Path (CP) values using topological order\n        for (int i = N - 1; i >= 0; --i) {\n            int u = topo_order[i];\n            double max_next_cp = 0;\n            for (int v : adj[u]) {\n                if (cp[v] > max_next_cp) max_next_cp = cp[v];\n            }\n            cp[u] = avg_t[u] + max_next_cp;\n        }\n\n        // 3. Identify available tasks and idle members\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] == 0 && in_degree[i] == 0) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // 4. Greedy matching based on task priority (CP) and speed (E[t])\n        // Sort available tasks by Critical Path value descending\n        sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n            return cp[a] > cp[b];\n        });\n\n        struct Assignment {\n            int m, t;\n        };\n        vector<Assignment> current_day_assignments;\n        vector<bool> member_used_today(M, false);\n\n        for (int i : available_tasks) {\n            int best_j = -1;\n            double min_et = 1e18;\n\n            for (int j : idle_members) {\n                if (member_used_today[j]) continue;\n                if (E_t[i][j] < min_et) {\n                    min_et = E_t[i][j];\n                    best_j = j;\n                }\n            }\n\n            if (best_j != -1) {\n                current_day_assignments.push_back({best_j, i});\n                member_used_today[best_j] = true;\n                task_status[i] = 1;\n                member_current_task[best_j] = i;\n                task_start_day[i] = current_day;\n            }\n        }\n\n        // 5. Output the assignments\n        cout << current_day_assignments.size();\n        for (auto& assign : current_day_assignments) {\n            cout << \" \" << assign.m + 1 << \" \" << assign.t + 1;\n        }\n        cout << endl;\n\n        // 6. Read feedback on completed tasks\n        int num_completed;\n        if (!(cin >> num_completed)) break;\n        if (num_completed == -1) break;\n\n        // 7. Update skill estimates (SGD) and task dependencies\n        for (int idx = 0; idx < num_completed; ++idx) {\n            int f;\n            cin >> f;\n            --f; // 0-indexed member\n            int t_idx = member_current_task[f];\n            int actual_t = current_day - task_start_day[t_idx] + 1;\n\n            // Recalculate current w_ij estimate for error calculation\n            double w_ij_est = 0;\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) w_ij_est += diff;\n            }\n            if (w_ij_est < 1e-7) w_ij_est = 1e-7; // Prevent division by zero\n\n            double error = (double)actual_t - E_t[t_idx][f];\n            double eta = 0.2 / (1.0 + 0.005 * current_day); // Learning rate decay\n\n            // Refined SGD update for skill levels\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) {\n                    double contribution = diff / w_ij_est;\n                    s[f][k] -= eta * error * contribution;\n                    if (s[f][k] < 0) s[f][k] = 0;\n                }\n            }\n\n            // Mark task as completed and update dependency graph\n            task_status[t_idx] = 2;\n            member_current_task[f] = -1;\n            for (int v : adj[t_idx]) {\n                in_degree[v]--;\n            }\n        }\n        current_day++;\n    }\n\n    return 0;\n}\n","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We need to select 50 orders out of 1000 and find an optimal route that visits each selected order's\n * restaurant (pickup) then its destination (delivery), starting and ending at (400, 400).\n * This is a Pickup and Delivery Problem (PDP), a variant of the Traveling Salesman Problem (TSP).\n * \n * Key Insights:\n * 1. The total number of points in the sequence is 100 (50 pickups + 50 deliveries).\n * 2. The precedence constraint (pickup must occur before delivery for each order) is critical.\n * 3. Simulated Annealing (SA) is an effective heuristic for this NP-hard problem.\n * 4. We can optimize both the set of 50 orders and the sequence of points.\n * \n * Optimization Strategy:\n * - Initial State: Select 50 orders with the smallest individual round-trip Manhattan distance.\n * - Moves in SA:\n *   - Swap: Swap two points in the delivery sequence (ensuring precedence is maintained).\n *   - Reinsert: Move one point in the sequence to a new position (ensuring precedence).\n *   - Replace: Remove one order from the set S and add a new one from the remaining 950, \n *     inserting its pickup/delivery points at new valid indices.\n * - Cooling Schedule: Exponential cooling from T_start to T_end.\n */\n\nstruct Order {\n    int a, b, c, d, id;\n};\n\nstruct Point {\n    int x, y, order_idx;\n    bool is_pickup;\n};\n\n// Manhattan distance calculation\ninline int dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Total travel distance for the current route (including return to office)\nint total_dist(const vector<Point>& P) {\n    if (P.empty()) return 0;\n    int d = 0;\n    d += dist(400, 400, P[0].x, P[0].y);\n    for (size_t i = 0; i < P.size() - 1; ++i) {\n        d += dist(P[i].x, P[i].y, P[i + 1].x, P[i + 1].y);\n    }\n    d += dist(P.back().x, P.back().y, 400, 400);\n    return d;\n}\n\n// Finds the indices of the pickup and delivery for a given order in the sequence\npair<int, int> find_indices(const vector<Point>& P, int order_idx) {\n    int pa = -1, pc = -1;\n    for (int k = 0; k < (int)P.size(); ++k) {\n        if (P[k].order_idx == order_idx) {\n            if (P[k].is_pickup) pa = k;\n            else pc = k;\n        }\n    }\n    return {pa, pc};\n}\n\n// Checks if the pickup-before-delivery constraint is still met for a specific order\nbool check_order_valid(const vector<Point>& P, int order_idx) {\n    int pa = -1, pc = -1;\n    for (int k = 0; k < (int)P.size(); ++k) {\n        if (P[k].order_idx == order_idx) {\n            if (P[k].is_pickup) pa = k;\n            else pc = k;\n        }\n    }\n    return (pa != -1 && pc != -1 && pa < pc);\n}\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<Order> all_orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        if (!(cin >> all_orders[i].a >> all_orders[i].b >> all_orders[i].c >> all_orders[i].d)) break;\n        all_orders[i].id = i + 1;\n    }\n\n    // Heuristic to pick initial 50 orders: smallest round-trip distance\n    vector<pair<int, int>> costs;\n    for (int i = 0; i < 1000; ++i) {\n        int d = dist(400, 400, all_orders[i].a, all_orders[i].b) +\n                dist(all_orders[i].a, all_orders[i].b, all_orders[i].c, all_orders[i].d) +\n                dist(all_orders[i].c, all_orders[i].d, 400, 400);\n        costs.push_back({d, i});\n    }\n    sort(costs.begin(), costs.end());\n\n    vector<int> S, not_S;\n    vector<bool> in_S(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        S.push_back(costs[i].second);\n        in_S[costs[i].second] = true;\n    }\n    for (int i = 0; i < 1000; ++i) {\n        if (!in_S[i]) not_S.push_back(i);\n    }\n\n    // Initial route: interleaved pickup and delivery\n    vector<Point> P;\n    for (int idx : S) {\n        P.push_back({all_orders[idx].a, all_orders[idx].b, idx, true});\n        P.push_back({all_orders[idx].c, all_orders[idx].d, idx, false});\n    }\n\n    int current_dist = total_dist(P);\n    vector<Point> best_P = P;\n    vector<int> best_S = S;\n    int best_dist = current_dist;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    // Simulated Annealing parameters\n    double T_start = 1000.0;\n    double T_end = 0.1;\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        // Check time limit every 2000 iterations\n        if (iter % 2000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n            if (elapsed >= 1.0) break;\n        }\n\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n        double T = T_start * pow(T_end / T_start, elapsed);\n\n        int move_type = rng() % 100;\n        if (move_type < 40) { // Type 0: Swap two points in sequence\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            int ord_j = P[j].order_idx;\n            swap(P[i], P[j]);\n            if (check_order_valid(P, ord_i) && check_order_valid(P, ord_j)) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    swap(P[i], P[j]);\n                }\n            } else {\n                swap(P[i], P[j]);\n            }\n        } else if (move_type < 70) { // Type 1: Reinsert a point\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            Point p = P[i];\n            P.erase(P.begin() + i);\n            P.insert(P.begin() + j, p);\n            if (check_order_valid(P, ord_i)) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    P.erase(P.begin() + j);\n                    P.insert(P.begin() + i, p);\n                }\n            } else {\n                P.erase(P.begin() + j);\n                P.insert(P.begin() + i, p);\n            }\n        } else { // Type 2: Replace an entire order\n            int i_idx = rng() % 50;\n            int j_idx = rng() % (int)not_S.size();\n            int old_ord = S[i_idx];\n            int new_ord = not_S[j_idx];\n\n            pair<int, int> pos = find_indices(P, old_ord);\n            int pa = pos.first;\n            int pc = pos.second;\n\n            // Copy state for rollback\n            vector<Point> old_P = P;\n            vector<int> old_S = S;\n            vector<int> old_not_S = not_S;\n\n            // Remove the old order's points\n            if (pa < pc) {\n                P.erase(P.begin() + pc);\n                P.erase(P.begin() + pa);\n            } else {\n                P.erase(P.begin() + pa);\n                P.erase(P.begin() + pc);\n            }\n            \n            // Choose new indices for the new order\n            int new_i = rng() % P.size();\n            int new_j = rng() % P.size();\n            if (new_i > new_j) swap(new_i, new_j);\n\n            // Insert new points (ensuring A < C)\n            P.insert(P.begin() + new_j, {all_orders[new_ord].c, all_orders[new_ord].d, new_ord, false});\n            P.insert(P.begin() + new_i, {all_orders[new_ord].a, all_orders[new_ord].b, new_ord, true});\n\n            S[i_idx] = new_ord;\n            not_S[j_idx] = old_ord;\n\n            int new_dist = total_dist(P);\n            if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                current_dist = new_dist;\n                if (current_dist < best_dist) {\n                    best_dist = current_dist;\n                    best_P = P;\n                    best_S = S;\n                }\n            } else {\n                P = old_P;\n                S = old_S;\n                not_S = old_not_S;\n            }\n        }\n    }\n\n    // Final Output\n    cout << 50;\n    for (int idx : best_S) cout << \" \" << all_orders[idx].id;\n    cout << endl;\n    cout << best_P.size() + 2;\n    cout << \" 400 400\";\n    for (const auto& p : best_P) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \" 400 400\" << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem: Online Minimum Spanning Tree with uncertain future edge weights.\n * Strategy: Monte Carlo simulation to estimate the bottleneck weight of alternative paths.\n * Complexity: O(M * K * M log M), where M is the number of edges and K is the number of samples.\n * With M=2000 and K=10, total operations are approximately 4e8, fitting in 2s.\n */\n\n// Fast Disjoint Set Union (DSU) for bottleneck calculations\nstruct FastDSU {\n    int parent[405];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    int find(int i) {\n        int root = i;\n        while (parent[root] != root) root = parent[root];\n        while (parent[i] != root) {\n            int next = parent[i];\n            parent[i] = root;\n            i = next;\n        }\n        return root;\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v, d, l, id;\n};\n\nstruct SimEdge {\n    int u, v, w;\n    bool operator<(const SimEdge& other) const {\n        return w < other.w;\n    }\n};\n\n// Global buffers to avoid repeated allocations in the loop\nSimEdge sim_edges[2500];\nFastDSU dsu;\nFastDSU dsu_S;\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    const int N = 400;\n    const int M = 1995;\n    const int K = 10; // Number of Monte Carlo samples\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> coords[i].first >> coords[i].second)) break;\n    }\n\n    vector<Edge> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) break;\n        all_edges[i].u = u;\n        all_edges[i].v = v;\n        all_edges[i].id = i;\n        double dx = (double)coords[u].first - coords[v].first;\n        double dy = (double)coords[u].second - coords[v].second;\n        all_edges[i].d = (int)round(hypot(dx, dy));\n    }\n\n    vector<int> S;\n    S.reserve(N);\n    dsu_S.init(N);\n\n    // Random number generator for sampling future weights\n    mt19937 rng(42);\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n        all_edges[i].l = l_i;\n\n        int u_i = all_edges[i].u;\n        int v_i = all_edges[i].v;\n\n        // If u and v are already connected, adding this edge only adds cost.\n        if (dsu_S.find(u_i) == dsu_S.find(v_i)) {\n            cout << \"0\" << endl; // endl performs flush\n        } else {\n            int Ws[K];\n            for (int k = 0; k < K; ++k) {\n                int edge_count = 0;\n                // 1. Include edges already adopted in our MST\n                for (int idx : S) {\n                    sim_edges[edge_count++] = {all_edges[idx].u, all_edges[idx].v, all_edges[idx].l};\n                }\n                // 2. Include future edges with sampled weights\n                for (int j = i + 1; j < M; ++j) {\n                    int d_j = all_edges[j].d;\n                    // Sample weight uniformly from [d_j, 3*d_j]\n                    int weight = d_j + (rng() % (2 * d_j + 1));\n                    sim_edges[edge_count++] = {all_edges[j].u, all_edges[j].v, weight};\n                }\n\n                // 3. Sort edges to find the bottleneck weight using Kruskal's logic\n                sort(sim_edges, sim_edges + edge_count);\n\n                dsu.init(N);\n                int W_k = 2000000000; // Infinity placeholder\n                for (int e = 0; e < edge_count; ++e) {\n                    dsu.unite(sim_edges[e].u, sim_edges[e].v);\n                    if (dsu.find(u_i) == dsu.find(v_i)) {\n                        W_k = sim_edges[e].w;\n                        break;\n                    }\n                }\n                Ws[k] = W_k;\n            }\n\n            // 4. Use the median of simulated bottlenecks as the decision threshold\n            sort(Ws, Ws + K);\n            int W_median = Ws[K / 2];\n\n            if (l_i < W_median) {\n                cout << \"1\" << endl;\n                S.push_back(i);\n                dsu_S.unite(u_i, v_i);\n            } else {\n                cout << \"0\" << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * Goal: Maximize human satisfaction score.\n * Scoring: s_i = (|R_i| / 900) * 2^(-n_i), where |R_i| is the reachable area for human i \n * and n_i is the number of pets in that area.\n * Key Strategy:\n * 1. Maintain n_i = 0 by enclosing the human in a wall.\n * 2. The \"impassable\" action is powerful but restricted by the \"no pet or adjacent square has a pet\" rule.\n * 3. Use each human to target and build a boundary of a large rectangle containing them and no pets.\n * 4. Manage simultaneous actions and conflicts (two people building the same square, or moving into a square being blocked).\n */\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nstruct Pet {\n    Pos p;\n    int type;\n};\n\nstruct Human {\n    Pos p;\n    int id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool impassable[31][31];\n\nbool is_valid(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\n// Checks if a square is safe to make impassable\nbool is_safe(int x, int y, const vector<Pet>& cur_pets, const vector<Human>& cur_humans) {\n    if (!is_valid(x, y) || impassable[x][y]) return false;\n    for (const auto& p : cur_pets) {\n        if (p.p.x == x && p.p.y == y) return false;\n        // The square or any adjacent square cannot contain a pet.\n        if (abs(p.p.x - x) + abs(p.p.y - y) <= 1) return false;\n    }\n    for (const auto& h : cur_humans) {\n        if (h.p.x == x && h.p.y == y) return false;\n    }\n    return true;\n}\n\n// BFS to find a path of passable squares\nvector<Pos> get_path(Pos start, Pos end) {\n    if (start == end) return {};\n    queue<Pos> q;\n    q.push(start);\n    vector<vector<Pos>> parent(31, vector<Pos>(31, {0, 0}));\n    vector<vector<bool>> visited(31, vector<bool>(31, false));\n    visited[start.x][start.y] = true;\n    bool found = false;\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n        if (curr == end) {\n            found = true;\n            break;\n        }\n        int dx[] = {-1, 1, 0, 0};\n        int dy[] = {0, 0, -1, 1};\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.x + dx[i], ny = curr.y + dy[i];\n            if (is_valid(nx, ny) && !visited[nx][ny] && !impassable[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n    if (!found) return {};\n    vector<Pos> path;\n    Pos curr = end;\n    while (curr != start) {\n        path.push_back(curr);\n        curr = parent[curr.x][curr.y];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    pets.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pets[i].p.x >> pets[i].p.y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humans[i].p.x >> humans[i].p.y;\n        humans[i].id = i;\n    }\n\n    for (int i = 1; i <= 30; ++i)\n        for (int j = 1; j <= 30; ++j)\n            impassable[i][j] = false;\n\n    // Pre-calculate potential boundaries (rectangles with no pets containing the human)\n    vector<vector<Pos>> human_boundaries(M);\n    for (int i = 0; i < M; ++i) {\n        int max_area = 0;\n        Rect best_rect = {humans[i].p.x, humans[i].p.y, humans[i].p.x, humans[i].p.y};\n        for (int x1 = 1; x1 <= humans[i].p.x; ++x1) {\n            for (int x2 = humans[i].p.x; x2 <= 30; ++x2) {\n                for (int y1 = 1; y1 <= humans[i].p.y; ++y1) {\n                    for (int y2 = humans[i].p.y; y2 <= 30; ++y2) {\n                        bool has_pet = false;\n                        for (const auto& pet : pets) {\n                            if (pet.p.x >= x1 && pet.p.x <= x2 && pet.p.y >= y1 && pet.p.y <= y2) {\n                                has_pet = true; break;\n                            }\n                        }\n                        if (!has_pet) {\n                            int area = (x2 - x1 + 1) * (y2 - y1 + 1);\n                            if (area > max_area) {\n                                max_area = area;\n                                best_rect = {x1, y1, x2, y2};\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for (int x = best_rect.x1; x <= best_rect.x2; ++x) {\n            human_boundaries[i].push_back({x, best_rect.y1});\n            human_boundaries[i].push_back({x, best_rect.y2});\n        }\n        for (int y = best_rect.y1 + 1; y < best_rect.y2; ++y) {\n            human_boundaries[i].push_back({best_rect.x1, y});\n            human_boundaries[i].push_back({best_rect.x2, y});\n        }\n        sort(human_boundaries[i].begin(), human_boundaries[i].end(), [](Pos a, Pos b) {\n            return a.x < b.x || (a.x == b.x && a.y < b.y);\n        });\n        human_boundaries[i].erase(unique(human_boundaries[i].begin(), human_boundaries[i].end()), human_boundaries[i].end());\n    }\n\n    for (int turn = 0; turn < 300; ++turn) {\n        struct IntendedAction {\n            char type; // 'B' build, 'M' move, '.' nothing\n            Pos target_impassable;\n            Pos move_to;\n        };\n        vector<IntendedAction> intended(M, {'.', {0, 0}, {0, 0}});\n\n        for (int i = 0; i < M; ++i) {\n            Pos best_T = {0, 0};\n            int min_dist = 1000;\n            for (const auto& T : human_boundaries[i]) {\n                if (is_safe(T.x, T.y, pets, humans)) {\n                    int d = abs(humans[i].p.x - T.x) + abs(humans[i].p.y - T.y);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_T = T;\n                    }\n                }\n            }\n\n            if (best_T.x != 0) {\n                if (min_dist == 1) {\n                    intended[i].type = 'B';\n                    intended[i].target_impassable = best_T;\n                } else {\n                    intended[i].type = 'M';\n                    intended[i].target_impassable = best_T;\n                    vector<Pos> path = get_path(humans[i].p, best_T);\n                    if (!path.empty()) {\n                        intended[i].move_to = path[0];\n                    } else {\n                        intended[i].type = '.';\n                    }\n                }\n            }\n        }\n\n        vector<char> final_actions(M, '.');\n        vector<Pos> actual_build_targets(M, {0, 0});\n\n        // Resolve build conflicts\n        vector<bool> build_taken(31 * 31, false);\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'B') {\n                int idx = intended[i].target_impassable.x * 31 + intended[i].target_impassable.y;\n                if (!build_taken[idx]) {\n                    build_taken[idx] = true;\n                    Pos h = humans[i].p;\n                    Pos t = intended[i].target_impassable;\n                    if (t.x == h.x - 1 && t.y == h.y) final_actions[i] = 'u';\n                    else if (t.x == h.x + 1 && t.y == h.y) final_actions[i] = 'd';\n                    else if (t.x == h.x && t.y == h.y - 1) final_actions[i] = 'l';\n                    else if (t.x == h.x && t.y == h.y + 1) final_actions[i] = 'r';\n                    actual_build_targets[i] = t;\n                } else {\n                    intended[i].type = '.';\n                }\n            }\n        }\n\n        // Resolve move conflicts\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'M') {\n                Pos next_pos = intended[i].move_to;\n                bool blocked = false;\n                for (int j = 0; j < M; ++j) {\n                    if (intended[j].type == 'B' && intended[j].target_impassable == next_pos) {\n                        blocked = true; break;\n                    }\n                }\n                if (blocked) {\n                    final_actions[i] = '.';\n                } else {\n                    Pos h = humans[i].p;\n                    if (next_pos.x == h.x - 1 && next_pos.y == h.y) final_actions[i] = 'U';\n                    else if (next_pos.x == h.x + 1 && next_pos.y == h.y) final_actions[i] = 'D';\n                    else if (next_pos.x == h.x && next_pos.y == h.y - 1) final_actions[i] = 'L';\n                    else if (next_pos.x == h.x && next_pos.y == h.y + 1) final_actions[i] = 'R';\n                }\n            }\n        }\n\n        string out = \"\";\n        for (int i = 0; i < M; ++i) out += final_actions[i];\n        cout << out << endl;\n\n        for (int i = 0; i < M; ++i) {\n            if (final_actions[i] == 'U') humans[i].p.x--;\n            else if (final_actions[i] == 'D') humans[i].p.x++;\n            else if (final_actions[i] == 'L') humans[i].p.y--;\n            else if (final_actions[i] == 'R') humans[i].p.y++;\n            \n            if (final_actions[i] == 'u' || final_actions[i] == 'd' || final_actions[i] == 'l' || final_actions[i] == 'r') {\n                if (actual_build_targets[i].x != 0) {\n                    impassable[actual_build_targets[i].x][actual_build_targets[i].y] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; ++i) {\n            string move;\n            cin >> move;\n            for (char c : move) {\n                if (c == 'U') pets[i].p.x--;\n                else if (c == 'D') pets[i].p.x++;\n                else if (c == 'L') pets[i].p.y--;\n                else if (c == 'R') pets[i].p.y++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// Problem constants and global state\nint si, sj, ti, tj;\ndouble p;\nbool wall_h[20][20];\nbool wall_v[20][20];\n\n// Movement directions\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\n/**\n * Finds the shortest path using BFS.\n * This is used as a starting point for the optimization.\n */\nstring get_shortest_path() {\n    queue<pair<pair<int, int>, string>> q;\n    q.push({{si, sj}, \"\"});\n    bool visited[20][20];\n    memset(visited, 0, sizeof(visited));\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto curr = q.front();\n        q.pop();\n        int r = curr.first.first;\n        int c = curr.first.second;\n        string path = curr.second;\n\n        if (r == ti && c == tj) return path;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            if (nr >= 0 && nr < 20 && nc >= 0 && nc < 20 && !visited[nr][nc]) {\n                bool blocked = false;\n                if (dr[i] == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n                if (!blocked) {\n                    visited[nr][nc] = true;\n                    q.push({{nr, nc}, path + dir_char[i]});\n                }\n            }\n        }\n    }\n    return \"\";\n}\n\n/**\n * Calculates the expected value of S = 401 - t using DP.\n * Complexity: O(L * 20 * 20)\n */\ndouble calculate_expected_value(const string& S) {\n    int L = S.length();\n    if (L > 200) return 0;\n    double dp[20][20];\n    memset(dp, 0, sizeof(dp));\n    dp[si][sj] = 1.0;\n    double expected_val = 0;\n    for (int t = 0; t < L; ++t) {\n        double next_dp[20][20];\n        memset(next_dp, 0, sizeof(next_dp));\n        int move_dr = 0, move_dc = 0;\n        if (S[t] == 'U') move_dr = -1;\n        else if (S[t] == 'D') move_dr = 1;\n        else if (S[t] == 'L') move_dc = -1;\n        else if (S[t] == 'R') move_dc = 1;\n\n        for (int r = 0; r < 20; ++r) {\n            for (int c = 0; c < 20; ++c) {\n                if (dp[r][c] <= 1e-18 || (r == ti && c == tj)) continue;\n\n                // Case 1: Forget (stay in place)\n                next_dp[r][c] += dp[r][c] * p;\n\n                // Case 2: Attempt move\n                int nr = r + move_dr;\n                int nc = c + move_dc;\n                bool blocked = false;\n                if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) {\n                    blocked = true;\n                } else if (move_dr == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n\n                if (blocked) {\n                    next_dp[r][c] += dp[r][c] * (1.0 - p);\n                } else {\n                    if (nr == ti && nc == tj) {\n                        expected_val += dp[r][c] * (1.0 - p) * (401 - (t + 1));\n                    } else {\n                        next_dp[nr][nc] += dp[r][c] * (1.0 - p);\n                    }\n                }\n            }\n        }\n        memcpy(dp, next_dp, sizeof(dp));\n    }\n    return expected_val;\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            wall_h[i][j] = (row[j] == '1');\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            wall_v[i][j] = (row[j] == '1');\n        }\n    }\n\n    // Starting string is the shortest path\n    string best_S = get_shortest_path();\n    double best_E = calculate_expected_value(best_S);\n\n    // Use a seeded random number generator\n    mt19937 rng(1337);\n    \n    // Optimization step: Enrichment (repeating moves)\n    // This improves robustness against forgetting moves.\n    for (int k = 2; k <= 5; ++k) {\n        string enriched_S = \"\";\n        for (char c : best_S) {\n            for (int count = 0; count < k; ++count) enriched_S += c;\n        }\n        if (enriched_S.length() <= 200) {\n            double e = calculate_expected_value(enriched_S);\n            if (e > best_E) {\n                best_E = e;\n                best_S = enriched_S;\n            }\n        }\n    }\n\n    // Simulated Annealing to optimize the string\n    string current_S = best_S;\n    double current_E = best_E;\n\n    clock_t start_time = clock();\n    const double max_time = 1.85; // Leave some buffer for safety\n\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > max_time) break;\n\n        // Linear cooling\n        double T = 5.0 * (1.0 - elapsed / max_time); \n\n        string next_S = current_S;\n        int type = uniform_int_distribution<int>(0, 4)(rng);\n\n        // Neighbor generation\n        if (type == 0) { // Add a duplicate character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.insert(i, 1, next_S[i]);\n            } else type = 1;\n        } else if (type == 1) { // Remove a duplicate character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                if (i > 0 && next_S[i] == next_S[i-1]) {\n                    next_S.erase(i, 1);\n                } else if (i < (int)next_S.length() - 1 && next_S[i] == next_S[i+1]) {\n                    next_S.erase(i, 1);\n                } else type = 0;\n            } else type = 0;\n        } else if (type == 2) { // Add a random character\n            if (next_S.length() < 200) {\n                int i = uniform_int_distribution<int>(0, next_S.length())(rng);\n                char c = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n                next_S.insert(i, 1, c);\n            } else type = 1;\n        } else if (type == 3) { // Remove a random character\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.erase(i, 1);\n            } else type = 2;\n        } else if (type == 4) { // Change a random character\n            int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            next_S[i] = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n        }\n\n        double next_E = calculate_expected_value(next_S);\n        \n        // Acceptance criteria\n        if (next_E > current_E || (T > 1e-9 && exp((next_E - current_E) / T) > uniform_real_distribution<double>(0, 1)(rng))) {\n            current_S = next_S;\n            current_E = next_E;\n            if (current_E > best_E) {\n                best_E = current_E;\n                best_S = current_S;\n            }\n        }\n    }\n\n    // Final output\n    cout << best_S << endl;\n\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// The directions: 0: Left, 1: Up, 2: Right, 3: Down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Initial connectivity table for the 8 types\nint base_to[8][4] = {\n    {1, 0, -1, -1}, // 0: one curve (Left, Up)\n    {3, -1, -1, 0}, // 1: one curve (Up, Down)\n    {-1, -1, 3, 2}, // 2: one curve (Right, Down)\n    {-1, 2, 1, -1}, // 3: one curve (Down, Left)\n    {1, 0, 3, 2},    // 4: two curves (Left-Up, Right-Down)\n    {3, 2, 1, 0},    // 5: two curves (Up-Down, Left-Right)\n    {2, -1, 0, -1}, // 6: one straight (Left, Right)\n    {-1, 3, -1, 1}, // 7: one straight (Up, Down)\n};\n\n// Precomputed rotation connectivity table\n// rot_to[t][r][d] is the direction to the next tile for type t, rotated r times CCW, \n// when entering from direction d.\nint rot_to[8][4][4];\n\n// Function to rotate a direction 90 degrees counterclockwise: \n// 0 (L) -> 3 (D), 3 (D) -> 2 (R), 2 (R) -> 1 (U), 1 (U) -> 0 (L)\ninline int rotate_dir(int d) { return (d + 3) % 4; }\n// Inverse rotation\ninline int inv_rotate_dir(int d) { return (d + 1) % 4; }\n\nvoid precompute() {\n    for (int t = 0; t < 8; ++t) {\n        for (int d = 0; d < 4; ++d) rot_to[t][0][d] = base_to[t][d];\n        for (int r = 1; r < 4; ++r) {\n            for (int d = 0; d < 4; ++d) {\n                int prev_d = inv_rotate_dir(d);\n                int prev_to = rot_to[t][r - 1][prev_d];\n                if (prev_to == -1) rot_to[t][r][d] = -1;\n                else rot_to[t][r][d] = rotate_dir(prev_to);\n            }\n        }\n    }\n}\n\nint current_to[30][30][4];\nint initial_type[30][30];\nint current_rot[30][30];\nint visited[30][30][4];\nint timer = 0;\n\nlong long get_score(int& L1, int& L2) {\n    vector<int> lengths;\n    timer++;\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                if (visited[i][j][d] != timer) {\n                    int ci = i, cj = j, cd = d;\n                    int len = 0;\n                    bool possible = true;\n                    while (visited[ci][cj][cd] != timer) {\n                        visited[ci][cj][cd] = timer;\n                        int cd2 = current_to[ci][cj][cd];\n                        if (cd2 == -1) {\n                            possible = false;\n                            break;\n                        }\n                        int ni = ci + di[cd2];\n                        int nj = cj + dj[cd2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            possible = false;\n                            break;\n                        }\n                        len++;\n                        ci = ni; cj = nj;\n                        cd = (cd2 + 2) % 4;\n                    }\n                    if (possible && len > 0) {\n                        lengths.push_back(len);\n                    }\n                }\n            }\n        }\n    }\n    if (lengths.size() < 2) {\n        L1 = 0; L2 = 0;\n        return 0;\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    L1 = lengths[0];\n    L2 = lengths[1];\n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precompute();\n\n    for (int i = 0; i < 30; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; ++j) {\n            initial_type[i][j] = s[j] - '0';\n            current_rot[i][j] = 0;\n            for (int d = 0; d < 4; ++d) {\n                current_to[i][j][d] = rot_to[initial_type[i][j]][0][d];\n            }\n        }\n    }\n\n    int L1, L2;\n    long long current_score = get_score(L1, L2);\n    \n    mt19937 rng(1337);\n    clock_t start_time = clock();\n    \n    // Use local time limit per test case (roughly 18ms)\n    // For competitive programming, we assume about 100 cases.\n    // We will check time roughly every 100 iterations.\n    int iterations = 0;\n    while (true) {\n        if (++iterations % 100 == 0) {\n            if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n        }\n\n        int ri = rng() % 30;\n        int rj = rng() % 30;\n        int old_r = current_rot[ri][rj];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        // Backup the current connectivity for this tile\n        int backup_to[4];\n        for (int d = 0; d < 4; ++d) backup_to[d] = current_to[ri][rj][d];\n\n        // Update connectivity\n        current_rot[ri][rj] = new_r;\n        for (int d = 0; d < 4; ++d) {\n            current_to[ri][rj][d] = rot_to[initial_type[ri][rj]][new_r][d];\n        }\n\n        int next_L1, next_L2;\n        long long next_score = get_score(next_L1, next_L2);\n\n        if (next_score >= current_score) {\n            current_score = next_score;\n            L1 = next_L1; L2 = next_L2;\n        } else {\n            // Simple Hill Climbing. For higher rank, use Simulated Annealing.\n            // Given the 20ms time limit, let's stick to Hill Climbing.\n            current_rot[ri][rj] = old_r;\n            for (int d = 0; d < 4; ++d) current_to[ri][rj][d] = backup_to[d];\n        }\n    }\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            cout << current_rot[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint N, T_limit;\nint board[10][10];\nint target_board[10][10];\nbool fixed_cell[10][10];\nstruct Pos { int r, c; bool operator==(const Pos& o) const { return r == o.r && c == o.c; } bool operator!=(const Pos& o) const { return !(*this == o); } };\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; // U, D, L, R\nchar dchar[] = {'U', 'D', 'L', 'R'};\n\nbool check_match(int t1, int t2, int dir) {\n    if (dir == 0) return (t1 & 8) && (t2 & 2); // U: t1 is (r,c), t2 is (r-1,c). t1 has U(2), t2 has D(8)\n    if (dir == 1) return (t1 & 2) && (t2 & 8); // D: t1 is (r,c), t2 is (r+1,c). t1 has D(8), t2 has U(2)\n    if (dir == 2) return (t1 & 1) && (t2 & 4); // L: t1 is (r,c), t2 is (r,c-1). t1 has L(1), t2 has R(4)\n    if (dir == 3) return (t1 & 4) && (t2 & 1); // R: t1 is (r,c), t2 is (r,c+1). t1 has R(4), t2 has L(1)\n    return false;\n}\n\n// The dir above is based on: if we move the tile from (r+dr, c+dc) to (r, c).\n// If dir=0 (Up), the tile at (r+1, c) moves to (r, c).\n// Let's just use the directions as: U means tile at (r+1, c) moves to (r, c).\n// D means tile at (r-1, c) moves to (r, c).\n// L means tile at (r, c+1) moves to (r, c).\n// R means tile at (r, c-1) moves to (r, c).\n\nint get_tile_dir(Pos from, Pos to) {\n    if (from.r == to.r + 1 && from.c == to.c) return 0; // Tile moves Up\n    if (from.r == to.r - 1 && from.c == to.c) return 1; // Tile moves Down\n    if (from.c == to.c + 1 && from.r == to.r) return 2; // Tile moves Left\n    if (from.c == to.c - 1 && from.r == to.r) return 3; // Tile moves Right\n    return -1;\n}\n\nint main() {\n    if (!(cin >> N >> T_limit)) return 0;\n    Pos empty_pos;\n    vector<int> all_tiles;\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) {\n            int val = stoi(s, nullptr, 16);\n            if (val == 0) empty_pos = {i, j};\n            else all_tiles.push_back(val);\n            board[i][j] = (val == 0 ? 0 : val);\n            target_board[i][j] = -1;\n        }\n    }\n\n    mt19937 rng(time(0));\n    vector<pair<Pos, Pos>> tree_edges;\n    vector<Pos> bfs_order;\n    while (true) {\n        tree_edges.clear(); bfs_order.clear();\n        vector<pair<Pos, Pos>> all_possible_edges;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (i == N - 1 && j == N - 1) continue;\n            if (i + 1 < N && !(i + 1 == N - 1 && j == N - 1)) all_possible_edges.push_back({{i, j}, {i + 1, j}});\n            if (j + 1 < N && !(i == N - 1 && j + 1 == N - 1)) all_possible_edges.push_back({{i, j}, {i, j + 1}});\n        }\n        shuffle(all_possible_edges.begin(), all_possible_edges.end(), rng);\n        vector<int> parent(N * N); for (int i = 0; i < N * N; ++i) parent[i] = i;\n        auto find = [&](auto self, int i) -> int { return parent[i] == i ? i : parent[i] = self(self, parent[i]); };\n        for (auto& e : all_possible_edges) {\n            int r1 = find(find, e.first.r * N + e.first.c), r2 = find(find, e.second.r * N + e.second.c);\n            if (r1 != r2) { parent[r1] = r2; tree_edges.push_back(e); }\n        }\n        bfs_order.push_back({0, 0});\n        vector<bool> visited(N * N, false); visited[0] = true;\n        queue<Pos> q; q.push({0, 0});\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = u.r + dr[i], nc = u.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !(nr == N - 1 && nc == N - 1) && !visited[nr * N + nc]) {\n                    visited[nr * N + nc] = true; bfs_order.push_back({nr, nc}); q.push({nr, nc});\n                }\n            }\n        }\n        auto backtrack = [&](auto self, int idx, vector<int>& used) -> bool {\n            if (idx == N * N - 1) return true;\n            Pos u = bfs_order[idx];\n            for (int i = 0; i < (int)all_tiles.size(); ++i) {\n                if (used[i]) continue;\n                int tile = all_tiles[i];\n                bool ok = true;\n                for (auto& edge : tree_edges) {\n                    if ((edge.first == u || edge.second == u)) {\n                        Pos other = (edge.first == u) ? edge.second : edge.first;\n                        if (target_board[other.r][other.c] != -1) {\n                            if (!check_match(tile, target_board[other.r][other.c], get_tile_dir(u, other))) { ok = false; break; }\n                        }\n                    }\n                }\n                if (ok) {\n                    target_board[u.r][u.c] = tile; used[i] = 1;\n                    if (self(self, idx + 1, used)) return true;\n                    used[i] = 0; target_board[u.r][u.c] = -1;\n                }\n            }\n            return false;\n        };\n        vector<int> used(all_tiles.size(), 0);\n        if (backtrack(backtrack, 0, used)) break;\n    }\n\n    vector<Pos> order;\n    for (int i = 0; i < N - 1; ++i) for (int j = 0; j < N; ++j) order.push_back({i, j});\n    for (int j = 0; j < N - 1; ++j) order.push_back({N - 1, j});\n\n    string res = \"\";\n    Pos cur_e = empty_pos;\n    for (auto p : order) {\n        int tr = -1, tc = -1;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (board[i][j] == target_board[p.r][p.c] && !fixed_cell[i][j]) { tr = i; tc = j; break; }\n        }\n        if (tr == p.r && tc == p.c) { fixed_cell[p.r][p.c] = true; continue; }\n\n        auto bfs_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            while (!q.empty()) {\n                auto [curr, path] = q.front(); q.pop();\n                if (curr == target) {\n                    res += path; cur_e = target;\n                    for (char c : path) {\n                        // To keep board in sync, we simulate. But easier to just swap.\n                    }\n                    return;\n                }\n                for (int i = 0; i < 4; ++i) {\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !v[nr][nc]) {\n                        v[nr][nc] = true;\n                        // If empty moves from (nr,nc) to (curr.r, curr.c), tile moves from (curr.r, curr.c) to (nr,nc)\n                        // The direction is the direction the TILE moves.\n                        // If empty moves (nr,nc) -> (curr.r, curr.c), tile moves (curr.r, curr.c) -> (nr,nc).\n                        // If nr = curr.r-1, tile moves Down. If nr = curr.r+1, tile moves Up.\n                        // If nc = curr.c-1, tile moves Right. If nc = curr.c+1, tile moves Left.\n                        char move_char;\n                        if (nr == curr.r - 1) move_char = 'D';\n                        else if (nr == curr.r + 1) move_char = 'U';\n                        else if (nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n        \n        // Correcting move: BFS to move empty to (tr, tc)\n        // But we must not move through the tile we are trying to move!\n        // No, we move the empty to (tr,tc) then to (p.r, p.c)? \n        // Let's do: 1. Move empty to (tr, tc) 2. Move empty to (p.r, p.c)\n        // Actually, to move tile from (tr,tc) to (p.r,p.c):\n        // Step 1: Move empty square to (p.r, p.c). Step 2: Move empty square to (tr, tc).\n        // Then the tile at (tr,tc) will be at (p.r, p.c).\n        \n        // Let's re-implement the BFS more simply.\n        auto move_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            // To move a tile to (p.r, p.c), we shouldn't let the empty square pass through (p.r, p.c)\n            // EXCEPT when it's the final step. But it's easier to say:\n            // During BFS, the empty square cannot pass through ANY fixed cell.\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply the moves to the board\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int nr = temp_e.r, nc = temp_e.c;\n                        int tr_idx = -1;\n                        if(c == 'U') tr_idx = 1; else if(c == 'D') tr_idx = 0;\n                        else if(c == 'L') tr_idx = 3; else tr_idx = 2;\n                        // Wait, the directions are for the TILE.\n                        // If tile moves Up, empty moves Down.\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char move_char;\n                        if(nr == curr.r - 1) move_char = 'D';\n                        else if(nr == curr.r + 1) move_char = 'U';\n                        else if(nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n\n        // 1. Move empty to (p.r, p.c)\n        // But we must avoid (tr, tc) during this, because it's the tile we want.\n        // Wait, the empty square can move through (tr, tc) if it's not fixed!\n        // Let's just move empty to (p.r, p.c) then to (tr, tc).\n        // Wait, the order is:\n        // 1. Move empty square to (p.r, p.c)\n        // 2. Move empty square to (tr, tc)\n        // Now the tile that was at (tr, tc) is at (p.r, p.c).\n        \n        // We'll use a slightly different approach: move empty to (tr, tc) and then to (p.r, p.c).\n        // Actually, the simplest: move empty to (p.r, p.c), then to (tr, tc).\n        // Let's use a modified BFS that avoids (tr, tc) if we are moving to (p.r, p.c).\n        // Wait, the current tile is at (tr, tc). The empty square should move to (p.r, p.c) \n        // without using (tr, tc) as an intermediate.\n        \n        // BFS to move empty to (p.r, p.c), avoiding (tr, tc) and all fixed cells.\n        auto bfs_with_avoid = [&](Pos target, Pos avoid) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            if(avoid.r != -1) v[avoid.r][avoid.c] = true;\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply moves\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char m;\n                        if(nr == curr.r - 1) m = 'D'; else if(nr == curr.r + 1) m = 'U';\n                        else if(nc == curr.c - 1) m = 'R'; else m = 'L';\n                        q.push({{nr, nc}, path + m});\n                    }\n                }\n            }\n        };\n\n        bfs_with_avoid(p, {tr, tc});\n        bfs_with_avoid({tr, tc}, {-1, -1});\n        fixed_cell[p.r][p.c] = true;\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <map>\n#include <unordered_map>\n\nusing namespace std;\n\ntypedef __int128_t int128;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Line {\n    long long a, b, c;\n    long long px, py, qx, qy;\n};\n\nstruct Signature {\n    uint64_t low, high;\n    bool operator<(const Signature& other) const {\n        if (low != other.low) return low < other.low;\n        return high < other.high;\n    }\n    bool operator==(const Signature& other) const {\n        return low == other.low && high == other.high;\n    }\n};\n\nstruct SignatureHash {\n    size_t operator()(const Signature& s) const {\n        return s.low ^ (s.high + 0x9e3779b9 + (s.low << 6) + (s.low >> 2));\n    }\n};\n\nstruct SigBitset {\n    uint64_t low, high;\n    void set_bit(int idx) {\n        if (idx < 64) low |= (1ULL << idx);\n        else high |= (1ULL << (idx - 64));\n    }\n    void reset_bit(int idx) {\n        if (idx < 64) low &= ~(1ULL << idx);\n        else high &= ~(1ULL << (idx - 64));\n    }\n    Signature to_signature() const {\n        return {low, high};\n    }\n};\n\nint N, K;\nint a[11];\nPoint strawberries[5505];\nLine lines[105];\nSigBitset sigs[5505];\nint on_count[5505];\n\nLine make_line(long long px, long long py, long long qx, long long qy) {\n    Line l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = qy - py;\n    l.b = px - qx;\n    l.c = (int128)px * qy - (int128)qx * py; // Need to be careful about precision here, but int128 is ok.\n    // Wait, the line equation is (qy-py)x - (qx-px)y + (pxqy - qxpy) = 0\n    // So a = qy-py, b = -(qx-px) = px-qx, c = pxqy - qxpy.\n    // Let's re-calculate to be more robust.\n    return l;\n}\n\n// Since c can be very large, we use __int128 for it.\n// Let's change the Line struct.\nstruct RobustLine {\n    int128 a, b, c;\n    long long px, py, qx, qy;\n};\n\nRobustLine make_robust_line(long long px, long long py, long long qx, long long qy) {\n    RobustLine l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = (int128)qy - py;\n    l.b = (int128)px - qx;\n    l.c = (int128)px * qy - (int128)qx * py;\n    return l;\n}\n\nRobustLine robust_lines[105];\n\nint calculate_score() {\n    unordered_map<Signature, int, SignatureHash> counts;\n    for (int i = 0; i < N; ++i) {\n        if (on_count[i] == 0) {\n            counts[sigs[i].to_signature()]++;\n        }\n    }\n    int b[11] = {0};\n    for (auto const& [sig, count] : counts) {\n        if (count <= 10) b[count]++;\n    }\n    int total = 0;\n    for (int d = 1; d <= 10; ++d) {\n        total += min(a[d], b[d]);\n    }\n    return total;\n}\n\nvoid update_line(int idx, RobustLine new_line) {\n    for (int i = 0; i < N; ++i) {\n        int128 val_old = robust_lines[idx].a * strawberries[i].x + robust_lines[idx].b * strawberries[i].y + robust_lines[idx].c;\n        if (val_old == 0) {\n            on_count[i]--;\n        } else {\n            // Bit was already set based on val_old.\n        }\n\n        int128 val_new = new_line.a * strawberries[i].x + new_line.b * strawberries[i].y + new_line.c;\n        if (val_new == 0) {\n            on_count[i]++;\n        } else {\n            if (val_new > 0) sigs[i].set_bit(idx);\n            else sigs[i].reset_bit(idx);\n        }\n    }\n    robust_lines[idx] = new_line;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> K)) return 0;\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    for (int i = 0; i < N; ++i) cin >> strawberries[i].x >> strawberries[i].y;\n\n    mt19937 rng(1337);\n    uniform_int_distribution<long long> dist_coord(-10000, 10000);\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    uniform_int_distribution<int> dist_K(0, K - 1);\n\n    // Dummy line\n    robust_lines[0] = make_robust_line(0, 1000000000, 1, 1000000000); \n    // Wait, the dummy line above is a bit invalid (a=0, b=-1, c=-10^9)\n    // Let's use a more standard dummy: y = -10^9\n    robust_lines[0] = make_robust_line(0, -1000000000, 1, -1000000000);\n    for (int i = 0; i < K; ++i) {\n        robust_lines[i] = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        // Re-initialize sigs and on_count\n    }\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        // Actually we need to initialize sigs and on_count properly\n        // Let's just set everything to 0 then update each line one by one.\n    }\n    // Correct initialization:\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].low = 0;\n        sigs[i].high = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        RobustLine rl = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        update_line(i, rl);\n    }\n\n    int current_score = calculate_score();\n    int best_score = current_score;\n    vector<RobustLine> best_lines(robust_lines, robust_lines + K);\n\n    auto start_time = chrono::steady_clock::now();\n    double T = 1.0;\n    double factor = 0.99995;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 127) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2800) break;\n        }\n        iter++;\n\n        int idx = dist_K(rng);\n        RobustLine old_line = robust_lines[idx];\n        RobustLine new_line;\n        \n        if (rng() % 10 < 7) {\n            new_line = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        } else {\n            int s1 = dist_idx(rng);\n            int s2 = dist_idx(rng);\n            if (s1 == s2) {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s1].x + 1, strawberries[s1].y + 1);\n            } else {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s2].x + (rng() % 3 - 1), strawberries[s2].y + (rng() % 3 - 1));\n            }\n        }\n\n        update_line(idx, new_line);\n        int new_score = calculate_score();\n\n        if (new_score >= current_score || (exp((new_score - current_score) / T) > (double)rng() / mt19937::max())) {\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < K; ++i) best_lines[i] = robust_lines[i];\n            }\n        } else {\n            update_line(idx, old_line);\n        }\n        T *= factor;\n    }\n\n    cout << K << \"\\n\";\n    for (int i = 0; i < K; ++i) {\n        cout << best_lines[i].px << \" \" << best_lines[i].py << \" \" << best_lines[i].qx << \" \" << best_lines[i].qy << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The goal is to maximize the sum of weights of dots placed on an N x N grid.\n * The weight of each point (x, y) is (x-c)^2 + (y-c)^2 + 1, where c is the center of the grid.\n * This means we want to place as many dots as possible, especially those far from the center.\n * We can place a new dot by forming a rectangle (axis-aligned or 45-degree inclined) \n * using three existing dots as corners.\n * \n * STRATEGY:\n * A greedy approach should work well here. In each step, find all possible valid \n * rectangles that can be formed and select the one that adds the point with \n * the highest weight.\n * \n * VALIDITY CONDITIONS:\n * 1. A new dot p1 must not currently have a dot.\n * 2. Three other corners (p2, p3, p4) must have dots.\n * 3. No other dots on the rectangle's perimeter.\n * 4. The perimeter must not share a common segment with any existing rectangle.\n * \n * ALGORITHM COMPLEXITY:\n * The number of existing dots M is up to N^2.\n * Searching for rectangles by iterating through all pairs (p2, p3) of existing dots \n * takes O(M^2) per step. \n * Total complexity across all steps is approximately O(N^5), which fits within the 5-second limit.\n */\n\nstruct Point {\n    int x, y;\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nint N, M;\nbool is_dot[65][65];\nbool used_h[65][65];   // used_h[x][y] represents segment (x, y) to (x+1, y)\nbool used_v[65][65];   // used_v[x][y] represents segment (x, y) to (x, y+1)\nbool used_d1[65][65];  // used_d1[x][y] represents segment (x, y) to (x+1, y+1)\nbool used_d2[65][65];  // used_d2[x][y] represents segment (x, y) to (x+1, y-1)\n\ndouble get_weight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1.0;\n}\n\nbool is_in_grid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Checks if any segment of the rectangle's perimeter is already used.\n// If check_and_use is true, it marks these segments as used.\nbool check_segments(const vector<Point>& rect, bool check_and_use) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x, cur_y = start.y;\n        while (cur_x != end.x || cur_y != end.y) {\n            int next_x = cur_x + dx;\n            int next_y = cur_y + dy;\n            if (dx != 0 && dy == 0) { // Horizontal\n                int min_x = min(cur_x, next_x);\n                if (used_h[min_x][cur_y]) return false;\n                if (check_and_use) used_h[min_x][cur_y] = true;\n            } else if (dx == 0 && dy != 0) { // Vertical\n                int min_y = min(cur_y, next_y);\n                if (used_v[cur_x][min_y]) return false;\n                if (check_and_use) used_v[cur_x][min_y] = true;\n            } else if (dx == 1 && dy == 1) { // Diag 1 (up-right)\n                int min_x = cur_x, min_y = cur_y;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == -1) { // Diag 1 (down-left)\n                int min_x = cur_x - 1, min_y = cur_y - 1;\n                if (used_d1[min_x][min_y]) return false;\n                if (check_and_use) used_d1[min_x][min_y] = true;\n            } else if (dx == -1 && dy == 1) { // Diag 2 (up-left)\n                int min_x = cur_x - 1, min_y = cur_y;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            } else if (dx == 1 && dy == -1) { // Diag 2 (down-right)\n                int min_x = cur_x, min_y = cur_y - 1;\n                if (used_d2[min_x][min_y]) return false;\n                if (check_and_use) used_d2[min_x][min_y] = true;\n            }\n            cur_x = next_x; cur_y = next_y;\n        }\n    }\n    return true;\n}\n\n// Checks if any other dots (not among the rectangle's corners p2, p3, p4) are on the perimeter.\nbool check_no_other_dots(const vector<Point>& rect) {\n    for (int i = 0; i < 4; ++i) {\n        Point start = rect[i], end = rect[(i + 1) % 4];\n        int dx = (end.x > start.x) ? 1 : (end.x < start.x ? -1 : 0);\n        int dy = (end.y > start.y) ? 1 : (end.y < start.y ? -1 : 0);\n        int cur_x = start.x + dx, cur_y = start.y + dy;\n        while (cur_x != end.x || cur_y != end.y) {\n            if (is_dot[cur_x][cur_y]) {\n                bool is_corner = false;\n                for (int j = 1; j < 4; ++j) { // p2, p3, p4 are corners rect[1], rect[2], rect[3]\n                    if (cur_x == rect[j].x && cur_y == rect[j].y) is_corner = true;\n                }\n                if (!is_corner) return false;\n            }\n            cur_x += dx; cur_y += dy;\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M)) return 0;\n    vector<Point> dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        is_dot[x][y] = true;\n        dots.push_back({x, y});\n    }\n\n    vector<vector<Point>> operations;\n\n    while (true) {\n        double best_val = -1;\n        vector<Point> best_rect;\n\n        for (int i = 0; i < (int)dots.size(); ++i) {\n            for (int j = i + 1; j < (int)dots.size(); ++j) {\n                Point p2 = dots[i];\n                Point p3 = dots[j];\n\n                // Axis-aligned rectangle search\n                if (p2.x != p3.x && p2.y != p3.y) {\n                    // Two potential cases: p2 and p3 are opposite corners.\n                    // The other two corners are (p2.x, p3.y) and (p3.x, p2.y).\n                    // One of these must be the new dot p1, the other must be an existing dot p4.\n                    Point corners[2] = {{p2.x, p3.y}, {p3.x, p2.y}};\n                    for (int k = 0; k < 2; ++k) {\n                        Point p1 = corners[k];\n                        Point p4 = corners[1 - k];\n                        if (is_in_grid(p1.x, p1.y) && is_in_grid(p4.x, p4.y)) {\n                            if (!is_dot[p1.x][p1.y] && is_dot[p4.x][p4.y]) {\n                                vector<Point> rect = {p1, p2, p3, p4};\n                                if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                    double val = get_weight(p1.x, p1.y);\n                                    if (val > best_val) {\n                                        best_val = val;\n                                        best_rect = rect;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                // 45-degree rectangle search\n                int dx = p3.x - p2.x;\n                int dy = p3.y - p2.y;\n                if ((dx + dy) % 2 == 0) {\n                    // For 45-degree rectangles, the center of the diagonal p2-p3 is a corner of the grid-dual.\n                    // Use geometric properties to find p1 and p4.\n                    int x12 = p2.x + p3.x + p2.y - p3.y;\n                    int y12 = p2.y + p3.y + p3.x - p2.x;\n                    if (x12 % 2 == 0 && y12 % 2 == 0) {\n                        Point p1_cand = {x12 / 2, y12 / 2};\n                        int x42 = p2.x + p3.x - p2.y + p3.y;\n                        int y42 = p2.y + p3.y - p3.x + p2.x;\n                        if (x42 % 2 == 0 && y42 % 2 == 0) {\n                            Point p4_cand = {x42 / 2, y42 / 2};\n                            if (is_in_grid(p1_cand.x, p1_cand.y) && is_in_grid(p4_cand.x, p4_cand.y)) {\n                                // p1_cand could be p1 (the new dot) and p4_cand could be p4 (an existing dot)\n                                if (!is_dot[p1_cand.x][p1_cand.y] && is_dot[p4_cand.x][p4_cand.y]) {\n                                    vector<Point> rect = {p1_cand, p2, p3, p4_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p1_cand.x, p1_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                                // Or vice versa\n                                if (!is_dot[p4_cand.x][p4_cand.y] && is_dot[p1_cand.x][p1_cand.y]) {\n                                    vector<Point> rect = {p4_cand, p2, p3, p1_cand};\n                                    if (check_no_other_dots(rect) && check_segments(rect, false)) {\n                                        double val = get_weight(p4_cand.x, p4_cand.y);\n                                        if (val > best_val) {\n                                            best_val = val;\n                                            best_rect = rect;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_val > 0) {\n            is_dot[best_rect[0].x][best_rect[0].y] = true;\n            dots.push_back(best_rect[0]);\n            check_segments(best_rect, true); // Commit segments as used\n            operations.push_back(best_rect);\n        } else {\n            break;\n        }\n    }\n\n    // Output results\n    cout << operations.size() << \"\\n\";\n    for (const auto& rect : operations) {\n        cout << rect[0].x << \" \" << rect[0].y << \" \"\n             << rect[1].x << \" \" << rect[1].y << \" \"\n             << rect[2].x << \" \" << rect[2].y << \" \"\n             << rect[3].x << \" \" << rect[3].y << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global grid and flavors to store current state and input\nint grid[10][10];\nint flavors[100];\n\nstruct Point {\n    int r, c;\n};\n\n// Directions for adjacency\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n/**\n * Calculates the connectivity score (sum of n_i^2) for the current grid.\n * n_i is the size of the i-th connected component of the same flavor.\n */\nint calculate_score(int current_grid[10][10]) {\n    bool visited[10][10] = {false};\n    int total_score = 0;\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (current_grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = current_grid[r][c];\n                int size = 0;\n                queue<Point> q;\n                q.push({r, c});\n                visited[r][c] = true;\n                while (!q.empty()) {\n                    Point curr = q.front();\n                    q.pop();\n                    size++;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = curr.r + dr[i];\n                        int nc = curr.c + dc[i];\n                        if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 &&\n                            !visited[nr][nc] && current_grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n/**\n * Simulates the effect of tilting the box in a given direction.\n * F: Front (r decreases), B: Backward (r increases), L: Left (c decreases), R: Right (c increases)\n */\nvoid simulate_tilt(int current_grid[10][10], char dir, int next_grid[10][10]) {\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            next_grid[i][j] = 0;\n\n    if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 0; r < 10; ++r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 9; r >= 0; --r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[9 - count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 0; c < 10; ++c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][count++] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 9; c >= 0; --c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][9 - count++] = current_grid[r][c];\n                }\n            }\n        }\n    }\n}\n\n/**\n * Applies the selected tilt to the current grid.\n */\nvoid apply_tilt(int current_grid[10][10], char dir) {\n    int next_grid[10][10];\n    simulate_tilt(current_grid, dir, next_grid);\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            current_grid[i][j] = next_grid[i][j];\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read the flavors of the 100 candies\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    // Initialize the grid as empty\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            grid[i][j] = 0;\n\n    char directions[] = {'F', 'B', 'L', 'R'};\n\n    // Process each of the 100 candies\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        if (!(cin >> p_t)) break;\n\n        // Locate the p_t-th empty cell (1-indexed)\n        vector<Point> empty_cells;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    empty_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // Place the t-th candy in the determined cell\n        Point pos = empty_cells[p_t - 1];\n        grid[pos.r][pos.c] = flavors[t - 1];\n\n        // Greedy strategy: choose the tilt direction that maximizes the current score\n        int best_score = -1;\n        char best_dir = 'F';\n\n        for (char d : directions) {\n            int next_grid_temp[10][10];\n            simulate_tilt(grid, d, next_grid_temp);\n            int score = calculate_score(next_grid_temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        // Output the chosen direction and flush\n        cout << best_dir << endl;\n        // Apply the move to the actual grid state\n        apply_tilt(grid, best_dir);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis and Improvement Strategy:\n * \n * 1. Insight from Feedback:\n *    The previous score was relatively high but had many failures. The primary \n *    weakness was likely the susceptibility of the clique-based encoding to vertex\n *    shuffling and noise when epsilon is high, or being stuck in local minima \n *    during the permutation search.\n * \n * 2. Encoding Strategy:\n *    Keep the clique-based encoding with N=100. For each index i (0 to M-1), \n *    the graph G_i is a clique of size k = i+1. This maximizes the distinctness \n *    of edge counts and degree distributions.\n * \n * 3. Decoding Strategy (Prediction):\n *    - Candidate Selection: Instead of checking all M, use the edge count of the \n *      received graph H to select the top 35 most likely candidate graphs G_i.\n *    - Permutation Initialization: Use the degree distribution. Sort the \n *      degrees of H and G_i and create an initial permutation P mapping \n *      H's vertices to G_i's vertices.\n *    - Local Search: Use a Hill Climbing approach with many iterations \n *      (1500 iterations per candidate). To avoid local minima, allow \n *      swaps that result in zero change in mismatch count (delta <= 0).\n * \n * 4. Optimization:\n *    - Use a flat 1D array for G_adj to improve cache locality.\n *    - Use a pre-calculated degree array for all G_i.\n *    - Implement a time-limited search to ensure the program runs within the 5s limit.\n *    - The delta calculation in the local search is optimized to O(N) per iteration.\n * \n * 5. Complexity:\n *    Total complexity is approximately O(Queries * Candidates * Iterations * N).\n *    100 * 35 * 1500 * 100 = 5.25 * 10^8 operations, which fits within 5 seconds.\n */\n\n// Global arrays to fit into memory and avoid reallocation\nunsigned char G_adj[100 * 100 * 100]; // G_adj[i][u][v] flattened\nbool H_adj[100][100];\nint Gi_edges[100];\nint G_deg[100][100];\n\nint main() {\n    // Fast I/O setup\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double epsilon;\n    if (!(cin >> M >> epsilon)) return 0;\n\n    const int N = 100;\n    const int L = N * (N - 1) / 2;\n\n    // Encoding step\n    for (int i = 0; i < M; ++i) {\n        int k = i + 1; // Clique size\n        Gi_edges[i] = k * (k - 1) / 2;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (u < k && v < k && u != v) {\n                    G_adj[i * 10000 + u * 100 + v] = 1;\n                } else {\n                    G_adj[i * 10000 + u * 100 + v] = 0;\n                }\n            }\n        }\n    }\n\n    // Pre-calculate degrees for all encoded graphs\n    for (int i = 0; i < M; ++i) {\n        for (int u = 0; u < N; ++u) {\n            int d = 0;\n            for (int v = 0; v < N; ++v) {\n                if (G_adj[i * 10000 + u * 100 + v]) d++;\n            }\n            G_deg[i][u] = d;\n        }\n    }\n\n    // Output encoding\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        string s = \"\";\n        s.reserve(L);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s += (G_adj[i * 10000 + u * 100 + v] ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    mt19937 rng(42);\n    auto start_total = chrono::steady_clock::now();\n\n    // Query processing\n    for (int q = 0; q < 100; ++q) {\n        string H_str;\n        if (!(cin >> H_str)) break;\n\n        int h_edges = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) H_adj[u][v] = false;\n        }\n        int idx = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (H_str[idx++] == '1') {\n                    H_adj[u][v] = H_adj[v][u] = true;\n                    h_edges++;\n                }\n            }\n        }\n\n        // Degree distribution of H\n        vector<int> H_deg(N, 0);\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (H_adj[u][v]) H_deg[u]++;\n            }\n        }\n\n        // Select candidates based on expected edge counts\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < M; ++i) {\n            double expected_h_edges = (double)Gi_edges[i] * (1.0 - 2.0 * epsilon) + (double)L * epsilon;\n            candidates.push_back({abs((double)h_edges - expected_h_edges), i});\n        }\n        sort(candidates.begin(), candidates.end());\n\n        int best_i = 0;\n        int min_mismatches = 2e9;\n\n        // Iterate through candidates\n        for (int c = 0; c < min(M, 35); ++c) {\n            int i = candidates[c].second;\n\n            // Initialize permutation by sorting degrees\n            vector<int> H_idx(N), G_idx(N);\n            for (int j = 0; j < N; ++j) {\n                H_idx[j] = j;\n                G_idx[j] = j;\n            }\n            sort(H_idx.begin(), H_idx.end(), [&](int a, int b) { return H_deg[a] < H_deg[b]; });\n            sort(G_idx.begin(), G_idx.end(), [&](int a, int b) { return G_deg[i][a] < G_deg[i][b]; });\n\n            vector<int> P(N);\n            for (int j = 0; j < N; ++j) P[H_idx[j]] = G_idx[j];\n\n            // Initial mismatch count\n            int cur_mismatches = 0;\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (G_adj[i * 10000 + P[u] * 100 + P[v]] != H_adj[u][v]) cur_mismatches++;\n                }\n            }\n\n            // Hill Climbing optimization\n            for (int iter = 0; iter < 1500; ++iter) {\n                int u = rng() % N;\n                int v = rng() % N;\n                if (u == v) continue;\n\n                // Compute delta in O(N)\n                int delta = 0;\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    // Calculate old and new mismatch contributions for edges (u, k) and (v, k)\n                    int old_uk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[u][k]);\n                    int old_vk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[v][k]);\n                    int new_uk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[u][k]);\n                    int new_vk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[v][k]);\n                    delta += (new_uk + new_vk) - (old_uk + old_vk);\n                }\n\n                // Accept swap if it improves or maintains mismatch count\n                if (delta <= 0) {\n                    cur_mismatches += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n\n            if (cur_mismatches < min_mismatches) {\n                min_mismatches = cur_mismatches;\n                best_i = i;\n            }\n            \n            // Periodic check to avoid TLE\n            if (c % 10 == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration_cast<chrono::milliseconds>(now - start_total).count() > 4700) break;\n            }\n        }\n\n        // Predict and output\n        cout << best_i << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n// Use a large INF for Dijkstra to avoid overflow while still being larger than any possible path\nconst long long INF = 1e15;\n// The problem defines unreachable distance as 10^9\nconst long long DIST_INF = 1000000000LL;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct AdjEdge {\n    int to, w, id;\n};\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w, i});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w, i});\n    }\n\n    // Skip vertex coordinates as they are not required for the improved heuristic\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // edge_count[i] stores the number of pairs (start, target) such that edge i is on the shortest path in the Dijkstra forest\n    vector<long long> edge_count(M, 0);\n\n    // Phase 1: Calculate how many shortest paths pass through each edge\n    for (int start = 1; start <= N; ++start) {\n        vector<long long> dist(N + 1, INF);\n        vector<int> parent_node(N + 1, -1);\n        vector<int> parent_edge(N + 1, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n\n        dist[start] = 0;\n        pq.push({0, start});\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& e : adj[u]) {\n                if (dist[e.to] > dist[u] + e.w) {\n                    dist[e.to] = dist[u] + e.w;\n                    parent_node[e.to] = u;\n                    parent_edge[e.to] = e.id;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n\n        // Sort nodes by distance in descending order to propagate counts up the Dijkstra tree\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 1);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n\n        vector<long long> node_count(N + 1, 1);\n        for (int u : nodes) {\n            if (u != start && parent_edge[u] != -1) {\n                int p = parent_node[u];\n                int id = parent_edge[u];\n                edge_count[id] += node_count[u];\n                node_count[p] += node_count[u];\n            }\n        }\n    }\n\n    // Phase 2: Calculate the \"detour\" weight for each edge to refine the impact metric\n    vector<long long> I(M);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int w = edges[i].w;\n\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        vector<long long> dist_u(N + 1, INF);\n        dist_u[u] = 0;\n        pq.push({0, u});\n\n        while (!pq.empty()) {\n            auto [d, curr] = pq.top();\n            pq.pop();\n            if (d > dist_u[curr]) continue;\n            if (curr == v) break; // Optimization: stop once we reach the other endpoint\n            for (auto& e_adj : adj[curr]) {\n                if (e_adj.id == i) continue; // Ignore the edge being analyzed\n                if (dist_u[e_adj.to] > d + e_adj.w) {\n                    dist_u[e_adj.to] = d + e_adj.w;\n                    pq.push({dist_u[e_adj.to], e_adj.to});\n                }\n            }\n        }\n\n        long long w_prime = dist_u[v];\n        if (w_prime >= INF) w_prime = DIST_INF; // If unreachable, use the penalty value\n        \n        // Refined Impact: (number of shortest paths) * (increase in path length)\n        I[i] = edge_count[i] * (w_prime - w);\n    }\n\n    // Phase 3: Sort edges by impact and assign to days greedily to balance the total frustration\n    vector<int> edge_indices(M);\n    iota(edge_indices.begin(), edge_indices.end(), 0);\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return I[a] > I[b];\n    });\n\n    vector<int> assignment(M);\n    vector<int> day_count(D, 0);\n    vector<long long> day_sum_I(D, 0);\n    for (int idx : edge_indices) {\n        int best_day = -1;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K) {\n                if (best_day == -1 || day_sum_I[d] < day_sum_I[best_day]) {\n                    best_day = d;\n                }\n            }\n        }\n        assignment[idx] = best_day + 1;\n        day_count[best_day]++;\n        day_sum_I[best_day] += I[idx];\n    }\n\n    // Final Output\n    for (int i = 0; i < M; ++i) {\n        cout << assignment[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem: AHC019 - Silhouette\n * \n * Analysis:\n * We are given two pairs of 2D silhouettes (front and right) for two 3D objects.\n * We need to construct a set of blocks such that the first set of silhouettes can be\n * formed by one subset of blocks, and the second set by another subset.\n * The score is minimized by using large blocks in both objects (as common blocks).\n * \n * Strategy:\n * 1. Identify the set of possible cubic regions (x, y, z) that satisfy the\n *    silhouette for object 1: S1 = {(x, y, z) | f1(z, x) == 1 and r1(z, y) == 1}.\n *    Similarly for S2.\n * 2. A cell (x, y, z) can be part of object 1 if and only if (x, y, z) is in S1.\n *    The set S1 itself satisfies the silhouette f1 and r1.\n * 3. To minimize the score, we maximize the volume of common blocks.\n *    The best common blocks are the connected components of S1 \u2229 S2.\n * 4. To avoid wasting blocks, we cover the remaining cells in S1 (those not in S2)\n *    and the remaining cells in S2 (those not in S1) with their own connected components.\n * 5. Each connected component becomes a single block. Since each block is a component,\n *    it is guaranteed to be connected. Since the components are derived from disjoint\n *    sets of cells (S_common, S_only1, S_only2), they do not overlap.\n * \n * Complexity:\n * O(D^3) time and memory, which is well within limits for D up to 14.\n */\n\nstruct Cell {\n    int x, y, z;\n};\n\nvoid find_components(const vector<vector<vector<bool>>>& S, int type, int D,\n                    vector<vector<vector<int>>>& b1, vector<vector<vector<int>>>& b2,\n                    int& block_id) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    static const int dx[] = {1, -1, 0, 0, 0, 0};\n    static const int dy[] = {0, 0, 1, -1, 0, 0};\n    static const int dz[] = {0, 0, 0, 0, 1, -1};\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S[x][y][z] && !visited[x][y][z]) {\n                    block_id++;\n                    queue<Cell> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    while (!q.empty()) {\n                        Cell curr = q.front();\n                        q.pop();\n                        \n                        if (type == 0) { // block in both objects\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 1) { // block in object 1 only\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 2) { // block in object 2 only\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        }\n\n                        for (int i = 0; i < 6; ++i) {\n                            int nx = curr.x + dx[i];\n                            int ny = curr.y + dy[i];\n                            int nz = curr.z + dz[i];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && \n                                S[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                visited[nx][ny][nz] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n    for (int i = 0; i < D; ++i) cin >> f2[i];\n    for (int i = 0; i < D; ++i) cin >> r2[i];\n\n    // Function to derive the set of valid cells from silhouette arrays\n    auto get_S = [&](const vector<string>& f, const vector<string>& r) {\n        vector<vector<vector<bool>>> S(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x) {\n                for (int y = 0; y < D; ++y) {\n                    if (f[z][x] == '1' && r[z][y] == '1') {\n                        S[x][y][z] = true;\n                    }\n                }\n            }\n        }\n        return S;\n    };\n\n    auto S1 = get_S(f1, r1);\n    auto S2 = get_S(f2, r2);\n\n    // Arrays to store the block ID at each location for each object\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int total_blocks = 0;\n\n    // Pre-calculating the three types of cell sets\n    vector<vector<vector<bool>>> S_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> S_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (S1[x][y][z] && S2[x][y][z]) {\n                    S_common[x][y][z] = true;\n                } else if (S1[x][y][z]) {\n                    S_only1[x][y][z] = true;\n                } else if (S2[x][y][z]) {\n                    S_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Find all connected components in each of the three sets\n    find_components(S_common, 0, D, b1, b2, total_blocks);\n    find_components(S_only1, 1, D, b1, b2, total_blocks);\n    find_components(S_only2, 2, D, b1, b2, total_blocks);\n\n    // Output the results\n    cout << total_blocks << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b1[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D * D * D; ++i) {\n        int x = i / (D * D);\n        int y = (i / D) % D;\n        int z = i % D;\n        cout << b2[x][y][z] << ( (i == D * D * D - 1) ? \"\" : \" \" );\n    }\n    cout << \"\\n\";\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize a cost function S = sum(P_i^2) + sum(w_j) where P_i is the output strength\n * of station i and w_j is the weight of an activated edge j. All residents must be covered.\n * A resident is covered if it's within distance P_i of some station i reachable from station 1.\n * \n * Algorithm:\n * 1. We use a Steiner Tree approximation approach to ensure connectivity and cover all residents.\n * 2. First, compute all-pairs shortest paths (APSP) using Floyd-Warshall.\n * 3. For each resident, identify its closest vertex in the entire graph. Let this set of vertices be V_target.\n * 4. Construct a metric closure of the graph using only vertices in V_target and find its Minimum Spanning Tree (MST).\n * 5. The union of the shortest paths corresponding to the MST edges forms our connected set of stations (V_prime) and cables (E_prime).\n * 6. For each resident, assign it to its closest vertex in V_prime and calculate the required P_i.\n * 7. Since all residents were within 5000 of some station, a valid configuration exists.\n */\n\nstruct Edge {\n    int u, v;\n    long long w;\n    int id;\n};\n\nstruct Resident {\n    int x, y;\n};\n\nstruct Station {\n    int x, y;\n};\n\nconst long long INF_LL = 1e18;\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n\n    vector<Edge> edges(M);\n    vector<vector<long long>> dist_matrix(N, vector<long long>(N, INF_LL));\n    vector<vector<int>> next_node(N, vector<int>(N, -1));\n    vector<vector<int>> adj_edge_idx(N, vector<int>(N, -1));\n\n    for (int i = 0; i < N; ++i) dist_matrix[i][i] = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        // Standard way to handle weights in adjacency matrices for Floyd-Warshall\n        if (w < dist_matrix[u][v]) {\n            dist_matrix[u][v] = dist_matrix[v][u] = w;\n            next_node[u][v] = v;\n            next_node[v][u] = u;\n            adj_edge_idx[u][v] = adj_edge_idx[v][u] = i;\n        }\n    }\n\n    vector<Resident> residents(K);\n    for (int i = 0; i < K; ++i) {\n        cin >> residents[i].x >> residents[i].y;\n    }\n\n    // Floyd-Warshall for All-Pairs Shortest Paths and reconstruction paths\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (dist_matrix[i][k] != INF_LL && dist_matrix[k][j] != INF_LL && \n                    dist_matrix[i][k] + dist_matrix[k][j] < dist_matrix[i][j]) {\n                    dist_matrix[i][j] = dist_matrix[i][k] + dist_matrix[k][j];\n                    next_node[i][j] = next_node[i][k];\n                }\n            }\n        }\n    }\n\n    // Determine the set of target vertices V_target\n    vector<int> V_target;\n    vector<bool> is_in_target(N, false);\n    V_target.push_back(0); // Station 1 is always a source\n    is_in_target[0] = true;\n\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_sq = 1e20;\n        for (int i = 0; i < N; ++i) {\n            double dx = (double)stations[i].x - residents[k].x;\n            double dy = (double)stations[i].y - residents[k].y;\n            double d2 = dx * dx + dy * dy;\n            if (d2 < min_dist_sq) {\n                min_dist_sq = d2;\n                best_i = i;\n            }\n        }\n        if (best_i != -1 && !is_in_target[best_i]) {\n            is_in_target[best_i] = true;\n            V_target.push_back(best_i);\n        }\n    }\n\n    // Calculate MST of the metric closure of V_target\n    int T_size = (int)V_target.size();\n    struct MSTEdge {\n        int u, v;\n        long long w;\n    };\n    vector<MSTEdge> mst_edges;\n    if (T_size > 1) {\n        // Prim's algorithm for MST on metric closure\n        vector<long long> min_dist_prim(T_size, INF_LL);\n        vector<int> parent(T_size, -1);\n        vector<bool> visited(T_size, false);\n        min_dist_prim[0] = 0;\n        for (int i = 0; i < T_size; ++i) {\n            int u_idx = -1;\n            for (int j = 0; j < T_size; ++j) {\n                if (!visited[j] && (u_idx == -1 || min_dist_prim[j] < min_dist_prim[u_idx])) {\n                    u_idx = j;\n                }\n            }\n            if (u_idx == -1 || min_dist_prim[u_idx] == INF_LL) break;\n            visited[u_idx] = true;\n            if (parent[u_idx] != -1) {\n                mst_edges.push_back({V_target[parent[u_idx]], V_target[u_idx], min_dist_prim[u_idx]});\n            }\n            for (int v_idx = 0; v_idx < T_size; ++v_idx) {\n                if (!visited[v_idx]) {\n                    long long weight_uv = dist_matrix[V_target[u_idx]][V_target[v_idx]];\n                    if (weight_uv < min_dist_prim[v_idx]) {\n                        min_dist_prim[v_idx] = weight_uv;\n                        parent[v_idx] = u_idx;\n                    }\n                }\n            }\n        }\n    }\n\n    // Reconstruct the connected subgraph V_prime and E_prime\n    vector<bool> is_in_prime(N, false);\n    is_in_prime[0] = true;\n    vector<int> B(M, 0);\n\n    for (auto& me : mst_edges) {\n        int u = me.u;\n        int v = me.v;\n        int curr = u;\n        while (curr != v) {\n            int nxt = next_node[curr][v];\n            if (nxt == -1) break;\n            int edge_idx = adj_edge_idx[curr][nxt];\n            if (edge_idx != -1) B[edge_idx] = 1;\n            is_in_prime[nxt] = true;\n            curr = nxt;\n        }\n        is_in_prime[u] = true;\n    }\n\n    // Determine minimal P_i for all i in V_prime to cover all residents\n    vector<int> P(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int best_i = -1;\n        double min_dist_val = 1e20;\n        for (int i = 0; i < N; ++i) {\n            if (is_in_prime[i]) {\n                double dx = (double)stations[i].x - residents[k].x;\n                double dy = (double)stations[i].y - residents[k].y;\n                double cur_dist = sqrt(dx * dx + dy * dy);\n                if (cur_dist < min_dist_val) {\n                    min_dist_val = cur_dist;\n                    best_i = i;\n                }\n            }\n        }\n        if (best_i != -1) {\n            // Use ceil to ensure coverage, subtracting epsilon for precision stability\n            int needed_radius = (int)ceil(min_dist_val - 1e-8);\n            if (needed_radius > P[best_i]) P[best_i] = needed_radius;\n        }\n    }\n\n    // Clamp P_i to maximum possible radius\n    for (int i = 0; i < N; ++i) {\n        if (P[i] > 5000) P[i] = 5000;\n    }\n\n    // Output P values\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    // Output B values\n    for (int i = 0; i < M; ++i) {\n        cout << B[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The problem asks us to transform a random N-tiered pyramid into a min-heap\n * where every ball (x, y) is smaller than its children (x+1, y) and (x+1, y+1).\n * Swaps are allowed only between adjacent balls in 6 directions.\n * \n * Goal: E = 0 (satisfy heap property) and minimize K (swaps), where K <= 10,000.\n * Score: 100,000 - 5K.\n * \n * Approach:\n * A standard heapify (sift-down) algorithm is very efficient (O(M) swaps),\n * where M = N(N+1)/2. For N=30, the maximum number of swaps is roughly 4,500,\n * which guarantees E=0 and a score of at least 100,000 - 5(4500) = 77,500.\n * \n * To improve this, we can use a greedy \"max-violation\" approach.\n * Instead of building the heap in a fixed order, we always pick the most\n * \"severe\" violation (the pair (parent, child) with the largest difference\n * b[parent] - b[child]) and swap them. This is essentially a hill-climbing\n * approach that directly addresses the largest heap property violations.\n * \n * This greedy approach is likely to reduce the total number of swaps K\n * compared to a standard bottom-up heapify, leading to a higher score.\n */\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nstruct Violation {\n    int diff;\n    int x, y;\n    int type; // 0 for child (x+1, y), 1 for child (x+1, y+1)\n\n    bool operator<(const Violation& other) const {\n        return diff < other.diff;\n    }\n};\n\nconst int N = 30;\nint pyramid[N][N];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> pyramid[i][j])) break;\n        }\n    }\n\n    vector<Swap> swaps;\n    priority_queue<Violation> pq;\n\n    // Function to check for a violation at (x, y) and add to pq\n    auto check_violation = [&](int x, int y) {\n        if (x < 0 || x >= N - 1) return;\n        // Check child 1: (x+1, y)\n        if (y <= x + 1 && pyramid[x][y] > pyramid[x + 1][y]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y], x, y, 0});\n        }\n        // Check child 2: (x+1, y+1)\n        if (y + 1 <= x + 1 && pyramid[x][y] > pyramid[x + 1][y + 1]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y + 1], x, y, 1});\n        }\n    };\n\n    // Initialize priority queue with all initial violations\n    for (int x = 0; x < N - 1; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            check_violation(x, y);\n        }\n    }\n\n    // Greedy swap approach\n    while (!pq.empty() && swaps.size() < 10000) {\n        Violation top = pq.top();\n        pq.pop();\n\n        int x = top.x;\n        int y = top.y;\n        int cx = x + 1;\n        int cy = y + top.type;\n\n        // Check if the violation is still valid and has the same difference\n        if (pyramid[x][y] - pyramid[cx][cy] != top.diff) continue;\n\n        // Perform the swap\n        swaps.push_back({x, y, cx, cy});\n        swap(pyramid[x][y], pyramid[cx][cy]);\n\n        // After swap, violations might have changed for:\n        // 1. (x, y) and its children\n        // 2. (cx, cy) and its children\n        // 3. (x, y)'s parents\n        // 4. (cx, cy)'s parents\n        \n        // Re-check (x, y) and its children\n        check_violation(x, y);\n        // Re-check (cx, cy) and its children\n        check_violation(cx, cy);\n        // Re-check parents of (x, y)\n        if (x > 0) {\n            check_violation(x - 1, y - 1);\n            check_violation(x - 1, y);\n        }\n        // Re-check parents of (cx, cy)\n        if (cx > 0) {\n            check_violation(cx - 1, cy - 1);\n            check_violation(cx - 1, cy);\n        }\n    }\n\n    // Output the results\n    cout << swaps.size() << \"\\n\";\n    for (const auto& s : swaps) {\n        cout << s.x1 << \" \" << s.y1 << \" \" << s.x2 << \" \" << s.y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem analysis:\n * The goal is to minimize inversions in the transport sequence of containers.\n * Containers must be reachable from the entrance during both storage and transportation.\n * Reachable means a path of \"empty\" squares exists from the entrance to the target square.\n * - During storage: Empty means not currently occupied by a container.\n * - During transport: Empty means the container has already been removed from that square.\n *\n * Strategy:\n * 1. Storage Phase: To avoid blocking the entrance, we fill the warehouse from the \"outside-in\".\n *    We prioritize placing containers in the reachable square with the largest distance from the entrance.\n *    This ensures that we don't trap any squares by filling them too early.\n * 2. Transport Phase: We want the transport order to be as close to 0, 1, 2, ... as possible.\n *    A greedy approach: at each step, pick the container with the smallest ID that is currently reachable from the entrance.\n */\n\nstruct Pos {\n    int r, c;\n    bool operator==(const Pos& other) const { return r == other.r && c == other.c; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nint D, N;\nbool is_obstacle[10][10];\nbool is_occupied[10][10]; // true if square is an obstacle or has a container\nint id_at_square[10][10];\nint dist_val[10][10];\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D && !is_obstacle[r][c];\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n\n    // Initialize grids\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            is_obstacle[i][j] = false;\n            is_occupied[i][j] = false;\n            id_at_square[i][j] = -1;\n            dist_val[i][j] = 1000;\n        }\n    }\n\n    // Read obstacle coordinates\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        is_occupied[r][c] = true; // Obstacles are always occupied\n    }\n\n    Pos entrance = {0, (D - 1) / 2};\n\n    // Precompute BFS distances from the entrance to all valid squares\n    queue<Pos> q_bfs;\n    q_bfs.push(entrance);\n    dist_val[entrance.r][entrance.c] = 0;\n    while (!q_bfs.empty()) {\n        Pos curr = q_bfs.front();\n        q_bfs.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i], nc = curr.c + dc[i];\n            if (is_valid(nr, nc) && dist_val[nr][nc] == 1000) {\n                dist_val[nr][nc] = dist_val[curr.r][curr.c] + 1;\n                q_bfs.push({nr, nc});\n            }\n        }\n    }\n\n    int total_containers = D * D - 1 - N;\n\n    // PHASE 1: Storage\n    for (int d = 0; d < total_containers; ++d) {\n        int t_d;\n        if (!(cin >> t_d)) break;\n\n        // Find all currently empty (not occupied) squares reachable from the entrance.\n        // Reachability is defined by a path consisting of empty squares.\n        vector<Pos> reachable_empty;\n        queue<Pos> rq;\n        rq.push(entrance);\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        visited[entrance.r][entrance.c] = true;\n\n        while (!rq.empty()) {\n            Pos curr = rq.front();\n            rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                // We can pass through non-obstacle, non-occupied squares (including entrance)\n                if (is_valid(nr, nc) && !visited[nr][nc] && !is_occupied[nr][nc] && !(nr == entrance.r && nc == entrance.c)) {\n                    visited[nr][nc] = true;\n                    reachable_empty.push_back({nr, nc});\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        // Selection strategy: Pick the reachable empty square furthest from the entrance.\n        // This \"outside-in\" approach helps avoid blocking access to other squares.\n        Pos best_s = {-1, -1};\n        int max_dist = -1;\n\n        for (auto& s : reachable_empty) {\n            if (dist_val[s.r][s.c] > max_dist) {\n                max_dist = dist_val[s.r][s.c];\n                best_s = s;\n            } else if (dist_val[s.r][s.c] == max_dist) {\n                // Tie-breaking using coordinate comparison\n                if (s.r > best_s.r || (s.r == best_s.r && s.c > best_s.c)) {\n                    best_s = s;\n                }\n            }\n        }\n\n        // Fallback (should not be reached given the problem constraints)\n        if (best_s.r == -1) {\n            for (int r = 0; r < D; ++r) {\n                for (int c = 0; c < D; ++c) {\n                    if (is_valid(r, c) && !is_occupied[r][c] && !(r == entrance.r && c == entrance.c)) {\n                        best_s = {r, c};\n                        goto placed;\n                    }\n                }\n            }\n        }\n        placed:\n\n        // Place the container\n        is_occupied[best_s.r][best_s.c] = true;\n        id_at_square[best_s.r][best_s.c] = t_d;\n        cout << best_s.r << \" \" << best_s.c << endl;\n    }\n\n    // PHASE 2: Transport\n    vector<bool> container_transported(total_containers, false);\n    for (int step = 0; step < total_containers; ++step) {\n        // 1. Determine which squares are \"empty\" and reachable from the entrance.\n        // Reachable empty squares are those we can walk through to reach a container.\n        vector<vector<bool>> reachable_empty_grid(D, vector<bool>(D, false));\n        queue<Pos> rq;\n        rq.push(entrance);\n        reachable_empty_grid[entrance.r][entrance.c] = true;\n        while (!rq.empty()) {\n            Pos curr = rq.front();\n            rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                if (is_valid(nr, nc) && !reachable_empty_grid[nr][nc] && !is_occupied[nr][nc]) {\n                    reachable_empty_grid[nr][nc] = true;\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        // 2. Find the container with the smallest ID that is currently reachable.\n        // A container at S is reachable if S is adjacent to a reachable empty square.\n        int best_id = 1e9;\n        Pos best_pos = {-1, -1};\n\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                int id = id_at_square[r][c];\n                if (id != -1 && !container_transported[id]) {\n                    bool can_reach = false;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r + dr[i], nc = c + dc[i];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && reachable_empty_grid[nr][nc]) {\n                            can_reach = true;\n                            break;\n                        }\n                    }\n                    if (can_reach) {\n                        if (id < best_id) {\n                            best_id = id;\n                            best_pos = {r, c};\n                        }\n                    }\n                }\n            }\n        }\n\n        // 3. Transport the chosen container and mark the square as empty.\n        if (best_id != 1e9) {\n            container_transported[best_id] = true;\n            is_occupied[best_pos.r][best_pos.c] = false; \n            id_at_square[best_pos.r][best_pos.c] = -1;\n            cout << best_pos.r << \" \" << best_pos.c << \"\\n\";\n        } else {\n            // This block should logically not be hit if storage was successful.\n            break;\n        }\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to represent a given adjacency graph of colors (wards) on an n x n grid,\n * minimizing the number of tiles used for the wards (maximizing the number of color 0 tiles).\n * The adjacencies between any two colors (including color 0) must be identical to the original.\n * Each color must form a connected set of tiles.\n * \n * Since the adjacency graph is planar (derived from a map), and the grid (50x50) is much larger \n * than the number of colors (100), we can use a greedy approach.\n * We place each color one by one using a BFS-based path construction.\n * To maintain the \"identical adjacency\" property, we use a \"safe cell\" condition:\n * a cell is safe for color c if it is currently color 0 and all its non-zero neighbors \n * are colors that c is actually adjacent to in the original map.\n * \n * Algorithm:\n * 1. Construct the adjacency graph G from the input.\n * 2. Use a BFS order starting from color 0 to decide the order of placing colors.\n * 3. For each color c:\n *    a. Identify the set T of colors already placed that c is adjacent to in G.\n *    b. Find a path of \"safe\" cells that connects c to all colors in T.\n *    c. A cell is safe if it's 0 and all its neighbors in the current grid belong to T.\n *    d. Use BFS to find the shortest paths connecting these target colors.\n *    e. Update the grid by coloring these cells with c.\n * 4. Output the resulting grid.\n */\n\nconst int N = 50;\nint grid[N][N];\nint n, m;\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < n && c >= 0 && c < n;\n}\n\n// A cell is safe for color c if it's 0 and its non-0 neighbors are all in the target set T.\nbool is_safe(int r, int c, const set<int>& T) {\n    if (grid[r][c] != 0) return false;\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (is_valid(nr, nc)) {\n            if (grid[nr][nc] != 0) {\n                if (T.find(grid[nr][nc]) == T.end()) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> original_grid(n, vector<int>(n));\n    set<int> adj[105]; // m can be up to 100\n    \n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> original_grid[i][j];\n        }\n    }\n\n    // Build the adjacency graph from the input map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = original_grid[i][j];\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (is_valid(ni, nj)) {\n                    int nc = original_grid[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                        adj[nc].insert(c);\n                    }\n                } else {\n                    // Adjacent to the outside (represented by color 0)\n                    if (c != 0) {\n                        adj[c].insert(0);\n                        adj[0].insert(c);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initialize the output grid with 0\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            grid[i][j] = 0;\n        }\n    }\n\n    // Determine the order of placement using BFS from color 0\n    vector<int> bfs_order;\n    queue<int> q_bfs;\n    q_bfs.push(0);\n    vector<bool> visited_bfs(m + 1, false);\n    visited_bfs[0] = true;\n    while (!q_bfs.empty()) {\n        int u = q_bfs.front();\n        q_bfs.pop();\n        if (u != 0) bfs_order.push_back(u);\n        for (int v : adj[u]) {\n            if (v <= m && v != 0 && !visited_bfs[v]) {\n                visited_bfs[v] = true;\n                q_bfs.push(v);\n            }\n        }\n    }\n    // Add any unvisited colors just in case\n    for (int i = 1; i <= m; ++i) {\n        if (!visited_bfs[i]) bfs_order.push_back(i);\n    }\n\n    set<int> P = {0}; // Colors already placed in the output grid\n\n    for (int c : bfs_order) {\n        // T is the set of colors already in the grid that c must be adjacent to\n        set<int> T;\n        for (int neighbor : adj[c]) {\n            if (P.count(neighbor)) {\n                T.insert(neighbor);\n            }\n        }\n\n        if (T.empty()) continue;\n\n        vector<Pos> Sc; // Set of cells to be assigned color c\n        Pos start_pos = {-1, -1};\n        bool found_start = false;\n        \n        // Find a starting safe cell adjacent to the first color in T\n        int d_first = *T.begin();\n        if (d_first != 0) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (grid[i][j] == d_first) {\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && is_safe(ni, nj, T)) {\n                                start_pos = {ni, nj};\n                                found_start = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            // If the first color is 0, any safe cell adjacent to 0 works\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        bool adj_to_zero = false;\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && grid[ni][nj] == 0) {\n                                adj_to_zero = true;\n                                break;\n                            }\n                        }\n                        if (adj_to_zero) {\n                            start_pos = {i, j};\n                            found_start = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: if no specifically adjacent start cell is found, pick any safe cell\n        if (!found_start) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        start_pos = {i, j};\n                        found_start = true;\n                    }\n                }\n            }\n        }\n\n        if (found_start) {\n            Sc.push_back(start_pos);\n            // Iteratively connect Sc to every other color in T using BFS\n            for (int d : T) {\n                if (d == d_first) continue;\n                \n                // Check if Sc is already adjacent to color d\n                bool already_adj = false;\n                for (auto p : Sc) {\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = p.r + dr[k], nj = p.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            already_adj = true;\n                            break;\n                        }\n                    }\n                    if (already_adj) break;\n                }\n                if (already_adj) continue;\n\n                // BFS to find the shortest path of safe cells to color d\n                queue<Pos> q;\n                vector<vector<int>> dist(n, vector<int>(n, -1));\n                vector<vector<Pos>> parent(n, vector<Pos>(n, {-1, -1}));\n                for (auto p : Sc) {\n                    q.push(p);\n                    dist[p.r][p.c] = 0;\n                }\n                Pos end_pos = {-1, -1};\n                while (!q.empty()) {\n                    Pos curr = q.front(); q.pop();\n                    bool adj_to_d = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = curr.r + dr[k], nj = curr.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            adj_to_d = true; \n                            break;\n                        }\n                    }\n                    if (adj_to_d) {\n                        end_pos = curr;\n                        break;\n                    }\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = curr.r + dr[k], nc = curr.c + dc[k];\n                        if (is_valid(nr, nc) && dist[nr][nc] == -1 && is_safe(nr, nc, T)) {\n                            dist[nr][nc] = dist[curr.r][curr.c] + 1;\n                            parent[nr][nc] = curr;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                // If a path is found, add it to the set Sc\n                if (end_pos.r != -1) {\n                    Pos curr = end_pos;\n                    while (dist[curr.r][curr.c] != 0) {\n                        Sc.push_back(curr);\n                        curr = parent[curr.r][curr.c];\n                    }\n                }\n            }\n            // Update grid with color c\n            for (auto p : Sc) grid[p.r][p.c] = c;\n            P.insert(c);\n        }\n    }\n\n    // Print the resulting map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc025":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to divide N items into D sets of equal total weight as much as possible, \n * given that item weights are unknown and we can only query the balance.\n * \n * Strategy:\n * 1. Estimate item weights: Use a gradient descent-based approach (specifically, Adam optimizer) \n *    to find weights that satisfy the comparison queries. We use the logarithm of weights \n *    (x_i = log(w_i)) to ensure weights are always positive and to handle potential scale issues.\n * 2. Intelligent Queries: In each step, pick items for the balance that make the sums on both sides \n *    as close as possible. This maximizes information gain when the balance result is unexpected.\n * 3. Partitioning: Once weights are estimated, use a Greedy approach combined with local \n *    search (hill climbing) to minimize the variance of the sums of weights in each set.\n */\n\nstruct Query {\n    vector<int> L, R;\n    char res;\n};\n\nint main() {\n    // Speed up input and output\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // x_i stores the log of the estimated weight w_i\n    vector<double> x(N, 0.0);\n    // Adam optimizer parameters\n    vector<double> m(N, 0.0); // First moment\n    vector<double> v(N, 0.0); // Second moment\n    double beta1 = 0.9, beta2 = 0.999, eps = 1e-8, alpha = 0.01;\n    double lambda = 0.01; // Regularization constant\n    vector<Query> queries;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int t_adam = 0; // Time step for Adam\n\n    for (int q = 0; q < Q; ++q) {\n        // Step 1: Select L and R for the query. \n        // We want |sum(L) - sum(R)| to be small.\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n\n        vector<int> best_L, best_R;\n        double best_diff = 1e18;\n\n        // Try multiple randomized greedy attempts to find good L and R\n        for (int attempt = 0; attempt < 40; ++attempt) {\n            vector<int> L, R;\n            double sumL = 0, sumR = 0;\n\n            // Ensure sets are non-empty\n            int i1 = indices[0], i2 = indices[1];\n            L.push_back(i1); sumL += exp(x[i1]);\n            R.push_back(i2); sumR += exp(x[i2]);\n\n            for (int i = 2; i < N; ++i) {\n                int idx = indices[i];\n                double val = exp(x[idx]);\n                double diff_L = abs(sumL + val - sumR);\n                double diff_R = abs(sumL - (sumR + val));\n                double diff_none = abs(sumL - sumR);\n\n                // Greedily decide to add item to L, R, or skip it\n                if (diff_L < diff_R && diff_L < diff_none) {\n                    L.push_back(idx);\n                    sumL += val;\n                } else if (diff_R < diff_none) {\n                    R.push_back(idx);\n                    sumR += val;\n                }\n            }\n\n            double diff = abs(sumL - sumR);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_L = L;\n                best_R = R;\n            }\n        }\n\n        // Output selected sets for the balance query\n        cout << best_L.size() << \" \" << best_R.size();\n        for (int idx : best_L) cout << \" \" << idx;\n        for (int idx : best_R) cout << \" \" << idx;\n        cout << endl;\n\n        char res;\n        if (!(cin >> res)) break;\n        queries.push_back({best_L, best_R, res});\n\n        // Step 2: Update weight estimates using Adam optimizer on recent queries\n        int M_window = min((int)queries.size(), 150);\n        int K_steps = 4;\n        for (int k_step = 0; k_step < K_steps; ++k_step) {\n            t_adam++;\n            vector<double> g(N, 0.0);\n            for (int i = 0; i < M_window; ++i) {\n                const auto& query = queries[queries.size() - 1 - i];\n                double sumL = 0, sumR = 0;\n                for (int idx : query.L) sumL += exp(x[idx]);\n                for (int idx : query.R) sumR += exp(x[idx]);\n                double d = sumL - sumR;\n\n                // Calculate gradient of squared loss function\n                if (query.res == '<') {\n                    if (d > 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '>') {\n                    if (d < 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '=') {\n                    for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                    for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                }\n            }\n            // Add regularization gradient to prevent x_i from exploding\n            for (int i = 0; i < N; ++i) g[i] += 2 * lambda * x[i];\n\n            // Adam update step\n            for (int i = 0; i < N; ++i) {\n                m[i] = beta1 * m[i] + (1.0 - beta1) * g[i];\n                v[i] = beta2 * v[i] + (1.0 - beta2) * g[i] * g[i];\n                double m_hat = m[i] / (1.0 - pow(beta1, t_adam));\n                double v_hat = v[i] / (1.0 - pow(beta2, t_adam));\n                x[i] -= alpha * m_hat / (sqrt(v_hat) + eps);\n            }\n        }\n    }\n\n    // Step 3: Final Division\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = exp(x[i]);\n\n    vector<int> d(N);\n    vector<double> set_sum(D, 0.0);\n\n    // Initial division using a greedy approach\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    for (int idx : p) {\n        int best_s = 0;\n        for (int s = 1; s < D; ++s) {\n            if (set_sum[s] < set_sum[best_s]) best_s = s;\n        }\n        d[idx] = best_s;\n        set_sum[best_s] += w[idx];\n    }\n\n    // Refine partition using hill climbing to minimize sum of squares (proportional to variance)\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            int old_s = d[i];\n            for (int new_s = 0; new_s < D; ++new_s) {\n                if (old_s == new_s) continue;\n                \n                double old_sum_sq = 0;\n                for (int s = 0; s < D; ++s) old_sum_sq += set_sum[s] * set_sum[s];\n                \n                double temp_sum_old = set_sum[old_s] - w[i];\n                double temp_sum_new = set_sum[new_s] + w[i];\n                double new_sum_sq_val = old_sum_sq - set_sum[old_s]*set_sum[old_s] - set_sum[new_s]*set_sum[new_s] + temp_sum_old*temp_sum_old + temp_sum_new*temp_sum_new;\n                \n                // If moving item i to new_s reduces the sum of squared set weights, accept move\n                if (new_sum_sq_val < old_sum_sq - 1e-7) {\n                    set_sum[old_s] -= w[i];\n                    set_sum[new_s] += w[i];\n                    d[i] = new_s;\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <deque>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to remove boxes in order 1, 2, ..., n.\n * - A box can be removed (Operation 2, cost 0) only if it is at the top of its stack.\n * - If a box v is not at the top, we must move all boxes above it to another stack (Operation 1, cost k+1).\n * - Our goal is to minimize total energy (sum of k+1).\n * \n * Key Insight:\n * - To minimize future costs, we want stacks to be in \"descending order\" from bottom to top.\n * - If a stack is [..., 5, 4, 3, 2, 1] (top is 1), then after removing 1, 2 becomes the top, then 3, etc.\n * - This way, many boxes can be removed using Operation 2 (cost 0) instead of Operation 1.\n * - A \"violation\" is defined as a pair (x, y) where x is below y but x < y.\n * - We use a greedy approach: when moving boxes above v to another stack, we pick the stack\n *   that minimizes the number of violations in the resulting stack, with a tie-breaker\n *   of minimizing the total stack size.\n * \n * Complexity:\n * - n=200, m=10.\n * - For each of the n boxes, we check m-1 possible target stacks.\n * - Each check takes O(n) to count violations.\n * - Total complexity: O(n^2 * m), which is ~400,000 operations. Well within 2.0s.\n */\n\n// Function to count the number of violations (x < y where x is below y) in a stack\nint count_violations(const deque<int>& s) {\n    int violations = 0;\n    for (size_t i = 0; i + 1 < s.size(); ++i) {\n        if (s[i] < s[i + 1]) {\n            violations++;\n        }\n    }\n    return violations;\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    // stacks[i] stores the boxes in stack i (bottom to top)\n    vector<deque<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n\n    // Record all operations to output at the end\n    // (v, 0) for Operation 2, (v, i) for Operation 1 (i is 1-indexed)\n    vector<pair<int, int>> operations;\n\n    for (int v = 1; v <= n; ++v) {\n        int current_stack_idx = -1;\n        int v_pos = -1;\n\n        // Step 1: Find the current position and stack of box v\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                    current_stack_idx = i;\n                    v_pos = j;\n                    break;\n                }\n            }\n            if (current_stack_idx != -1) break;\n        }\n\n        // Step 2: If v is not at the top, move all boxes above it to another stack\n        if (v_pos < (int)stacks[current_stack_idx].size() - 1) {\n            // The box immediately above v is our target for Operation 1\n            int u_idx = v_pos + 1;\n            int u = stacks[current_stack_idx][u_idx];\n\n            // Collect all boxes to be moved (from u to the current top)\n            vector<int> to_move;\n            for (int k = u_idx; k < (int)stacks[current_stack_idx].size(); ++k) {\n                to_move.push_back(stacks[current_stack_idx][k]);\n            }\n\n            // Greedy decision: Which stack to move these boxes to?\n            int best_target_idx = -1;\n            long long min_cost = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == current_stack_idx) continue;\n\n                // Simulate adding the moved part to stack i\n                deque<int> simulated_stack = stacks[i];\n                for (int val : to_move) {\n                    simulated_stack.push_back(val);\n                }\n\n                // Cost function: prioritize minimizing violations, then minimize stack size\n                // Large weight for violations to ensure it is the primary objective\n                long long cost = (long long)count_violations(simulated_stack) * 10000LL + (long long)simulated_stack.size();\n\n                if (best_target_idx == -1 || cost < min_cost) {\n                    min_cost = cost;\n                    best_target_idx = i;\n                }\n            }\n\n            // Perform the chosen move\n            // Remove the moved boxes from the current stack\n            for (size_t k = 0; k < to_move.size(); ++k) {\n                stacks[current_stack_idx].pop_back();\n            }\n            // Add the moved boxes to the target stack\n            for (int val : to_move) {\n                stacks[best_target_idx].push_back(val);\n            }\n\n            // Record Operation 1 (u, target_stack_1_indexed)\n            operations.push_back({u, best_target_idx + 1});\n        }\n\n        // Step 3: v is now at the top of its stack, remove it using Operation 2\n        operations.push_back({v, 0});\n        stacks[current_stack_idx].pop_back();\n    }\n\n    // Step 4: Output the operations\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize the average dirtiness over an infinite period.\n * The average dirtiness of a square (i, j) is given by (d_{i,j} * (T_{i,j} - 1) / 2),\n * where T_{i,j} is the interval between visits to square (i, j).\n * If we have a cleaning route of length L, and m_{i,j} is the number of visits to \n * square (i, j), then T_{i,j} = L / m_{i,j}.\n * The total average dirtiness is S = sum_{i,j} [d_{i,j} * (L/m_{i,j} - 1) / 2].\n * S = (L/2) * sum_{i,j} (d_{i,j}/m_{i,j}) - (1/2) * sum_{i,j} d_{i,j}.\n * To minimize this, the frequency f_{i,j} = m_{i,j}/L should be proportional to sqrt(d_{i,j}).\n *\n * Algorithm:\n * 1. Generate an initial cleaning route using DFS that visits all reachable squares \n *    and returns to (0, 0). This route ensures each edge is traversed twice.\n * 2. Use a greedy approach to add \"detours\" to this route. A detour on edge (u, v) \n *    consists of moves u -> v -> u -> v, which increases m_u and m_v by 1 and \n *    increases the total length L by 2.\n * 3. The benefit (change in S) of adding a detour to edge (u, v) is:\n *    Delta S = -((L/2) + 1) * (d_u / (m_u * (m_u + 1)) + d_v / (m_v * (m_v + 1))) + Sigma,\n *    where Sigma = sum_{i,j} (d_{i,j}/m_{i,j}).\n * 4. We use a priority queue to greedily select the edge that provides the most \n *    negative Delta S, updating Sigma and L as we add detours, until the length \n *    reaches 10^5 or no more improvements are possible.\n */\n\nstruct Square {\n    int r, c;\n};\n\nint N;\nvector<string> h_walls;\nvector<string> v_walls;\nvector<vector<int>> d;\nbool visited[40][40];\nvector<Square> path;\nvector<char> move_chars;\n\n// DFS to generate a route that visits all reachable squares and returns to (0,0).\nvoid dfs(int r, int c) {\n    visited[r][c] = true;\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n    char move_c[] = {'R', 'D', 'L', 'U'};\n    char back_c[] = {'L', 'U', 'R', 'D'};\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {\n            bool wall = false;\n            if (i == 0) wall = (v_walls[r][c] == '1'); // Right\n            else if (i == 1) wall = (h_walls[r][c] == '1'); // Down\n            else if (i == 2) wall = (v_walls[nr][nc] == '1'); // Left\n            else if (i == 3) wall = (h_walls[nr][nc] == '1'); // Up\n\n            if (!wall) {\n                move_chars.push_back(move_c[i]);\n                path.push_back({nr, nc});\n                dfs(nr, nc);\n                move_chars.push_back(back_c[i]);\n                path.push_back({r, c});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[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    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited[i][j] = false;\n        }\n    }\n\n    path.push_back({0, 0});\n    dfs(0, 0);\n\n    int L = move_chars.size();\n    vector<int> m(N * N, 0);\n    for (int i = 0; i < L; ++i) {\n        m[path[i].r * N + path[i].c]++;\n    }\n\n    double sigma = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sigma += (double)d[i][j] / m[i * N + j];\n        }\n    }\n\n    auto get_delta = [&](int k, int current_L) {\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double term1 = (double)d[u / N][u % N] / (m[u] * (m[u] + 1.0));\n        double term2 = (double)d[v / N][v % N] / (m[v] * (m[v] + 1.0));\n        double delta = -(current_L / 2.0 + 1.0) * (term1 + term2) + sigma;\n        return delta;\n    };\n\n    priority_queue<pair<double, int>> pq;\n    for (int k = 0; k < L; ++k) {\n        pq.push({-get_delta(k, L), k});\n    }\n\n    vector<int> detours(L, 0);\n    int current_L = L;\n\n    while (current_L + 2 <= 100000 && !pq.empty()) {\n        pair<double, int> top = pq.top();\n        pq.pop();\n\n        int k = top.second;\n        double neg_delta = top.first;\n\n        double current_delta = get_delta(k, current_L);\n        if (current_delta > -1e-9) break; \n\n        // Lazy update check\n        if (abs(neg_delta - (-current_delta)) > 1e-7) {\n            pq.push({-current_delta, k});\n            continue;\n        }\n\n        // Add detour\n        detours[k]++;\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double du = (double)d[u / N][u % N];\n        double dv = (double)d[v / N][v % N];\n        double mu = (double)m[u];\n        double mv = (double)m[v];\n\n        sigma = sigma - du / mu - dv / mv + du / (mu + 1.0) + dv / (mv + 1.0);\n        m[u]++;\n        m[v]++;\n        current_L += 2;\n\n        pq.push({-get_delta(k, current_L), k});\n    }\n\n    string final_route = \"\";\n    for (int k = 0; k < L; ++k) {\n        final_route += move_chars[k];\n        if (detours[k] > 0) {\n            char move_k = move_chars[k];\n            char rev_move_k;\n            if (move_k == 'R') rev_move_k = 'L';\n            else if (move_k == 'L') rev_move_k = 'R';\n            else if (move_k == 'U') rev_move_k = 'D';\n            else rev_move_k = 'U';\n\n            for (int i = 0; i < detours[k]; ++i) {\n                final_route += rev_move_k;\n                final_route += move_k;\n            }\n        }\n    }\n\n    cout << final_route << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Kakizome Taikai\n * Strategy:\n * 1. Precompute distances and overlaps between strings.\n * 2. Precompute the minimum cost to add a suffix of each target string t[k]\n *    starting from any (r_s, c_s) and ending at any (r_e, c_e).\n *    Since the number of states (M * 5 * N^2 * N^2) is around 5 * 10^7,\n *    we store it in an unsigned short array of about 100 MB.\n * 3. Use Simulated Annealing to optimize the order in which we attempt to cover the target strings.\n *    The scoring function for SA prioritizes covering all M strings (K=M) \n *    and then minimizes the total cost T.\n * 4. Reconstruct the final path using the best order found.\n */\n\nconst int MAX_N = 15;\nconst int MAX_M = 200;\nconst int MAX_S = 225;\nconst unsigned short INF = 32767;\n\nint N, M;\nint si, sj;\nstring A[MAX_N];\nstring t[MAX_M];\nint dist[MAX_N][MAX_N][MAX_N][MAX_N];\nint overlap_mat[MAX_M][MAX_M];\n\n// pre[k][p][r_s*N+c_s][r_e*N+c_e]\nunsigned short pre[MAX_M][5][MAX_S][MAX_S];\n\nvoid precompute() {\n    for (int r1 = 0; r1 < N; ++r1)\n        for (int c1 = 0; c1 < N; ++c1)\n            for (int r2 = 0; r2 < N; ++r2)\n                for (int c2 = 0; c2 < N; ++c2)\n                    dist[r1][c1][r2][c2] = abs(r1 - r2) + abs(c1 - c2) + 1;\n\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            int max_ov = 0;\n            for (int len = 1; len <= 4; ++len) {\n                if (t[i].substr(5 - len) == t[j].substr(0, len)) {\n                    max_ov = len;\n                }\n            }\n            overlap_mat[i][j] = max_ov;\n        }\n    }\n\n    for (int k = 0; k < M; ++k) {\n        for (int p = 0; p < 5; ++p) {\n            string suffix = t[k].substr(p);\n            int L = suffix.length();\n            for (int rs = 0; rs < N; ++rs) {\n                for (int cs = 0; cs < N; ++cs) {\n                    vector<vector<unsigned short>> dp(L + 1, vector<unsigned short>(N * N, INF));\n                    // Base case: first character of suffix\n                    for (int r = 0; r < N; ++r) {\n                        for (int c = 0; c < N; ++c) {\n                            if (A[r][c] == suffix[0]) {\n                                if (L == 1) {\n                                    // if L=1, dp[1][r][c] is already the cost to type first char.\n                                    // But we need it relative to (rs, cs).\n                                    // To simplify, let's just let dp[1][r][c] be the movement + 1.\n                                }\n                                dp[1][r * N + c] = dist[rs][cs][r][c];\n                            }\n                        }\n                    }\n\n                    for (int idx = 2; idx <= L; ++idx) {\n                        for (int curr = 0; curr < N * N; ++curr) {\n                            int r = curr / N, c = curr % N;\n                            if (A[r][c] == suffix[idx - 1]) {\n                                for (int prev = 0; prev < N * N; ++prev) {\n                                    if (dp[idx - 1][prev] != INF) {\n                                        int pr = prev / N, pc = prev % N;\n                                        int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                        if (d < dp[idx][curr]) dp[idx][curr] = (unsigned short)d;\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    for (int re = 0; re < N; ++re) {\n                        for (int ce = 0; ce < N; ++ce) {\n                            if (L == 0) pre[k][p][rs * N + cs][re * N + ce] = 0;\n                            else pre[k][p][rs * N + cs][re * N + ce] = dp[L][re * N + ce];\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nstruct EvalResult {\n    long long score;\n    int total_cost;\n    int covered_count;\n    vector<pair<int, int>> sequence;\n};\n\nint get_overlap(const string& S, const string& target) {\n    int max_ov = 0;\n    int len_s = S.length();\n    int len_t = target.length();\n    for (int len = 1; len <= min(4, min(len_s, len_t - 1)); ++len) {\n        if (S.substr(len_s - len) == target.substr(0, len)) {\n            max_ov = len;\n        }\n    }\n    // The problem says overlap is suffix of S and prefix of target.\n    // Since target length is 5, the prefix can be up to 4 chars.\n    // But a 5-char overlap means the target is already a substring.\n    // However, the problem states the target string is length 5.\n    // A 5-char overlap would only happen if target is exactly S.suffix(5).\n    // Let's check len=4, 3, 2, 1.\n    return max_ov;\n}\n\n// More robust overlap\nint get_overlap_robust(const string& S, const string& target) {\n    int max_ov = 0;\n    int s_len = S.length();\n    int t_len = target.length();\n    for (int len = 1; len <= 4; ++len) {\n        if (len <= s_len && len < t_len) {\n            if (S.substr(s_len - len) == target.substr(0, len)) {\n                max_ov = len;\n            }\n        }\n    }\n    return max_ov;\n}\n\nEvalResult evaluate(const vector<int>& order) {\n    string S = \"\";\n    int curr_r = si, curr_c = sj;\n    int cost = 0;\n    int covered_count = 0;\n    vector<bool> covered(M, false);\n    vector<pair<int, int>> sequence;\n\n    for (int k : order) {\n        if (covered[k]) continue;\n\n        int p = get_overlap_robust(S, t[k]);\n        string suffix = t[k].substr(p);\n        \n        int best_cost = 30000;\n        int best_r = -1, best_c = -1;\n        \n        int rs_idx = curr_r * N + curr_c;\n        for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n            if (pre[k][p][rs_idx][re_idx] < best_cost) {\n                best_cost = pre[k][p][rs_idx][re_idx];\n                best_r = re_idx / N;\n                best_c = re_idx % N;\n            }\n        }\n\n        if (best_r == -1) continue;\n\n        cost += best_cost;\n        for (int i = 0; i < suffix.length(); ++i) {\n            // This is tricky: we need to find the exact path to add to S.\n            // But for SA, we only need the cost and end position.\n            // We'll reconstruct the string S in a simpler way for SA.\n        }\n        // To keep SA fast, we won't build the full S, just track its end.\n        // But we need to know which strings are covered. \n        // Let's just build S. It's not that slow.\n        // Actually, to find which strings are covered, we need the characters.\n        // Let's use a simplified approach for SA.\n        // Since we only need to know if t[j] is a substring, and strings have len 5:\n        // A new t[j] can only be formed if it overlaps with the current S and the added suffix.\n        // Let's just build the added string characters. \n        // We can precompute the path if needed, but let's see.\n        \n        // Wait, a better way: instead of building S, let's just build the *suffix*\n        // that we actually added.\n        \n        // For simplicity, we'll find the path using the DP.\n        // However, doing this in evaluate is too slow.\n        // Let's just track the last 4 characters of S.\n        \n        // Re-calculating S in evaluate:\n        // To make it fast, we need to know what characters were added.\n        // Instead of the full path, let's just track the last 4 chars of S.\n        // But that's not enough to check if a *new* t[j] is covered.\n        // A new t[j] could be covered if it's entirely within the new suffix, \n        // or if it overlaps with the old S.\n        \n        // Let's use a simpler SA: only track cost and covered_count.\n        // To find covered_count, we'll just assume every string is covered in order.\n        // That's not correct. Let's build S.\n        // To build S without full path, we can precompute the added characters.\n        // But the path can be different for different (rs, cs, re, ce).\n        // Let's just use the current get_min_cost_to_add to build the string.\n    }\n    return {0, 0, 0, {}};\n}\n\n// Due to the complexity of the evaluate function, let's use a simpler greedy\n// and then optimize it with SA. The key is a very efficient evaluate.\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    precompute();\n\n    // Since the SA with full string building is slow, let's use a greedy\n    // with a bit of randomness and several restarts.\n\n    auto solve = [&]() {\n        string S = \"\";\n        int curr_r = si, curr_c = sj;\n        int total_cost = 0;\n        vector<bool> covered(M, false);\n        int covered_count = 0;\n        vector<pair<int, int>> final_path;\n\n        while (covered_count < M && final_path.size() < 5000) {\n            int best_k = -1;\n            int best_p = -1;\n            int best_r = -1, best_c = -1;\n            int best_cost = 1e9;\n            double best_ratio = 1e18;\n\n            for (int k = 0; k < M; ++k) {\n                if (covered[k]) continue;\n                int p = get_overlap_robust(S, t[k]);\n                int rs_idx = curr_r * N + curr_c;\n                \n                // We need to find the (re, ce) that minimizes pre[k][p][rs_idx][re_idx]\n                // but also considers how many new strings are covered.\n                // For speed, let's just pick the one with minimum cost.\n                int min_c = 1e9;\n                int min_re = -1, min_ce = -1;\n                for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n                    if (pre[k][p][rs_idx][re_idx] < min_c) {\n                        min_c = pre[k][p][rs_idx][re_idx];\n                        min_re = re_idx / N;\n                        min_ce = re_idx % N;\n                    }\n                }\n\n                if (min_re == -1) continue;\n\n                // To correctly calculate newly_covered, we need the actual added characters.\n                // Since we don't have the path in 'pre', we must reconstruct it.\n                // But we can only do this for the *best* k.\n                \n                // For now, let's use a simple ratio: min_c / (1.0 + epsilon)\n                double ratio = (double)min_c; \n                if (ratio < best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    best_p = p;\n                    best_r = min_re;\n                    best_c = min_ce;\n                    best_cost = min_c;\n                }\n            }\n\n            if (best_k == -1) break;\n\n            // Reconstruct path for best_k\n            string suffix = t[best_k].substr(best_p);\n            int L = suffix.length();\n            vector<pair<int, int>> path;\n            int tr = best_r, tc = best_c;\n            \n            // Use DP to find the path\n            vector<vector<int>> dp(L + 1, vector<int>(N * N, 1e9));\n            vector<vector<int>> parent(L + 1, vector<int>(N * N, -1));\n            \n            // Re-run the DP for the specific suffix and start pos\n            int rs_idx = curr_r * N + curr_c;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (A[r][c] == suffix[0]) {\n                        dp[1][r * N + c] = dist[curr_r][curr_c][r][c];\n                    }\n                }\n            }\n            for (int idx = 2; idx <= L; ++idx) {\n                for (int curr = 0; curr < N * N; ++curr) {\n                    int r = curr / N, c = curr % N;\n                    if (A[r][c] == suffix[idx - 1]) {\n                        for (int prev = 0; prev < N * N; ++prev) {\n                            if (dp[idx - 1][prev] != 1e9) {\n                                int pr = prev / N, pc = prev % N;\n                                int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                if (d < dp[idx][curr]) {\n                                    dp[idx][curr] = d;\n                                    parent[idx][curr] = prev;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int cur_idx = best_r * N + best_c;\n            for (int i = L; i >= 1; --i) {\n                path.push_back({cur_idx / N, cur_idx % N});\n                cur_idx = parent[i][cur_idx];\n            }\n            reverse(path.begin(), path.end());\n\n            string added_chars = \"\";\n            for (auto p_idx : path) added_chars += A[p_idx.first][p_idx.second];\n            \n            S += added_chars;\n            for (auto p_idx : path) final_path.push_back(p_idx);\n            total_cost += best_cost;\n            curr_r = best_r;\n            curr_c = best_c;\n\n            for (int i = 0; i < M; ++i) {\n                if (!covered[i] && S.find(t[i]) != string::npos) {\n                    covered[i] = true;\n                    covered_count++;\n                }\n            }\n        }\n\n        for (auto p_idx : final_path) cout << p_idx.first << \" \" << p_idx.second << \"\\n\";\n    };\n\n    solve();\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct Polyomino {\n    int d;\n    vector<pair<int, int>> shape;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> fields;\nvector<vector<pair<int, int>>> field_positions;\nvector<vector<double>> field_probs;\ndouble Q1[20][20][20];\n\nbool is_valid(int r, int c, const Polyomino& poly) {\n    for (auto& p : poly.shape) {\n        int nr = r + p.first;\n        int nc = c + p.second;\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> fields[i].d;\n        for (int j = 0; j < fields[i].d; ++j) {\n            int r, c;\n            cin >> r >> c;\n            fields[i].shape.push_back({r, c});\n        }\n    }\n\n    field_positions.resize(M);\n    for (int i = 0; i < M; ++i) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_valid(r, c, fields[i])) {\n                    field_positions[i].push_back({r, c});\n                }\n            }\n        }\n    }\n\n    field_probs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        field_probs[i].assign(field_positions[i].size(), 1.0 / (double)field_positions[i].size());\n    }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            for (int m = 0; m < M; ++m)\n                Q1[i][j][m] = 0.0;\n\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n            for (auto& coord : fields[m].shape) {\n                int r = field_positions[m][p].first + coord.first;\n                int c = field_positions[m][p].second + coord.second;\n                if (r >= 0 && r < N && c >= 0 && c < N) {\n                    Q1[r][c][m] += field_probs[m][p];\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> v_known(N, vector<int>(N, -1));\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n\n    for (int step = 0; step < N * N; ++step) {\n        vector<vector<double>> p_ij(N, vector<double>(N, 0.0));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                double prob_zero = 1.0;\n                for (int m = 0; m < M; ++m) {\n                    prob_zero *= (1.0 - Q1[i][j][m]);\n                }\n                p_ij[i][j] = 1.0 - prob_zero;\n            }\n        }\n\n        bool all_certain = true;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j] && p_ij[i][j] > 1e-4 && p_ij[i][j] < (1.0 - 1e-4)) {\n                    all_certain = false;\n                    break;\n                }\n            }\n            if (!all_certain) break;\n        }\n\n        if (all_certain) {\n            vector<pair<int, int>> ans;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (v_known[i][j] > 0 || p_ij[i][j] > 0.5) {\n                        ans.push_back({i, j});\n                    }\n                }\n            }\n            cout << \"a \" << ans.size();\n            for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n            cout << endl;\n            int resp; cin >> resp;\n            return 0;\n        }\n\n        int best_i = -1, best_j = -1;\n        double max_unc = -1.0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!drilled[i][j]) {\n                    double unc = p_ij[i][j] * (1.0 - p_ij[i][j]);\n                    if (unc > max_unc) {\n                        max_unc = unc;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n\n        if (best_i == -1) break;\n\n        cout << \"q 1 \" << best_i << \" \" << best_j << endl;\n        int V;\n        if (!(cin >> V)) break;\n        v_known[best_i][best_j] = V;\n        drilled[best_i][best_j] = true;\n\n        for (int m = 0; m < M; ++m) {\n            vector<double> dp(M + 1, 0.0);\n            dp[0] = 1.0;\n            for (int mp = 0; mp < M; ++mp) {\n                if (mp == m) continue;\n                double q1 = Q1[best_i][best_j][mp];\n                double q0 = 1.0 - q1;\n                for (int s = M; s >= 0; --s) {\n                    dp[s] = dp[s] * q0 + (s > 0 ? dp[s - 1] * q1 : 0.0);\n                }\n            }\n\n            vector<double> old_probs = field_probs[m];\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                bool covered = false;\n                for (auto& coord : fields[m].shape) {\n                    if (field_positions[m][p].first + coord.first == best_i &&\n                        field_positions[m][p].second + coord.second == best_j) {\n                        covered = true;\n                        break;\n                    }\n                }\n                int target = V - (covered ? 1 : 0);\n                if (target >= 0 && target < M) field_probs[m][p] *= dp[target];\n                else field_probs[m][p] = 0.0;\n            }\n\n            double sum_p = 0;\n            for (double pr : field_probs[m]) sum_p += pr;\n            if (sum_p > 1e-18) {\n                for (double& pr : field_probs[m]) pr /= sum_p;\n            } else {\n                field_probs[m].assign(field_positions[m].size(), 1.0 / field_positions[m].size());\n            }\n\n            for (int p = 0; p < (int)field_positions[m].size(); ++p) {\n                double diff = field_probs[m][p] - old_probs[p];\n                if (abs(diff) > 1e-18) {\n                    for (auto& coord : fields[m].shape) {\n                        int r = field_positions[m][p].first + coord.first;\n                        int c = field_positions[m][p].second + coord.second;\n                        if (r >= 0 && r < N && c >= 0 && c < N) {\n                            Q1[r][c][m] += diff;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If we reach here, guess everything we know\n    vector<pair<int, int>> ans;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (v_known[i][j] > 0) ans.push_back({i, j});\n        }\n    }\n    cout << \"a \" << ans.size();\n    for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int resp; cin >> resp;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * 1. The goal is to minimize the total cost, which consists of area shortfall cost and partition cost.\n *    Area shortfall cost: 100 * (desired_area - actual_area).\n *    Partition cost: Total length of partition segments that change between consecutive days.\n * 2. Area shortfall cost is very expensive (100x), so we should prioritize meeting area requirements.\n * 3. Partition cost is proportional to the number of changing horizontal/vertical segments. \n *    If we use horizontal strips (rectangles spanning the full width W), only horizontal partitions exist.\n *    A change in boundary at y-coordinate y costs W (for each of the W horizontal segments at that height).\n * 4. Let the y-coordinates of the boundaries on day d be 0 = y_{d,0} < y_{d,1} < ... < y_{d,N} = W.\n *    The k-th rectangle (k=0...N-1) has height (y_{d,k+1} - y_{d,k}) and area W * (y_{d,k+1} - y_{d,k}).\n *    We ensure the area requirement by setting y_{d,k+1} - y_{d,k} >= ceil(a_{d,k} / W).\n * 5. To minimize partition cost, we want the boundaries y_{d,k} on day d to be the same as day d-1\n *    as much as possible. This can be modeled as maximizing the number of shared boundary coordinates.\n * 6. We can use Dynamic Programming (DP) for each day to find the best set of boundaries.\n *    dp[k][y] = maximum number of boundaries in {y_{d,1}, ..., y_{d,k}} that are in S_{d-1}, \n *    where y_{d,k} = y.\n *    Complexity: O(D * N * W), which is roughly 50 * 50 * 1000 = 2.5 * 10^6 operations.\n */\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i][j];\n        }\n    }\n\n    // y_vals[d][k] is the y-coordinate of the boundary after the (k-1)-th rectangle.\n    // y_vals[d][0] = 0, y_vals[d][N] = W.\n    vector<vector<int>> y_vals(D, vector<int>(N + 1));\n\n    for (int d = 0; d < D; ++d) {\n        // H[k] is the minimum height (integer) required for the k-th rectangle to satisfy area a[d][k].\n        vector<int> H(N);\n        for (int k = 0; k < N; ++k) {\n            H[k] = (a[d][k] + W - 1) / W;\n            if (H[k] < 1) H[k] = 1;\n        }\n\n        // Pre-calculate cumulative minimum heights to define valid ranges for y_vals[d][k].\n        vector<int> PreH(N + 1, 0);\n        for (int k = 0; k < N; ++k) PreH[k + 1] = PreH[k] + H[k];\n\n        vector<int> SufH(N + 1, 0);\n        for (int k = N - 1; k >= 0; --k) SufH[k] = SufH[k + 1] + H[k];\n\n        if (d == 0) {\n            // First day partition installation cost is 0, so just satisfy requirements.\n            y_vals[d][0] = 0;\n            for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n            y_vals[d][N] = W;\n        } else {\n            // Identify which boundary y-coordinates were used on the previous day.\n            vector<bool> is_in_S_prev(W + 1, false);\n            for (int k = 1; k < N; ++k) {\n                is_in_S_prev[y_vals[d - 1][k]] = true;\n            }\n\n            // dp[k][y] = max common boundaries in {y_{d,1}, ..., y_{d,k}} with y_{d,k} = y.\n            // k ranges from 1 to N-1.\n            vector<vector<int>> dp(N, vector<int>(W + 1, -1000000));\n            vector<vector<int>> parent(N, vector<int>(W + 1, -1));\n\n            // Base case: k=0, y_{d,0}=0.\n            dp[0][0] = 0;\n\n            for (int k = 1; k < N; ++k) {\n                // Use prefix maximum optimization to speed up the DP transition to O(1) per state.\n                vector<int> pref_max(W + 1, -1000000);\n                vector<int> pref_max_idx(W + 1, -1);\n                int cur_max = -1000000;\n                int cur_idx = -1;\n                for (int i = 0; i <= W; ++i) {\n                    if (dp[k - 1][i] > cur_max) {\n                        cur_max = dp[k - 1][i];\n                        cur_idx = i;\n                    }\n                    pref_max[i] = cur_max;\n                    pref_max_idx[i] = cur_idx;\n                }\n\n                // Iterate over valid y-coordinates for the k-th boundary.\n                for (int y = PreH[k]; y <= W - SufH[k]; ++y) {\n                    int max_y_prev = y - H[k - 1];\n                    if (max_y_prev >= 0) {\n                        int val = pref_max[max_y_prev];\n                        if (val >= 0) {\n                            dp[k][y] = val + (is_in_S_prev[y] ? 1 : 0);\n                            parent[k][y] = pref_max_idx[max_y_prev];\n                        }\n                    }\n                }\n            }\n\n            // Backtrack to find the optimal boundaries.\n            int best_y = -1;\n            int max_val = -1000000;\n            for (int y = PreH[N - 1]; y <= W - SufH[N - 1]; ++y) {\n                if (dp[N - 1][y] > max_val) {\n                    max_val = dp[N - 1][y];\n                    best_y = y;\n                }\n            }\n\n            y_vals[d][N] = W;\n            y_vals[d][0] = 0;\n            if (best_y != -1) {\n                y_vals[d][N - 1] = best_y;\n                for (int k = N - 1; k >= 1; --k) {\n                    y_vals[d][k - 1] = parent[k][y_vals[d][k]];\n                }\n            } else {\n                // Safety fallback if the DP failed (should not occur).\n                for (int k = 1; k < N; ++k) y_vals[d][k] = PreH[k];\n                y_vals[d][0] = 0;\n                y_vals[d][N] = W;\n            }\n        }\n    }\n\n    // Output the rectangles in the required format.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            // Rectangle for k-th reservation on day d.\n            // Top-left (y_vals[d][k], 0), Bottom-right (y_vals[d][k+1], W).\n            cout << y_vals[d][k] << \" \" << 0 << \" \" << y_vals[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\nlong long a[N][N];\nlong long s[M][3][3];\nlong long b[N][N];\n\nstruct Operation {\n    int m, p, q;\n};\n\nOperation slots[K];\nbool occupied[K];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in, k_in;\n    if (!(cin >> n_in >> m_in >> k_in)) return 0;\n\n    // Input initial board\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    // Input stamps\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 >> s[m][i][j];\n\n    // Initialize board and current score\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            b[i][j] = a[i][j];\n\n    long long current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            current_score += b[i][j] % P;\n\n    mt19937_64 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    long long best_score = current_score;\n    vector<Operation> best_ops;\n    for (int i = 0; i < K; ++i) occupied[i] = false;\n\n    // SA parameters\n    double T_start = 1e9;\n    double T_end = 1e-1;\n\n    // Pre-allocate buffers to speed up loop\n    bool is_aff[N][N];\n    pair<int, int> affected[18];\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.85) break; // Leave time for final output\n\n        double T = T_start * pow(T_end / T_start, elapsed / 1.85);\n\n        int i = rng() % K;\n\n        if (occupied[i]) {\n            // Decide between REMOVE or MODIFY\n            int move_type = rng() % 100;\n            if (move_type < 30) { // REMOVE move\n                int m = slots[i].m;\n                int p = slots[i].p;\n                int q = slots[i].q;\n\n                long long delta = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v - s[m][di][dj];\n                        delta += (new_v % P) - (old_v % P);\n                    }\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int r = p + di, c = q + dj;\n                            b[r][c] -= s[m][di][dj];\n                        }\n                    }\n                    occupied[i] = false;\n                    current_score += delta;\n                }\n            } else { // MODIFY move\n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n                int m_old = slots[i].m;\n                int p_old = slots[i].p;\n                int q_old = slots[i].q;\n\n                if (m_new == m_old && p_new == p_old && q_new == q_old) continue;\n\n                // Identify union of cells affected by old and new stamp\n                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) is_aff[r][c] = false;\n                int aff_cnt = 0;\n\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_old + di, c = q_old + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n\n                long long delta = 0;\n                for (int k = 0; k < aff_cnt; ++k) {\n                    int r = affected[k].first, c = affected[k].second;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v;\n                    if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                        new_v -= s[m_old][r - p_old][c - q_old];\n                    if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                        new_v += s[m_new][r - p_new][c - q_new];\n                    delta += (new_v % P) - (old_v % P);\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int k = 0; k < aff_cnt; ++k) {\n                        int r = affected[k].first, c = affected[k].second;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v;\n                        if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                            new_v -= s[m_old][r - p_old][c - q_old];\n                        if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                            new_v += s[m_new][r - p_new][c - q_new];\n                        b[r][c] = new_v;\n                    }\n                    slots[i] = {m_new, p_new, q_new};\n                    current_score += delta;\n                }\n            }\n        } else { // ADD move\n            int m_new = rng() % M;\n            int p_new = rng() % (N - 2);\n            int q_new = rng() % (N - 2);\n\n            long long delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int r = p_new + di, c = q_new + dj;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v + s[m_new][di][dj];\n                    delta += (new_v % P) - (old_v % P);\n                }\n            }\n\n            if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        b[r][c] += s[m_new][di][dj];\n                    }\n                }\n                slots[i] = {m_new, p_new, q_new};\n                occupied[i] = true;\n                current_score += delta;\n            }\n        }\n\n        // Update best known solution\n        if (current_score > best_score) {\n            best_score = current_score;\n            best_ops.clear();\n            for (int k = 0; k < K; ++k) {\n                if (occupied[k]) best_ops.push_back(slots[k]);\n            }\n        }\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/*\nProblem Analysis:\n- The goal is to dispatch N^2 = 25 containers from specific Dispatch Gates.\n- Containers must be dispatched in a specific order: 0, 1, ..., 24.\n- The scoring favors minimizing the total turns (M0), the number of inversions (M1),\n  wrong dispatch gates (M2), and undispatched containers (M3).\n- To minimize M1, M2, and M3, the most important thing is to dispatch containers\n  in the correct order 0, 1, ..., 24 at their respective correct gates (c/N, N-1).\n- We use a single large crane (crane 0) to pick up each container one by one in \n  increasing order.\n- All other cranes are immediately bombed to ensure they don't block the path.\n- The large crane is capable of moving through squares with other containers.\n- BFS is used to find the shortest path for the large crane between target locations.\n*/\n\nint N;\nint A[5][5];\nint grid[5][5];\nint arrival_idx[5];\nint crane_x[5], crane_y[5];\nint crane_holding[5];\nbool container_on_grid[25];\nint container_pos_x[25], container_pos_y[25];\nbool container_dispatched[25];\nint target_c = 0;\n\n// Returns the direction char to move from (sx, sy) to (nx, ny)\nchar get_move_char(int sx, int sy, int nx, int ny) {\n    if (nx < sx) return 'U';\n    if (nx > sx) return 'D';\n    if (ny < sy) return 'L';\n    if (ny > sy) return 'R';\n    return '.';\n}\n\n// BFS to find the next step towards (tx, ty) on a 5x5 grid\npair<int, int> get_next_step(int sx, int sy, int tx, int ty) {\n    if (sx == tx && sy == ty) return {sx, sy};\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    queue<pair<int, int>> q;\n    q.push({sx, sy});\n    int dist[5][5];\n    pair<int, int> parent[5][5];\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    dist[sx][sy] = 0;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        if (curr.first == tx && curr.second == ty) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.first + dx[i];\n            int ny = curr.second + dy[i];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n\n    if (dist[tx][ty] == -1) return {sx, sy};\n\n    // Backtrack to find the first step along the path from (sx, sy)\n    int cx = tx, cy = ty;\n    while (parent[cx][cy].first != sx || parent[cx][cy].second != sy) {\n        pair<int, int> p = parent[cx][cy];\n        cx = p.first;\n        cy = p.second;\n    }\n    return {cx, cy};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            grid[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        arrival_idx[i] = 0;\n        crane_x[i] = i;\n        crane_y[i] = 0;\n        crane_holding[i] = -1;\n    }\n    crane_x[0] = 0;\n    crane_y[0] = 0;\n    for (int i = 0; i < 25; ++i) {\n        container_on_grid[i] = false;\n        container_dispatched[i] = false;\n    }\n\n    // Pre-allocate strings for outputs\n    vector<string> actions(N, string(10000, '.'));\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // 1. Arrivals (Step 1)\n        for (int i = 0; i < N; ++i) {\n            bool crane_holding_at_gate = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_holding[k] != -1 && crane_x[k] == i && crane_y[k] == 0) {\n                    crane_holding_at_gate = true;\n                    break;\n                }\n            }\n            if (arrival_idx[i] < N && grid[i][0] == -1 && !crane_holding_at_gate) {\n                int c = A[i][arrival_idx[i]];\n                grid[i][0] = c;\n                container_on_grid[c] = true;\n                container_pos_x[c] = i;\n                container_pos_y[c] = 0;\n                arrival_idx[i]++;\n            }\n        }\n\n        // 2. Crane Actions (Step 2)\n        // First turn: Bomb all small cranes to clear paths\n        if (turn == 1) {\n            for (int i = 1; i < N; ++i) {\n                actions[i][0] = 'B';\n                // Small cranes are effectively removed from the simulation now\n            }\n        }\n\n        // Decision for the large crane (crane 0)\n        if (crane_holding[0] == -1) {\n            if (target_c < 25) {\n                // Check if target container is on the grid\n                if (container_on_grid[target_c]) {\n                    int rx = container_pos_x[target_c];\n                    int ry = container_pos_y[target_c];\n                    if (crane_x[0] == rx && crane_y[0] == ry) {\n                        // If at the container, pick it up\n                        actions[0][turn - 1] = 'P';\n                        crane_holding[0] = target_c;\n                        grid[rx][ry] = -1;\n                        container_on_grid[target_c] = false;\n                    } else {\n                        // Otherwise, move towards it\n                        pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                        actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                        crane_x[0] = next_pos.first;\n                        crane_y[0] = next_pos.second;\n                    }\n                } else {\n                    // Target container hasn't arrived yet\n                    actions[0][turn - 1] = '.';\n                }\n            } else {\n                actions[0][turn - 1] = '.';\n            }\n        } else {\n            // Large crane is holding a container\n            int c = crane_holding[0];\n            int rx = c / N, ry = N - 1;\n            if (crane_x[0] == rx && crane_y[0] == ry) {\n                // If at target dispatch gate, release it\n                actions[0][turn - 1] = 'Q';\n                grid[rx][ry] = c;\n                crane_holding[0] = -1;\n                target_c++;\n            } else {\n                // Move towards the dispatch gate\n                pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                crane_x[0] = next_pos.first;\n                crane_y[0] = next_pos.second;\n            }\n        }\n\n        // 3. Dispatches (Step 3)\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][N - 1] != -1) {\n                int c = grid[i][N - 1];\n                grid[i][N - 1] = -1;\n                container_on_grid[c] = false;\n                container_dispatched[c] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - The goal is to make all h[i][j] = 0 by loading and unloading soil.\n * - Costs: \n *   - Loading/unloading d units: d.\n *   - Moving to an adjacent square: 100 + current_load.\n * - Strategy:\n *   1. At the current square (r, c), if h[r][c] > 0, we load all the soil (d = h[r][c]).\n *   2. If h[r][c] < 0 and we have soil (cur_load > 0), we unload as much as possible (d = min(cur_load, |h[r][c]|)).\n *   3. If neither is possible (e.g., h[r][c] is 0 or we don't have soil to unload), we move towards:\n *      - The nearest sink (h[i][j] < 0) if we currently have soil (cur_load > 0).\n *      - The nearest source (h[i][j] > 0) if we currently have no soil (cur_load == 0).\n *   4. Repeat until all h[i][j] are 0 and cur_load is 0.\n * - The sum of h[i][j] is guaranteed to be 0, ensuring that we can always find a source or a sink\n *   unless all heights are 0.\n * - The number of turns will be well within the limit of 100,000 because there are N^2 = 400 squares\n *   and the distance between any two squares is at most 40.\n */\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n\n    int cur_r = 0, cur_c = 0, cur_load = 0;\n    vector<string> ops;\n\n    while (true) {\n        if (h[cur_r][cur_c] > 0) {\n            // Step 1: Load soil from the current source\n            int d = h[cur_r][cur_c];\n            h[cur_r][cur_c] = 0;\n            cur_load += d;\n            ops.push_back(\"+\" + to_string(d));\n        } else if (h[cur_r][cur_c] < 0 && cur_load > 0) {\n            // Step 2: Unload soil to the current sink\n            int d = min(cur_load, -h[cur_r][cur_c]);\n            h[cur_r][cur_c] += d;\n            cur_load -= d;\n            ops.push_back(\"-\" + to_string(d));\n        } else {\n            // Step 3: Find the nearest target to move towards\n            int target_r = -1, target_c = -1;\n            int min_dist = 1000000;\n\n            // Greedy search for the nearest relevant square\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (cur_load > 0) {\n                        // If carrying soil, look for a sink\n                        if (h[i][j] < 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    } else {\n                        // If empty, look for a source\n                        if (h[i][j] > 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // If no valid target square is found, we are finished.\n            if (target_r == -1) break;\n\n            // Step 4: Move one step toward the target square\n            if (target_r < cur_r) {\n                ops.push_back(\"U\");\n                cur_r--;\n            } else if (target_r > cur_r) {\n                ops.push_back(\"D\");\n                cur_r++;\n            } else if (target_c < cur_c) {\n                ops.push_back(\"L\");\n                cur_c--;\n            } else if (target_c > cur_c) {\n                ops.push_back(\"R\");\n                cur_c++;\n            } else {\n                // This part should ideally not be reached given the logic above.\n                break;\n            }\n        }\n        \n        // Safety limit for the number of operations\n        if (ops.size() >= 100000) break;\n    }\n\n    // Output the list of operations\n    for (const string& s : ops) {\n        cout << s << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to maximize the maximum sum of evaluation criteria for a single seed after T operations.\n * In each operation, we place 36 seeds on a 6x6 grid. Adjacent pairs (60 pairs in total) generate \n * new seeds where each criterion is inherited from one of the two parents.\n * \n * Heuristic Approach:\n * To maximize the sum, we want to have a single pair of seeds where, for many criteria, one seed\n * has a very high value. The potential of a pair (k, k') can be estimated by the maximum possible\n * sum it could produce: V_max(k, k') = sum_{l=0}^{M-1} max(x_{k,l}, x_{k',l}).\n * We use Simulated Annealing (SA) to find a placement of seeds on the grid that maximizes \n * a function related to these potential values.\n * \n * The objective function for SA is: max_{p in Pairs} V_max(p) + 0.01 * sum_{p in Pairs} V_max(p).\n * This encourages both a single very good pair and many moderately good pairs.\n */\n\n// Fixed problem parameters based on constraints\nconst int MAX_N = 6;\nconst int MAX_M = 15;\nconst int MAX_SEEDS = 60;\nconst int MAX_PAIRS = 60;\n\nint N, M, T;\nint seed_count;\nint grid_size;\n\nstruct Seed {\n    int x[MAX_M];\n    int v;\n};\n\nSeed seeds[MAX_SEEDS];\nint grid[MAX_N][MAX_N];\nint pos[MAX_SEEDS]; // Position of seed k in the grid (0-35) or -1\n\nstruct Pair {\n    int r1, c1, r2, c2;\n};\nPair adj_pairs[MAX_PAIRS];\nint cell_to_pairs[MAX_N][MAX_N][8];\nint cell_to_pairs_size[MAX_N][MAX_N];\ndouble pair_scores[MAX_PAIRS];\n\n// Calculate the maximum possible value of a new seed from a pair of seeds\ndouble calculate_pair_vmax(int k1, int k2) {\n    double vmax = 0;\n    for (int l = 0; l < M; ++l) {\n        vmax += max(seeds[k1].x[l], seeds[k2].x[l]);\n    }\n    return vmax;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial input\n    if (!(cin >> N >> M >> T)) return 0;\n\n    seed_count = 2 * N * (N - 1);\n    grid_size = N * N;\n\n    for (int i = 0; i < seed_count; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> seeds[i].x[j];\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    // Precompute grid adjacency\n    int pair_idx = 0;\n    for (int i = 0; i < MAX_N; ++i) {\n        for (int j = 0; j < MAX_N; ++j) {\n            cell_to_pairs_size[i][j] = 0;\n        }\n    }\n\n    // Horizontal adjacent pairs\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            adj_pairs[pair_idx] = {i, j, i, j + 1};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i][j + 1][cell_to_pairs_size[i][j + 1]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    // Vertical adjacent pairs\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            adj_pairs[pair_idx] = {i, j, i + 1, j};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i + 1][j][cell_to_pairs_size[i + 1][j]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Reset grid for the current turn\n        for (int i = 0; i < seed_count; ++i) pos[i] = -1;\n        for (int i = 0; i < grid_size; ++i) {\n            grid[i / N][i % N] = i;\n            pos[i] = i;\n        }\n\n        // Initial score setup\n        for (int i = 0; i < pair_idx; ++i) {\n            pair_scores[i] = calculate_pair_vmax(grid[adj_pairs[i].r1][adj_pairs[i].c1], grid[adj_pairs[i].r2][adj_pairs[i].c2]);\n        }\n\n        auto get_current_score = [&]() {\n            double max_v = 0;\n            double sum_v = 0;\n            for (int i = 0; i < pair_idx; ++i) {\n                if (pair_scores[i] > max_v) max_v = pair_scores[i];\n                sum_v += pair_scores[i];\n            }\n            return max_v + 0.01 * sum_v;\n        };\n\n        double current_score = get_current_score();\n        auto start_time = chrono::steady_clock::now();\n\n        int iter = 0;\n        // Simulated Annealing core loop\n        while (true) {\n            // Periodically check for the time limit (each turn gets ~0.15 seconds)\n            if ((iter & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start_time).count() > 0.16) break;\n            }\n            iter++;\n\n            int r = uniform_int_distribution<int>(0, N - 1)(rng);\n            int c = uniform_int_distribution<int>(0, N - 1)(rng);\n            int s = uniform_int_distribution<int>(0, seed_count - 1)(rng);\n\n            int r2 = -1, c2 = -1;\n            if (pos[s] != -1) {\n                r2 = pos[s] / N;\n                c2 = pos[s] % N;\n            }\n\n            if (r == r2 && c == c2) continue;\n\n            int old_seed_rc = grid[r][c];\n            int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n\n            int changed_pairs[10];\n            double old_pair_scores[10];\n            int cp_cnt = 0;\n\n            // Lambda to record affected pairs and their scores for undoing moves\n            auto record_affected_pairs = [&](int row, int col) {\n                for (int i = 0; i < cell_to_pairs_size[row][col]; ++i) {\n                    int p_idx = cell_to_pairs[row][col][i];\n                    bool already_recorded = false;\n                    for (int k = 0; k < cp_cnt; ++k) {\n                        if (changed_pairs[k] == p_idx) {\n                            already_recorded = true;\n                            break;\n                        }\n                    }\n                    if (!already_recorded) {\n                        changed_pairs[cp_cnt] = p_idx;\n                        old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                        cp_cnt++;\n                    }\n                }\n            };\n\n            record_affected_pairs(r, c);\n            if (r2 != -1) record_affected_pairs(r2, c2);\n\n            // Apply the potential move (either swap or replace)\n            if (r2 != -1) {\n                // Swap\n                grid[r][c] = s;\n                grid[r2][c2] = old_seed_rc;\n                pos[s] = r * N + c;\n                pos[old_seed_rc] = r2 * N + c2;\n            } else {\n                // Replace\n                grid[r][c] = s;\n                pos[old_seed_rc] = -1;\n                pos[s] = r * N + c;\n            }\n\n            // Recalculate pair scores for the updated grid\n            for (int i = 0; i < cp_cnt; ++i) {\n                int p_idx = changed_pairs[i];\n                pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n            }\n\n            double next_score = get_current_score();\n            \n            // Time-based temperature reduction\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double temp = 10.0 * (1.0 - elapsed / 0.16);\n            if (temp < 0.01) temp = 0.01;\n\n            // Metropolis criterion\n            if (next_score > current_score || exp((next_score - current_score) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_score = next_score;\n            } else {\n                // Revert the move\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc;\n                    grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2;\n                    pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc;\n                    pos[s] = -1;\n                    pos[old_seed_rc] = r * N + c;\n                }\n                for (int i = 0; i < cp_cnt; ++i) {\n                    pair_scores[changed_pairs[i]] = old_pair_scores[i];\n                }\n            }\n        }\n\n        // Output current placement\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // Read newly generated seeds from the judge\n        for (int i = 0; i < seed_count; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                cin >> seeds[i].x[j];\n                seeds[i].v += seeds[i].x[j];\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We need to move M takoyaki from initial positions S to target positions T.\n * We can design a robotic arm as a tree with up to V vertices.\n * A star-like tree with a single fingertip (leaf) and the root at the center is a good choice.\n * Let's use V'=2 (one root and one fingertip) with an edge length L=1.\n * The fingertip (vertex 1) can reach any cell (sx, sy) if the root (vertex 0) is placed\n * at an adjacent cell (sx+/-1, sy) or (sx, sy+/-1).\n * The movements involve moving the root (U, D, L, R) and rotating the fingertip (L, R).\n * \n * The score is based on the number of turns. Moving one takoyaki at a time\n * from its current position to its target position should be efficient.\n */\n\nstruct State {\n    int rx, ry, dir_idx;\n};\n\nint N, M, V;\nvector<string> s_grid, t_grid;\nint curr_rx, curr_ry, curr_dir_idx;\n\n// Directions for dir_idx: 0: Down (1,0), 1: Right (0,1), 2: Up (-1,0), 3: Left (0,-1)\nint dx[] = {1, 0, -1, 0};\nint dy[] = {0, 1, 0, -1};\n\nvoid move_to(int target_rx, int target_ry, int target_dir_idx, bool is_last) {\n    int dist = abs(curr_rx - target_rx) + abs(curr_ry - target_ry);\n    int rot_ccw = (target_dir_idx - curr_dir_idx + 4) % 4;\n    int rot_cw = (curr_dir_idx - target_dir_idx + 4) % 4;\n\n    int turns, rot_needed;\n    char rot_char;\n    if (max(dist, rot_ccw) <= max(dist, rot_cw)) {\n        turns = max(dist, rot_ccw);\n        rot_needed = rot_ccw;\n        rot_char = 'L';\n    } else {\n        turns = max(dist, rot_cw);\n        rot_needed = rot_cw;\n        rot_char = 'R';\n    }\n\n    // If already at the target position and direction, we still need one turn to pick/place.\n    if (turns == 0) turns = 1;\n\n    int temp_rx = curr_rx, temp_ry = curr_ry;\n    int temp_dir = curr_dir_idx;\n    int rotations_done = 0;\n\n    for (int i = 1; i <= turns; ++i) {\n        char move_char = '.';\n        if (temp_rx < target_rx) { move_char = 'D'; temp_rx++; }\n        else if (temp_rx > target_rx) { move_char = 'U'; temp_rx--; }\n        else if (temp_ry < target_ry) { move_char = 'R'; temp_ry++; }\n        else if (temp_ry > target_ry) { move_char = 'L'; temp_ry--; }\n\n        char cur_rot_char = '.';\n        if (rotations_done < rot_needed) {\n            cur_rot_char = rot_char;\n            if (rot_char == 'L') temp_dir = (temp_dir + 1) % 4;\n            else temp_dir = (temp_dir + 3) % 4;\n            rotations_done++;\n        }\n\n        char action_char = (is_last && i == turns) ? 'P' : '.';\n        // Turn format: S[0] (move), S[1] (rotation of vertex 1), S[2] (action of root), S[3] (action of leaf)\n        cout << move_char << cur_rot_char << '.' << action_char << \"\\n\";\n    }\n    curr_rx = target_rx;\n    curr_ry = target_ry;\n    curr_dir_idx = target_dir_idx;\n}\n\nState find_state(int sx, int sy, int n) {\n    for (int d = 0; d < 4; ++d) {\n        int rx = sx - dx[d];\n        int ry = sy - dy[d];\n        if (rx >= 0 && rx < n && ry >= 0 && ry < n) {\n            return {rx, ry, d};\n        }\n    }\n    return {0, 0, 0};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    s_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Design the tree: V'=2, vertex 0 is root, vertex 1 is leaf. Edge (0,1) length 1.\n    cout << 2 << \"\\n\";\n    cout << \"0 1\" << \"\\n\";\n    // Initial root position (0, 0)\n    cout << \"0 0\" << \"\\n\";\n\n    // Initial robotic arm state (root at 0,0 and all edges extend to the right: dir_idx = 1)\n    curr_rx = 0;\n    curr_ry = 0;\n    curr_dir_idx = 1;\n\n    // Identify takoyaki that need to be moved\n    vector<pair<int, int>> s_only, t_only;\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                s_only.push_back({i, j});\n            }\n            if (s_grid[i][j] == '0' && t_grid[i][j] == '1') {\n                t_only.push_back({i, j});\n            }\n        }\n    }\n\n    // Each takoyaki in s_only must be moved to a position in t_only\n    for (size_t i = 0; i < s_only.size(); ++i) {\n        // 1. Pick up from current s_only[i]\n        State pick_state = find_state(s_only[i].first, s_only[i].second, N);\n        move_to(pick_state.rx, pick_state.ry, pick_state.dir_idx, true);\n\n        // 2. Drop at target t_only[i]\n        State drop_state = find_state(t_only[i].first, t_only[i].second, N);\n        move_to(drop_state.rx, drop_state.ry, drop_state.dir_idx, true);\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We are given N mackerels (weight +1) and N sardines (weight -1).\n * We need to find an axis-parallel polygon that maximizes the sum of weights of fish inside it.\n * The polygon must have at most 1000 vertices, edge length at most 4*10^5, \n * and coordinates between 0 and 10^5. It must not self-intersect.\n * \n * The maximum weight rectangle problem can be solved in O(N^2) by iterating \n * through all pairs of y-coordinates and using Kadane's algorithm on x-coordinates.\n * With N = 5000, O(N^2) is approximately 2.5 * 10^7, which fits within the 2-second limit.\n * Specifically, if we collect unique x and y coordinates, the complexity becomes O(L^2 + LN),\n * where L is the number of unique y-coordinates and N is the total number of fish.\n */\n\nstruct Fish {\n    int x, y, weight;\n};\n\nint main() {\n    // Speed up I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Fish> all_fish;\n    vector<int> all_x, all_y;\n\n    // Read mackerels\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    // Read sardines\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Pre-process unique coordinates for compression\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n\n    int K = all_x.size();\n    int L = all_y.size();\n\n    // Group fish by their unique y-coordinate index\n    vector<vector<pair<int, int>>> fish_at_y(L);\n    for (const auto& f : all_fish) {\n        int xi = lower_bound(all_x.begin(), all_x.end(), f.x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), f.y) - all_y.begin();\n        fish_at_y[yi].push_back({xi, f.weight});\n    }\n\n    // Initialize with a single mackerel to ensure a minimum score of 2 (a-b+1 = 1-0+1 = 2)\n    // (assuming mackerels are the first N fish)\n    int best_sum = 0;\n    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n\n    // A single mackerel at index i (0 <= i < N) provides sum 1\n    for (int i = 0; i < N; ++i) {\n        // Since all_fish[0...N-1] are mackerels\n        int xi = lower_bound(all_x.begin(), all_x.end(), all_fish[i].x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), all_fish[i].y) - all_y.begin();\n        if (1 > best_sum) {\n            best_sum = 1;\n            bx1 = xi; bx2 = xi;\n            by1 = yi; by2 = yi;\n        }\n    }\n\n    // O(L^2 + LN) algorithm to find the maximum weight rectangle\n    vector<int> f(K, 0);\n    for (int i = 0; i < L; ++i) {\n        // Reset x-coordinate weights for the new starting y-coordinate\n        fill(f.begin(), f.end(), 0);\n        for (int j = i; j < L; ++j) {\n            // Add fish at current y-coordinate j to the weights\n            for (auto& p : fish_at_y[j]) {\n                f[p.first] += p.second;\n            }\n            \n            // Find maximum subarray sum of weights in f using Kadane's\n            int cur_sum = 0;\n            int start = 0;\n            for (int k = 0; k < K; ++k) {\n                cur_sum += f[k];\n                if (cur_sum > best_sum) {\n                    best_sum = cur_sum;\n                    bx1 = start; bx2 = k;\n                    by1 = i; by2 = j;\n                }\n                if (cur_sum < 0) {\n                    cur_sum = 0;\n                    start = k + 1;\n                }\n            }\n        }\n    }\n\n    // Convert the discrete indices back to actual coordinates\n    int x1 = all_x[bx1], x2 = all_x[bx2];\n    int y1 = all_y[by1], y2 = all_y[by2];\n\n    // Ensure we form a valid non-zero area polygon\n    if (x1 == x2) {\n        if (x1 < 100000) x2 = x1 + 1;\n        else { x1 = x1 - 1; x2 = x1 + 1; }\n    }\n    if (y1 == y2) {\n        if (y1 < 100000) y2 = y1 + 1;\n        else { y1 = y1 - 1; y2 = y1 + 1; }\n    }\n\n    // Output the 4 vertices of the rectangle\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << endl;\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Rectangular packing in a single cardboard box.\n * Goal: Minimize W + H + Sum(unused rectangles' dimensions).\n * Method: Randomized Greedy approach with time-limited iterations.\n * \n * Rules:\n * - Rectangles must be placed in increasing order of indices.\n * - Each can be rotated 90 degrees.\n * - Directions: U (upward, move towards y=0) or L (leftward, move towards x=0).\n * - U with reference b: x_left_new = x_right_b (or 0).\n * - L with reference b: y_top_new = y_bottom_b (or 0).\n * - Movement stops when it hits an edge of a previously placed rectangle or axis.\n */\n\nstruct Rect {\n    int id;\n    long long w, h;\n    long long x, y;\n    long long x_right, y_bottom;\n};\n\nstruct Placement {\n    int p, r, d, b; \n};\n\nstruct State {\n    vector<Rect> placed;\n    vector<Placement> placements;\n    long long W, H;\n    long long score;\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<pair<long long, long long>> measured_wh(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> measured_wh[i].first >> measured_wh[i].second;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Time management to avoid TLE in system tests\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 2.7) break;\n\n        State best_state;\n        best_state.score = 4e18; \n\n        // Perform randomized greedy iterations in batches\n        for (int batch = 0; batch < 100; ++batch) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) break;\n\n            for (int iter = 0; iter < 5; ++iter) {\n                State current_state;\n                current_state.W = 0;\n                current_state.H = 0;\n                long long unused_sum = 0;\n                for (int i = 0; i < N; ++i) unused_sum += (measured_wh[i].first + measured_wh[i].second);\n\n                for (int i = 0; i < N; ++i) {\n                    long long wi = measured_wh[i].first;\n                    long long hi = measured_wh[i].second;\n\n                    struct Option {\n                        int r, d, b;\n                        long long new_W, new_H;\n                    };\n                    static Option options[405];\n                    int opt_count = 0;\n                    long long best_new_W_H = 4e18;\n\n                    for (int r : {0, 1}) {\n                        long long w = (r == 0 ? wi : hi);\n                        long long h = (r == 0 ? hi : wi);\n                        \n                        for (int d : {0, 1}) { // 0 for U, 1 for L\n                            // Try Case 1: Reference rectangle b = -1\n                            long long x_l, x_r, y_t, y_b;\n                            if (d == 0) { // U\n                                x_l = 0; x_r = w; y_t = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                }\n                                y_b = y_t + h;\n                            } else { // L\n                                y_t = 0; y_b = h; x_l = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                }\n                                x_r = x_l + w;\n                            }\n                            long long nw = max(current_state.W, x_r);\n                            long long nh = max(current_state.H, y_b);\n                            if (nw + nh < best_new_W_H) {\n                                best_new_W_H = nw + nh;\n                                opt_count = 0;\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            } else if (nw + nh == best_new_W_H) {\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            }\n\n                            // Try Case 2: Reference rectangle b is a previously placed rectangle\n                            for (const auto& prev : current_state.placed) {\n                                int b_id = prev.id;\n                                if (d == 0) { // U\n                                    x_l = prev.x_right; x_r = x_l + w; y_t = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                    }\n                                    y_b = y_t + h;\n                                } else { // L\n                                    y_t = prev.y_bottom; y_b = y_t + h; x_l = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                    }\n                                    x_r = x_l + w;\n                                }\n                                nw = max(current_state.W, x_r);\n                                nh = max(current_state.H, y_b);\n                                if (nw + nh < best_new_W_H) {\n                                    best_new_W_H = nw + nh;\n                                    opt_count = 0;\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                } else if (nw + nh == best_new_W_H) {\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                }\n                            }\n                        }\n                    }\n\n                    // Greedy decision: Include rectangle i if the score improvement is worth it.\n                    long long delta = best_new_W_H - (current_state.W + current_state.H);\n                    if (delta < wi + hi && opt_count > 0) {\n                        uniform_int_distribution<int> dist(0, opt_count - 1);\n                        Option opt = options[dist(rng)];\n                        long long w = (opt.r == 0 ? wi : hi);\n                        long long h = (opt.r == 0 ? hi : wi);\n                        Rect nr; nr.id = i; nr.w = w; nr.h = h;\n                        if (opt.d == 0) { // Direction U\n                            if (opt.b == -1) nr.x = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.x = p.x_right; break; }\n                            }\n                            nr.x_right = nr.x + w;\n                            long long yt = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.x_right <= p.x || nr.x >= p.x_right)) yt = max(yt, p.y_bottom);\n                            nr.y = yt; nr.y_bottom = yt + h;\n                        } else { // Direction L\n                            if (opt.b == -1) nr.y = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.y = p.y_bottom; break; }\n                            }\n                            nr.y_bottom = nr.y + h;\n                            long long xl = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.y_bottom <= p.y || nr.y >= p.y_bottom)) xl = max(xl, p.x_right);\n                            nr.x = xl; nr.x_right = xl + w;\n                        }\n                        current_state.placed.push_back(nr);\n                        current_state.placements.push_back({i, opt.r, opt.d, opt.b});\n                        current_state.W = max(current_state.W, nr.x_right);\n                        current_state.H = max(current_state.H, nr.y_bottom);\n                        unused_sum -= (wi + hi);\n                    }\n                }\n                current_state.score = current_state.W + current_state.H + unused_sum;\n                if (current_state.score < best_state.score) best_state = current_state;\n            }\n        }\n\n        // Output the best arrangement found for the current turn.\n        cout << best_state.placed.size() << \"\\n\";\n        for (const auto& pl : best_state.placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << (pl.d == 0 ? \"U\" : \"L\") << \" \" << pl.b << \"\\n\";\n        }\n        cout.flush();\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n    }\n\n    return 0;\n}\n","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Partition a planar graph into rooted trees to maximize sum (h_v + 1) * A_v,\n * subject to height constraint h_v <= H.\n * \n * Strategy:\n * 1. Initial Solution: Greedy approach. Sort nodes by beauty ascending.\n *    For each node, attach it to a neighbor that is already in a tree and has the maximum depth < H.\n *    This puts high-beauty nodes at deeper levels of the trees.\n * 2. Optimization: Simulated Annealing (SA).\n *    Moves: Change the parent of a node v to a neighbor u (or -1 for root).\n *    Checking validity: \n *      - Ensure no cycles (u is not in v's subtree).\n *      - Ensure height constraint is maintained (new_depth_v + max_rel_depth_v <= H).\n *    Efficiency:\n *      - Depth and ancestor check in O(H).\n *      - Maintain subtree_sum_A and max_rel_depth for each node.\n *      - Updating these values takes O(H * degree) by walking up the ancestors.\n *    This allows for many SA iterations within the 2-second time limit.\n */\n\nconst int MAXN = 1005;\nint N, M, H;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_rel_depth[MAXN];\nbool visited[MAXN];\n\nint get_depth(int v) {\n    int d = 0;\n    while (v != -1 && parent[v] != -1) {\n        v = parent[v];\n        d++;\n    }\n    return d;\n}\n\nbool is_ancestor(int v, int u) { // is v an ancestor of u?\n    int curr = u;\n    for (int i = 0; i <= H + 1; ++i) {\n        if (curr == v) return true;\n        if (curr == -1) break;\n        curr = parent[curr];\n    }\n    return false;\n}\n\nvoid update_ancestors(int v) {\n    int curr = v;\n    while (curr != -1) {\n        // Update subtree_sum_A[curr]\n        long long new_sum = A[curr];\n        for (int c : children[curr]) {\n            new_sum += subtree_sum_A[c];\n        }\n        subtree_sum_A[curr] = new_sum;\n\n        // Update max_rel_depth[curr]\n        int new_md = 0;\n        for (int c : children[curr]) {\n            new_md = max(new_md, max_rel_depth[c] + 1);\n        }\n        max_rel_depth[curr] = new_md;\n\n        curr = parent[curr];\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> H)) return 0;\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Initial state: all nodes are roots\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_rel_depth[i] = 0;\n        visited[i] = false;\n    }\n\n    // Greedy initial construction\n    vector<int> order(N);\n    for (int i = 0; i < N; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return A[a] < A[b];\n    });\n\n    for (int v : order) {\n        int best_u = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (visited[u]) {\n                int d = get_depth(u);\n                if (d < H && d > max_d) {\n                    max_d = d;\n                    best_u = u;\n                }\n            }\n        }\n        if (best_u != -1) {\n            parent[v] = best_u;\n            children[best_u].push_back(v);\n            visited[v] = true;\n            // v's depth is already 0 relative to its parent, but we calculate depth(v) as depth(u)+1\n            // We need to update v's subtree info and its ancestors.\n            // To start, v is a leaf, so max_rel_depth[v] = 0 and subtree_sum_A[v] = A[v].\n            max_rel_depth[v] = 0;\n            subtree_sum_A[v] = A[v];\n            update_ancestors(v);\n        } else {\n            parent[v] = -1;\n            visited[v] = true;\n            max_rel_depth[v] = 0;\n            subtree_sum_A[v] = A[v];\n        }\n    }\n\n    // Simulated Annealing\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 rng(42);\n    \n    double T_start = 100.0;\n    double T_end = 0.01;\n    int iterations = 800000;\n\n    for (int iter = 0; iter < iterations; ++iter) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n\n        double T = T_start * pow(T_end / T_start, (double)iter / iterations);\n\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int u_idx = uniform_int_distribution<int>(-1, (int)adj[v].size() - 1)(rng);\n        int u = (u_idx == -1) ? -1 : adj[v][u_idx];\n\n        if (u == parent[v]) continue;\n        if (u != -1 && is_ancestor(v, u)) continue;\n\n        int old_p = parent[v];\n        int new_p = u;\n        int old_depth_v = get_depth(v);\n        int new_depth_v = (new_p == -1) ? 0 : get_depth(new_p) + 1;\n\n        if (new_depth_v + max_rel_depth[v] > H) continue;\n\n        long long delta = (long long)(new_depth_v - old_depth_v) * subtree_sum_A[v];\n\n        if (delta > 0 || uniform_real_distribution<double>(0, 1)(rng) < exp((double)delta / T)) {\n            // Accept the move\n            if (old_p != -1) {\n                children[old_p].erase(remove(children[old_p].begin(), children[old_p].end(), v), children[old_p].end());\n                update_ancestors(old_p);\n            }\n            parent[v] = new_p;\n            if (new_p != -1) {\n                children[new_p].push_back(v);\n            }\n            update_ancestors(v);\n        }\n    }\n\n    // Output results\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i] << (i == N - 1 ? \"\" : \" \");\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\n/**\n * Problem: Oni wa Soto, Fuku wa Uchi\n * Objective: Remove all Oni ('x') from an NxN board without removing any Fukunokami ('o').\n * Strategy:\n * 1. Identify all Oni positions.\n * 2. Identify all possible \"efficient\" moves:\n *    - For each row/column, if a contiguous sequence of squares from an edge does not contain 'o', \n *      we can remove all 'x' in that sequence using a single group of shifts and a restoration sequence.\n *    - For example, shifting row i Left k times and then Right k times removes all 'x' in (i, 0) to (i, k-1)\n *      and restores the remaining pieces to their original positions.\n * 3. Use a Greedy Set Cover heuristic to select the minimum-cost set of moves that covers all 'x'.\n * 4. Output the sequence of moves.\n */\n\nstruct Oni {\n    int r, c;\n};\n\nstruct Move {\n    char d;\n    int p;\n    int k;\n    vector<int> covered_indices; // Indices in the initial Oni list\n    int cost;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> board(N);\n    vector<Oni> oni_list;\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_list.push_back({i, j});\n            }\n        }\n    }\n\n    vector<Move> all_possible_moves;\n\n    // Generate possible moves for each column (Up and Down)\n    for (int j = 0; j < N; ++j) {\n        // Up moves\n        int max_up = 0;\n        while (max_up < N && board[max_up][j] != 'o') {\n            max_up++;\n        }\n        for (int k = 1; k <= max_up; ++k) {\n            Move m;\n            m.d = 'U'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Down moves\n        int max_down = 0;\n        while (max_down < N && board[N - 1 - max_down][j] != 'o') {\n            max_down++;\n        }\n        for (int k = 1; k <= max_down; ++k) {\n            Move m;\n            m.d = 'D'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Generate possible moves for each row (Left and Right)\n    for (int i = 0; i < N; ++i) {\n        // Left moves\n        int max_left = 0;\n        while (max_left < N && board[i][max_left] != 'o') {\n            max_left++;\n        }\n        for (int k = 1; k <= max_left; ++k) {\n            Move m;\n            m.d = 'L'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Right moves\n        int max_right = 0;\n        while (max_right < N && board[i][N - 1 - max_right] != 'o') {\n            max_right++;\n        }\n        for (int k = 1; k <= max_right; ++k) {\n            Move m;\n            m.d = 'R'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Greedy Set Cover\n    vector<bool> uncovered(oni_list.size(), true);\n    int remaining_oni = oni_list.size();\n    vector<Move> chosen_moves;\n\n    while (remaining_oni > 0) {\n        int best_m_idx = -1;\n        double best_ratio = -1.0;\n\n        for (int i = 0; i < (int)all_possible_moves.size(); ++i) {\n            int count = 0;\n            for (int idx : all_possible_moves[i].covered_indices) {\n                if (uncovered[idx]) count++;\n            }\n            if (count > 0) {\n                double ratio = (double)count / all_possible_moves[i].cost;\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_m_idx = i;\n                }\n            }\n        }\n\n        if (best_m_idx == -1) break; // Should not happen given problem guarantees\n\n        chosen_moves.push_back(all_possible_moves[best_m_idx]);\n        for (int idx : all_possible_moves[best_m_idx].covered_indices) {\n            if (uncovered[idx]) {\n                uncovered[idx] = false;\n                remaining_oni--;\n            }\n        }\n    }\n\n    // Output moves\n    for (const auto& m : chosen_moves) {\n        char d1 = m.d, d2 = (m.d == 'U' ? 'D' : (m.d == 'D' ? 'U' : (m.d == 'L' ? 'R' : 'L')));\n        for (int step = 0; step < m.k; ++step) cout << d1 << \" \" << m.p << \"\\n\";\n        for (int step = 0; step < m.k; ++step) cout << d2 << \" \" << m.p << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Global variables for efficiency in the optimization loop\nint N;\nlong long L;\nvector<long long> T;\nvector<int> a, b;\nvector<long long> S;\nlong long current_err = 0;\n\n// Function to update the sum of T_j for the nodes a[j] and b[j]\n// We maintain the error term 'current_err' = sum |S_i - 2*T_i| in O(1)\nvoid apply_a(int j, int new_a) {\n    int old_a = a[j];\n    if (old_a == new_a) return;\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] -= T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] += T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    a[j] = new_a;\n}\n\nvoid revert_a(int j, int old_a, int new_a) {\n    if (old_a == new_a) return;\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] -= T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] += T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    a[j] = old_a;\n}\n\nvoid apply_b(int j, int new_b) {\n    int old_b = b[j];\n    if (old_b == new_b) return;\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] -= T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] += T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    b[j] = new_b;\n}\n\nvoid revert_b(int j, int old_b, int new_b) {\n    if (old_b == new_b) return;\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] -= T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] += T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    b[j] = old_b;\n}\n\nint visited[105];\nint timestamp = 0;\nint q[105];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> L)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    a.resize(N);\n    b.resize(N);\n    S.assign(N, 0);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Initial random assignment\n    for (int i = 0; i < N; ++i) {\n        a[i] = rng() % N;\n        b[i] = rng() % N;\n        S[a[i]] += T[i];\n        S[b[i]] += T[i];\n    }\n\n    current_err = 0;\n    for (int i = 0; i < N; ++i) {\n        current_err += abs(S[i] - 2 * T[i]);\n    }\n\n    // BFS-based reachability check to calculate the penalty\n    auto get_total_cost = [&]() {\n        timestamp++;\n        int head = 0, tail = 0;\n        q[tail++] = 0;\n        visited[0] = timestamp;\n        while (head < tail) {\n            int u = q[head++];\n            if (visited[a[u]] != timestamp) {\n                visited[a[u]] = timestamp;\n                q[tail++] = a[u];\n            }\n            if (visited[b[u]] != timestamp) {\n                visited[b[u]] = timestamp;\n                q[tail++] = b[u];\n            }\n        }\n        long long penalty = 0;\n        for (int i = 0; i < N; ++i) {\n            // If an employee with assigned duties is not reachable, penalize heavily\n            if (T[i] > 0 && visited[i] != timestamp) {\n                penalty += 1000000LL;\n            }\n        }\n        return current_err + penalty;\n    };\n\n    long long current_cost = get_total_cost();\n    \n    // Simulated Annealing parameters\n    int total_iters = 1000000;\n    double T_start = 1000000.0;\n    double T_end = 0.5;\n\n    for (int iter = 0; iter < total_iters; ++iter) {\n        int j = rng() % N;\n        int old_a = a[j], old_b = b[j];\n        int type = rng() % 3; // 0: change a, 1: change b, 2: change both\n        int new_a = old_a, new_b = old_b;\n        \n        if (type == 0) new_a = rng() % N;\n        else if (type == 1) new_b = rng() % N;\n        else { new_a = rng() % N; new_b = rng() % N; }\n\n        if (new_a == old_a && new_b == old_b) continue;\n\n        bool a_changed = (new_a != old_a);\n        bool b_changed = (new_b != old_b);\n\n        if (a_changed) apply_a(j, new_a);\n        if (b_changed) apply_b(j, new_b);\n\n        long long next_cost = get_total_cost();\n        double temp = T_start * pow(T_end / T_start, (double)iter / total_iters);\n\n        if (next_cost < current_cost || dist(rng) < exp((double)(current_cost - next_cost) / temp)) {\n            current_cost = next_cost;\n        } else {\n            // Revert changes if not accepted\n            if (b_changed) revert_b(j, old_b, new_b);\n            if (a_changed) revert_a(j, old_a, new_a);\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Improved Strategy:\n * 1. Estimate city coordinates using their rectangular centers.\n * 2. Sort cities using a Morton curve (Z-order) to ensure initial spatial locality.\n * 3. Partition the sorted cities into groups of fixed sizes G_i.\n * 4. Use a Randomized Local Search (swap heuristic) to improve the grouping.\n *    - In each iteration, pick two cities from different groups and swap them.\n *    - The swap is accepted if it reduces the total estimated MST cost (using Euclidean distance of centers).\n *    - This is done within a time limit (e.g., 0.6 seconds) to ensure we don't TLE.\n * 5. Once grouping is finalized, use a sliding window of size L with step S=2 to query edges.\n *    - This ensures we cover all cities and maintain connectivity through overlapping windows.\n *    - S=2 is safe for the query limit Q=400 as long as N=800.\n * 6. For each group, collect all edges from queries and use Kruskal's algorithm \n *    to pick the MST edges that connect all cities in that group.\n * 7. Output the finalized grouping and edges.\n */\n\n// Morton (Z-order) curve encoding for 2D points.\nuint64_t interleave(uint32_t x, uint32_t y) {\n    uint64_t z = 0;\n    for (int i = 0; i < 32; ++i) {\n        z |= (static_cast<uint64_t>((x >> i) & 1) << (2 * i));\n        z |= (static_cast<uint64_t>((y >> i) & 1) << (2 * i + 1));\n    }\n    return z;\n}\n\nstruct City {\n    int id;\n    uint64_t morton;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int i) {\n        if (parent[i] == i) return i;\n        return parent[i] = find(parent[i]);\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\ndouble estimated_dist(int i, int j, const vector<pair<int, int>>& centers) {\n    double dx = (double)centers[i].first - centers[j].first;\n    double dy = (double)centers[i].second - centers[j].second;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Prim's algorithm for calculating MST cost of a group of cities.\ndouble calculate_group_mst_cost(const vector<int>& group_cities, const vector<pair<int, int>>& centers) {\n    int n = group_cities.size();\n    if (n <= 1) return 0;\n    vector<double> min_dist(n, 1e18);\n    vector<bool> visited(n, false);\n    min_dist[0] = 0;\n    double total_cost = 0;\n    for (int i = 0; i < n; ++i) {\n        int u = -1;\n        for (int j = 0; j < n; ++j) {\n            if (!visited[j] && (u == -1 || min_dist[j] < min_dist[u]))\n                u = j;\n        }\n        if (u == -1 || min_dist[u] == 1e18) break; \n        visited[u] = true;\n        total_cost += min_dist[u];\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v]) {\n                double d = estimated_dist(group_cities[u], group_cities[v], centers);\n                if (d < min_dist[v]) min_dist[v] = d;\n            }\n        }\n    }\n    return total_cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<pair<int, int>> centers(N);\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        int cx = (lx + rx) / 2;\n        int cy = (ly + ry) / 2;\n        centers[i] = {cx, cy};\n        cities[i] = {i, interleave((uint32_t)cx, (uint32_t)cy)};\n    }\n\n    // Initial grouping based on Morton order.\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        return a.morton < b.morton;\n    });\n\n    vector<int> current_assignment(N);\n    vector<vector<int>> groups(M);\n    int curr_idx = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            int city_id = cities[curr_idx++].id;\n            groups[i].push_back(city_id);\n            current_assignment[city_id] = i;\n        }\n    }\n\n    // Local search to optimize grouping.\n    vector<double> group_mst_costs(M);\n    double total_cost = 0;\n    for (int i = 0; i < M; ++i) {\n        group_mst_costs[i] = calculate_group_mst_cost(groups[i], centers);\n        total_cost += group_mst_costs[i];\n    }\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 600) {\n        int u = uniform_int_distribution<int>(0, N - 1)(rng);\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int gu = current_assignment[u];\n        int gv = current_assignment[v];\n        if (gu == gv) continue;\n\n        // Swap u and v.\n        vector<int> new_group_u, new_group_v;\n        for (int city : groups[gu]) if (city != u) new_group_u.push_back(city);\n        new_group_u.push_back(v);\n\n        for (int city : groups[gv]) if (city != v) new_group_v.push_back(city);\n        new_group_v.push_back(u);\n\n        double new_cost_u = calculate_group_mst_cost(new_group_u, centers);\n        double new_cost_v = calculate_group_mst_cost(new_group_v, centers);\n\n        if (new_cost_u + new_cost_v < group_mst_costs[gu] + group_mst_costs[gv]) {\n            groups[gu] = new_group_u;\n            groups[gv] = new_group_v;\n            current_assignment[u] = gv;\n            current_assignment[v] = gu;\n            total_cost = total_cost - (group_mst_costs[gu] + group_mst_costs[gv]) + (new_cost_u + new_cost_v);\n            group_mst_costs[gu] = new_cost_u;\n            group_mst_costs[gv] = new_cost_v;\n        }\n    }\n\n    // Perform queries.\n    int S = 2;\n    vector<vector<pair<int, int>>> edges_in_group(M);\n    for (int i = 0; i < M; ++i) {\n        int g_size = groups[i].size();\n        if (g_size <= 1) continue;\n\n        vector<pair<int, int>> collected_edges;\n        if (g_size <= L) {\n            cout << \"? \" << g_size;\n            for (int k = 0; k < g_size; ++k) cout << \" \" << groups[i][k];\n            cout << endl;\n            for (int k = 0; k < g_size - 1; ++k) {\n                int u_edge, v_edge;\n                cin >> u_edge >> v_edge;\n                collected_edges.push_back({u_edge, v_edge});\n            }\n        } else {\n            // Window size L, step S. Overlap ensures connectivity.\n            for (int start = 0; start < g_size - 1; ) {\n                int end = min(start + L - 1, g_size - 1);\n                int subset_size = end - start + 1;\n                if (subset_size < 2) { // Should not happen as L >= 3, S=2.\n                    start++;\n                    continue;\n                }\n                cout << \"? \" << subset_size;\n                for (int k = start; k <= end; ++k) cout << \" \" << groups[i][k];\n                cout << endl;\n                for (int k = 0; k < subset_size - 1; ++k) {\n                    int u_edge, v_edge;\n                    cin >> u_edge >> v_edge;\n                    collected_edges.push_back({u_edge, v_edge});\n                }\n                // Step to next window.\n                start += S;\n                // But ensure that if the window was not full, we still move forward.\n                // The connectivity requirement means each new window must share at least one node.\n                // With start incrementing by S, and end being start+L-1, they overlap if S < L.\n            }\n        }\n\n        // Kruskal's to get the MST of the collected edges.\n        // Note: we sort edges by some proxy to make Kruskal's work.\n        // But wait, we don't know the actual distances. \n        // However, the queries already return MST edges which are \"good\".\n        // We just need a set of edges that connects the group.\n        DSU dsu(N);\n        // Since we can't sort by actual dist, we just use them in the order they came.\n        // Actually, any connected graph will work, but to keep it \"good\", we could sort by estimated_dist.\n        sort(collected_edges.begin(), collected_edges.end(), [&](const pair<int,int>& a, const pair<int,int>& b) {\n            return estimated_dist(a.first, a.second, centers) < estimated_dist(b.first, b.second, centers);\n        });\n\n        for (auto& edge : collected_edges) {\n            if (dsu.unite(edge.first, edge.second)) {\n                edges_in_group[i].push_back(edge);\n            }\n        }\n        // If for any reason connectivity isn't achieved, fallback.\n        for (int k = 1; k < g_size; ++k) {\n            if (dsu.unite(groups[i][0], groups[i][k])) {\n                edges_in_group[i].push_back({groups[i][0], groups[i][k]});\n            }\n        }\n    }\n\n    // Final Output.\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            cout << groups[i][j] << (j == (int)groups[i].size() - 1 ? \"\" : \" \");\n        }\n        cout << endl;\n        for (auto& edge : edges_in_group[i]) {\n            cout << edge.first << \" \" << edge.second << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size: 20x20.\n * - Number of target squares: M-1 = 39.\n * - Total turns allowed: 1600.\n * - Score formula: M + 2NM - T, where T is the number of turns.\n * - Goals: Visit all targets in order and minimize T.\n * \n * Insights from Initial Approach:\n * - The 'Move' (M) only strategy achieves a score of ~1100.\n * - A better strategy should utilize 'Slide' (S) to reduce the number of turns T.\n * - 'Slide' is useful when it can cover a large distance by hitting a boundary or a block.\n * - Boundary sliding can be used to jump from (r, c) to (0, c) or (N-1, c) in one turn.\n * \n * Refined Strategy:\n * - Use Dijkstra's algorithm to find the shortest path between consecutive target squares.\n * - The state for Dijkstra will be the current (row, col) position.\n * - Transitions include:\n *   1. Move (M) in 4 cardinal directions (cost 1, only if the cell is in bounds and not a block).\n *   2. Slide (S) in 4 cardinal directions (cost 1, stops at the first block or boundary encountered).\n * - This approach naturally optimizes both 'Move' and 'Slide' actions, including boundary jumps.\n * - Since the grid is small (20x20), Dijkstra is computationally efficient.\n */\n\nconst int INF = 1e9;\n\n// State for Dijkstra\nstruct State {\n    int d, r, c;\n    bool operator>(const State& other) const {\n        return d > other.d;\n    }\n};\n\n// Parent pointer to reconstruct the path\nstruct Parent {\n    int r, c;\n    char action;\n    int dir;\n};\n\nint N, M;\nbool G[20][20]; // Grid representing block positions\nint dr[] = {-1, 1, 0, 0}; // Directions: Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar dir_chars[] = {'U', 'D', 'L', 'R'};\n\nvoid solve() {\n    // Input N and M\n    if (!(cin >> N >> M)) return;\n    int r0, c0;\n    if (!(cin >> r0 >> c0)) return;\n    \n    // Read the sequence of target squares\n    vector<pair<int, int>> targets(M);\n    targets[0] = {r0, c0};\n    for (int i = 1; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    // Initialize grid (initially no blocks)\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            G[i][j] = false;\n\n    int curr_r = r0, curr_c = c0;\n\n    // Iterate through target squares in order\n    for (int k = 1; k < M; ++k) {\n        int tr = targets[k].first;\n        int tc = targets[k].second;\n\n        // Dijkstra algorithm to find the shortest path from curr to target\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<Parent>> parent(N, vector<Parent>(N, {-1, -1, ' ', -1}));\n\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[curr_r][curr_c] = 0;\n        pq.push({0, curr_r, curr_c});\n\n        while (!pq.empty()) {\n            State top = pq.top();\n            pq.pop();\n            int d = top.d, r = top.r, c = top.c;\n\n            if (d > dist[r][c]) continue;\n            if (r == tr && c == tc) break;\n\n            for (int i = 0; i < 4; ++i) {\n                // Action 1: Move (M)\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !G[nr][nc]) {\n                    if (dist[nr][nc] > d + 1) {\n                        dist[nr][nc] = d + 1;\n                        parent[nr][nc] = {r, c, 'M', i};\n                        pq.push({dist[nr][nc], nr, nc});\n                    }\n                }\n\n                // Action 2: Slide (S)\n                int sr = r, sc = c;\n                while (true) {\n                    int next_r = sr + dr[i], next_c = sc + dc[i];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                // A Slide is only considered if it actually results in a movement\n                if (sr != r || sc != c) {\n                    if (dist[sr][sc] > d + 1) {\n                        dist[sr][sc] = d + 1;\n                        parent[sr][sc] = {r, c, 'S', i};\n                        pq.push({dist[sr][sc], sr, sc});\n                    }\n                }\n            }\n        }\n\n        // Reconstruct the sequence of actions taken to reach target (tr, tc)\n        vector<pair<char, int>> path;\n        if (dist[tr][tc] == INF) {\n            // Safety fallback: manual Manhattan movement if Dijkstra fails\n            int temp_r = curr_r, temp_c = curr_c;\n            while (temp_r != tr) {\n                int d_dir = (tr > temp_r) ? 1 : 0;\n                path.push_back({'M', d_dir});\n                temp_r += dr[d_dir];\n            }\n            while (temp_c != tc) {\n                int d_dir = (tc > temp_c) ? 3 : 2;\n                path.push_back({'M', d_dir});\n                temp_c += dc[d_dir];\n            }\n        } else {\n            int pr = tr, pc = tc;\n            while (pr != curr_r || pc != curr_c) {\n                Parent p = parent[pr][pc];\n                path.push_back({p.action, p.dir});\n                pr = p.r; pc = p.c;\n            }\n            reverse(path.begin(), path.end());\n        }\n\n        // Output the actions and update current position\n        for (auto& step : path) {\n            cout << step.first << \" \" << dir_chars[step.second] << \"\\n\";\n            if (step.first == 'M') {\n                curr_r += dr[step.second];\n                curr_c += dc[step.second];\n            } else if (step.first == 'S') {\n                int sr = curr_r, sc = curr_c;\n                while (true) {\n                    int next_r = sr + dr[step.second], next_c = sc + dc[step.second];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                curr_r = sr; curr_c = sc;\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    solve();\n    return 0;\n}\n"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    int x, y, r, id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const {\n        return (ll)(x2 - x1) * (y2 - y1);\n    }\n};\n\nstruct RectTask {\n    Rect R;\n    vector<Point> P;\n    ll sum_r;\n    ll error;\n\n    // Max-priority queue to pick the rectangle with the largest error\n    bool operator<(const RectTask& other) const {\n        return error < other.error;\n    }\n};\n\nstruct SplitResult {\n    bool vertical;\n    int k;\n    int j; \n    double score;\n    ll sum_r_L;\n};\n\nint N;\nPoint points_orig[205];\nRect ans[205];\n\nvoid solve() {\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 gen(42);\n\n    double best_total_sat = -1.0;\n    Rect best_ans_res[205];\n\n    // Main loop: perform multiple randomized greedy constructions\n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 4500) break;\n\n        priority_queue<RectTask> pq;\n        ll total_r = 0;\n        vector<Point> P_init;\n        for (int i = 0; i < N; ++i) {\n            total_r += points_orig[i].r;\n            P_init.push_back(points_orig[i]);\n        }\n\n        // Initial task: the entire 10000x10000 area\n        pq.push({ {0, 0, 10000, 10000}, P_init, total_r, abs(100000000LL - total_r) });\n\n        Rect current_ans[205];\n\n        while (!pq.empty()) {\n            RectTask curr = pq.top();\n            pq.pop();\n\n            if (curr.P.size() == 1) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            int n = curr.P.size();\n            ll area_R = curr.R.area();\n            ll sum_r_P = curr.sum_r;\n            vector<SplitResult> possible_splits;\n\n            // Vertical splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.x < b.x;\n            });\n            ll sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].x < curr.P[j].x) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int H = curr.R.y2 - curr.R.y1;\n                    int target_k = curr.R.x1 + (int)round((double)target_area_L / H);\n                    int k = max(curr.P[j - 1].x + 1, min(curr.P[j].x, target_k));\n                    \n                    ll area_L = (ll)(k - curr.R.x1) * H;\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ true, k, j, score, sum_r_L });\n                }\n            }\n\n            // Horizontal splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.y < b.y;\n            });\n            sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].y < curr.P[j].y) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int W = curr.R.x2 - curr.R.x1;\n                    int target_k = curr.R.y1 + (int)round((double)target_area_L / W);\n                    int k = max(curr.P[j - 1].y + 1, min(curr.P[j].y, target_k));\n\n                    ll area_L = (ll)W * (k - curr.R.y1);\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ false, k, j, score, sum_r_L });\n                }\n            }\n\n            if (possible_splits.empty()) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            // Randomized selection from the best splits\n            sort(possible_splits.begin(), possible_splits.end(), [](const SplitResult& a, const SplitResult& b) {\n                return a.score < b.score;\n            });\n\n            int top_count = min((int)possible_splits.size(), 3);\n            uniform_int_distribution<int> dist(0, top_count - 1);\n            SplitResult best = possible_splits[dist(gen)];\n\n            // Re-sort points to correctly divide them\n            if (best.vertical) {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.x < b.x;\n                });\n            } else {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.y < b.y;\n                });\n            }\n\n            vector<Point> P_L, P_R;\n            for (int i = 0; i < best.j; ++i) P_L.push_back(curr.P[i]);\n            for (int i = best.j; i < n; ++i) P_R.push_back(curr.P[i]);\n\n            Rect R_L, R_R;\n            if (best.vertical) {\n                R_L = { curr.R.x1, curr.R.y1, best.k, curr.R.y2 };\n                R_R = { best.k, curr.R.y1, curr.R.x2, curr.R.y2 };\n            } else {\n                R_L = { curr.R.x1, curr.R.y1, curr.R.x2, best.k };\n                R_R = { curr.R.x1, best.k, curr.R.x2, curr.R.y2 };\n            }\n\n            ll sum_r_R = sum_r_P - best.sum_r_L;\n            pq.push({ R_L, P_L, best.sum_r_L, abs(R_L.area() - best.sum_r_L) });\n            pq.push({ R_R, P_R, sum_r_R, abs(R_R.area() - sum_r_R) });\n        }\n\n        // Evaluate the total satisfaction level\n        double current_sat = 0;\n        for (int i = 0; i < N; ++i) {\n            int xi = points_orig[i].x, yi = points_orig[i].y, ri = points_orig[i].r;\n            Rect r = current_ans[i];\n            if (xi >= r.x1 && xi < r.x2 && yi >= r.y1 && yi < r.y2) {\n                ll si = r.area();\n                double x = (double)min((ll)ri, si) / max((ll)ri, si);\n                current_sat += 1.0 - (1.0 - x) * (1.0 - x);\n            }\n        }\n\n        if (current_sat > best_total_sat) {\n            best_total_sat = current_sat;\n            for (int i = 0; i < N; ++i) best_ans_res[i] = current_ans[i];\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_res[i].x1 << \" \" << best_ans_res[i].y1 << \" \"\n             << best_ans_res[i].x2 << \" \" << best_ans_res[i].y2 << \"\\n\";\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> points_orig[i].x >> points_orig[i].y >> points_orig[i].r;\n        points_orig[i].id = i;\n    }\n    solve();\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a path in a 50x50 grid that maximizes the sum of values of visited squares.\n * The key constraint is that each tile (1x1, 1x2, or 2x1) can be stepped on at most once.\n * This implies that once we enter a square belonging to a certain tile, we cannot enter\n * any other square belonging to the same tile later in the path.\n *\n * Algorithm Choice:\n * This is a variation of the Longest Path problem, which is NP-hard. A robust way to \n * approach this in a competitive programming context is using a Randomized Beam Search.\n * \n * Improved Strategy:\n * 1. Multi-start Beam Search: Instead of a single search, we run multiple iterations of \n *    Beam Search with different parameters to explore diverse parts of the solution space.\n * 2. Intelligent Heuristic: For each potential next state, we calculate a heuristic \n *    that considers:\n *    - The current path score.\n *    - The estimated future potential (approximated by the number of unvisited tiles).\n *    - Connectivity (the number of unvisited adjacent tiles to the current square).\n * 3. Parameter Randomization: In each run, we randomly vary the beam width and the \n *    weights assigned to the score, remaining tiles, and connectivity.\n * 4. Efficient State Management: We use bitsets (represented by uint64_t arrays) to \n *    track visited tiles and pre-allocate memory for state management to maximize speed.\n */\n\n// Constants for the 50x50 grid\nconst int N = 50;\nconst int MAX_TILES = 2505;\nconst int NUM_U64 = (MAX_TILES + 63) / 64;\n\nint si, sj;\nint T[N][N];\nint P[N][N];\n\n// State structure for Beam Search\nstruct State {\n    int r, c;\n    int score;\n    uint64_t visited_tiles[NUM_U64];\n    int prev_idx;\n    char move;\n    float heuristic;\n    int visited_count;\n};\n\n// Movement vectors\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\n// Global best result found across all runs\nstring global_best_path = \"\";\nint global_best_score = -1;\n\n/**\n * solve_beam performs a single Beam Search iteration.\n * @param weight_tiles Weight for the estimated remaining score potential.\n * @param weight_neighbors Weight for the connectivity of the current square.\n * @param beam_width Number of paths to maintain in the beam at each step.\n * @param all_states Memory pool for all states visited in this iteration.\n */\nvoid solve_beam(int weight_tiles, int weight_neighbors, int beam_width, vector<State>& all_states) {\n    all_states.clear();\n    \n    // Initialize the starting state\n    State start;\n    start.r = si;\n    start.c = sj;\n    start.score = P[si][sj];\n    memset(start.visited_tiles, 0, sizeof(start.visited_tiles));\n    int start_tile = T[si][sj];\n    start.visited_tiles[start_tile / 64] |= (1ULL << (start_tile % 64));\n    start.prev_idx = -1;\n    start.move = ' ';\n    start.visited_count = 1;\n    start.heuristic = 0.0f;\n    all_states.push_back(start);\n\n    // current_beam stores indices of the most promising states from the previous step\n    vector<int> current_beam;\n    current_beam.push_back(0);\n\n    int best_idx_in_this_run = 0;\n\n    // Expand the path step-by-step\n    for (int step = 0; step < 2500; ++step) {\n        if (current_beam.empty()) break;\n\n        vector<int> next_beam_candidates;\n        next_beam_candidates.reserve(current_beam.size() * 4);\n\n        for (int idx : current_beam) {\n            const State& s = all_states[idx];\n\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i];\n                int nc = s.c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int nt = T[nr][nc];\n                    // Check if the tile of the target square has not been visited\n                    if (!(s.visited_tiles[nt / 64] & (1ULL << (nt % 64)))) {\n                        State next_s;\n                        next_s.r = nr;\n                        next_s.c = nc;\n                        next_s.score = s.score + P[nr][nc];\n                        memcpy(next_s.visited_tiles, s.visited_tiles, sizeof(next_s.visited_tiles));\n                        next_s.visited_tiles[nt / 64] |= (1ULL << (nt % 64));\n                        next_s.prev_idx = idx;\n                        next_s.move = move_char[i];\n                        next_s.visited_count = s.visited_count + 1;\n\n                        // Connectivity heuristic: count unvisited neighbors of the new square\n                        int next_neighbors = 0;\n                        for (int j = 0; j < 4; ++j) {\n                            int nnr = nr + dr[j];\n                            int nnc = nc + dc[j];\n                            if (nnr >= 0 && nnr < N && nnc >= 0 && nnc < N) {\n                                int nnt = T[nnr][nnc];\n                                if (!(next_s.visited_tiles[nnt / 64] & (1ULL << (nnt % 64)))) {\n                                    next_neighbors++;\n                                }\n                            }\n                        }\n\n                        // Heuristic = Current Score + Weight_Tiles * Remaining Potential + Weight_Neighbors * Connectivity\n                        next_s.heuristic = (float)next_s.score + \n                                           (float)weight_tiles * (MAX_TILES - next_s.visited_count) + \n                                           (float)weight_neighbors * next_neighbors;\n\n                        next_beam_candidates.push_back(all_states.size());\n                        all_states.push_back(next_s);\n\n                        if (all_states.back().score > all_states[best_idx_in_this_run].score) {\n                            best_idx_in_this_run = (int)all_states.size() - 1;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (next_beam_candidates.empty()) break;\n\n        // Sort candidates by heuristic for the next step of the beam search\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [&](int a, int b) {\n            return all_states[a].heuristic > all_states[b].heuristic;\n        });\n\n        // Update the beam with the top B candidates\n        current_beam.clear();\n        int num_to_keep = min((int)next_beam_candidates.size(), beam_width);\n        for (int i = 0; i < num_to_keep; ++i) {\n            current_beam.push_back(next_beam_candidates[i]);\n        }\n    }\n\n    // Update global best if this run found a superior path\n    if (all_states[best_idx_in_this_run].score > global_best_score) {\n        global_best_score = all_states[best_idx_in_this_run].score;\n        string path = \"\";\n        int curr = best_idx_in_this_run;\n        while (curr != -1 && all_states[curr].prev_idx != -1) {\n            path += all_states[curr].move;\n            curr = all_states[curr].prev_idx;\n        }\n        reverse(path.begin(), path.end());\n        global_best_path = path;\n    }\n}\n\nint main() {\n    // Optimization for standard input and output\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Parse input grid and tile data\n    if (!(cin >> si >> sj)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cin >> T[i][j];\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cin >> P[i][j];\n    }\n\n    clock_t start_time = clock();\n    mt19937 rng(42); // Seeded generator\n    \n    // Parameter distributions for randomized beam search\n    uniform_int_distribution<int> dist_w1(10, 120);\n    uniform_int_distribution<int> dist_w2(1, 40);\n    uniform_int_distribution<int> dist_bw(40, 100);\n\n    // Pre-allocate large pool for state memory management\n    vector<State> all_states;\n    all_states.reserve(500000);\n\n    // Continuously run randomized beam search as long as time permits\n    while (true) {\n        // Stop searching roughly 150ms before the 2.0s limit\n        if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n\n        int w1 = dist_w1(rng);\n        int w2 = dist_w2(rng);\n        int bw = dist_bw(rng);\n        \n        solve_beam(w1, w2, bw, all_states);\n    }\n\n    // Output the best path found\n    cout << global_best_path << endl;\n\n    return 0;\n}\n","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: Estimate unknown edge weights in a 30x30 grid graph through noisy feedback.\n * Strategy: Use Dijkstra's algorithm to find paths based on current estimates,\n * and update those estimates using a relaxed Kaczmarz method (stochastic gradient descent \n * on the error between the reported path length and our current estimated path length).\n * \n * The feedback L_k is a noisy measurement of the true path length b_k: L_k = round(b_k * e_k),\n * where e_k is uniformly random in [0.9, 1.1].\n * To deal with this noise, we use a decaying learning rate (eta).\n */\n\nconst int N = 30;\ndouble h[N][N - 1]; // horizontal edges: h[i][j] connects (i, j) and (i, j+1)\ndouble v[N - 1][N]; // vertical edges: v[i][j] connects (i, j) and (i+1, j)\n\nstruct Node {\n    int r, c;\n    double d;\n    bool operator>(const Node& other) const {\n        return d > other.d;\n    }\n};\n\nstruct Parent {\n    int r, c;\n    char dir;\n};\n\nParent parent[N][N];\ndouble dists[N][N];\n\n// Dijkstra's algorithm to find the shortest path from (sr, sc) to (tr, tc)\n// based on current edge weight estimates.\nvoid dijkstra(int sr, int sc, int tr, int tc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j] = 1e18;\n            parent[i][j] = {-1, -1, ' '};\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[sr][sc] = 0;\n    pq.push({sr, sc, 0.0});\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    while (!pq.empty()) {\n        Node top = pq.top();\n        pq.pop();\n\n        int r = top.r;\n        int c = top.c;\n        double d = top.d;\n\n        if (d > dists[r][c]) continue;\n        if (r == tr && c == tc) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = 0;\n                if (dirs[i] == 'U') weight = v[nr][c];\n                else if (dirs[i] == 'D') weight = v[r][c];\n                else if (dirs[i] == 'L') weight = h[r][nc];\n                else if (dirs[i] == 'R') weight = h[r][c];\n\n                if (dists[nr][nc] > d + weight) {\n                    dists[nr][nc] = d + weight;\n                    parent[nr][nc] = {r, c, dirs[i]};\n                    pq.push({nr, nc, dists[nr][nc]});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Increase speed of standard I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize edge weights to a reasonable middle value (average of expected range).\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Step 1: Compute path using Dijkstra's based on current estimates.\n        dijkstra(si, sj, ti, tj);\n\n        string path = \"\";\n        int cr = ti, cc = tj;\n        // Backtrack from destination to start to build the path string.\n        while (cr != si || cc != sj) {\n            Parent p = parent[cr][cc];\n            path += p.dir;\n            cr = p.r;\n            cc = p.c;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl; // endl ensures standard output is flushed.\n\n        // Step 2: Receive the reported path length (with 10% noise).\n        long long L_k;\n        if (!(cin >> L_k)) break;\n\n        // Step 3: Calculate the current path length according to our estimated weights.\n        double estimated_path_len = 0;\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                estimated_path_len += v[cr - 1][cc];\n                cr--;\n            } else if (d == 'D') {\n                estimated_path_len += v[cr][cc];\n                cr++;\n            } else if (d == 'L') {\n                estimated_path_len += h[cr][cc - 1];\n                cc--;\n            } else if (d == 'R') {\n                estimated_path_len += h[cr][cc];\n                cc++;\n            }\n        }\n\n        // Step 4: Update weights using the error diff = (reported_length - estimated_length).\n        // Using the Relaxed Kaczmarz method: w_e = w_e + (diff / |path|) * eta.\n        double diff = (double)L_k - estimated_path_len;\n        \n        // The learning rate eta decays slowly to manage the 10% noise and achieve convergence.\n        double eta = 0.5 * pow(0.9975, k);\n        double step = (diff / (double)path.size()) * eta;\n\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') {\n                v[cr - 1][cc] += step;\n                cr--;\n            } else if (d == 'D') {\n                v[cr][cc] += step;\n                cr++;\n            } else if (d == 'L') {\n                h[cr][cc - 1] += step;\n                cc--;\n            } else if (d == 'R') {\n                h[cr][cc] += step;\n                cc++;\n            }\n        }\n\n        // Step 5: Maintain edge weights within physically reasonable bounds.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) if (h[i][j] < 100.0) h[i][j] = 100.0;\n            if (i < N - 1) {\n                for (int j = 0; j < N; ++j) if (v[i][j] < 100.0) v[i][j] = 100.0;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find an N x N (N=20) matrix of characters A-H or '.' that satisfies \n * as many of M (400-800) given strings as possible. The matrix is a torus.\n * Scoring:\n * - If c < M: 10^8 * (c / M)\n * - If c = M: 10^8 * (2 * N^2 / (2 * N^2 - d)), where d is the number of '.' characters.\n * \n * Strategy:\n * 1. Use Simulated Annealing (SA) to maximize the number of satisfied strings (c).\n *    The state is an N x N matrix of characters A-H.\n *    An efficient way to update c during SA is to maintain a mismatch count for \n *    each possible occurrence of each string.\n * 2. If c = M is achieved, use a greedy approach to maximize the number of '.' characters (d).\n *    Replace characters with '.' as long as no string is lost.\n * \n * Complexity:\n * - SA: O(iterations * (number of occurrences covering a cell) * (strings per length))\n * - Pre-calculation: O(N^2 * M * L)\n */\n\nint N, M;\nstring s[800];\nchar A[20][20];\nint counts[800]; // Number of occurrences of string s[k] currently satisfied\nint c_satisfied = 0;\nvector<int> strings_by_len[13];\nvector<int> mismatch_count[2][20][20][13];\n\nstruct Occ {\n    int t, line, start, len, p, idx, k;\n};\nvector<Occ> cell_occs[20][20];\n\nstruct Change {\n    int t, line, start, len, idx, k;\n    int old_m, old_count_k;\n};\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        strings_by_len[s[i].length()].push_back(i);\n    }\n\n    // Initial random matrix of A-H\n    mt19937 rng(42);\n    string chars = \"ABCDEFGH\";\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = chars[rng() % 8];\n        }\n    }\n\n    // Pre-calculate mismatch counts for each occurrence of each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    mismatch_count[t][i][j][len].resize(strings_by_len[len].size());\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        int k = strings_by_len[len][idx];\n                        int mismatches = 0;\n                        for (int p = 0; p < len; ++p) {\n                            int ni = (t == 0) ? i : (i + p) % N;\n                            int nj = (t == 0) ? (j + p) % N : j;\n                            if (A[ni][nj] != s[k][p]) mismatches++;\n                        }\n                        mismatch_count[t][i][j][len][idx] = mismatches;\n                    }\n                }\n            }\n        }\n    }\n\n    // Calculate the number of satisfied occurrences for each string\n    for (int t = 0; t < 2; ++t) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                        if (mismatch_count[t][i][j][len][idx] == 0) {\n                            counts[strings_by_len[len][idx]]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    for (int k = 0; k < M; ++k) if (counts[k] > 0) c_satisfied++;\n\n    // Pre-calculate which occurrences cover which cell (i, j)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int t = 0; t < 2; ++t) {\n                for (int len = 2; len <= 12; ++len) {\n                    for (int p = 0; p < len; ++p) {\n                        int line = (t == 0) ? i : (i - p + N) % N;\n                        int start = (t == 0) ? (j - p + N) % N : j;\n                        for (int idx = 0; idx < (int)strings_by_len[len].size(); ++idx) {\n                            cell_occs[i][j].push_back({t, line, start, len, p, idx, strings_by_len[len][idx]});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulated Annealing phase\n    auto start_time = chrono::high_resolution_clock::now();\n    int max_iter = 250000;\n    vector<Change> changes;\n    changes.reserve(15000); \n\n    for (int iter = 0; iter < max_iter; ++iter) {\n        if ((iter & 1023) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2600) break;\n        }\n\n        int r = rng() % (N * N);\n        int i = r / N, j = r % N;\n        char old_v = A[i][j];\n        char new_v = chars[rng() % 8];\n        if (old_v == new_v) continue;\n\n        double T = 1.0 * (1.0 - (double)iter / max_iter);\n        int delta_c = 0;\n        changes.clear();\n\n        for (auto& occ : cell_occs[i][j]) {\n            int& m = mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx];\n            int old_m = m;\n            if (old_v != s[occ.k][occ.p] && new_v == s[occ.k][occ.p]) m--;\n            else if (old_v == s[occ.k][occ.p] && new_v != s[occ.k][occ.p]) m++;\n            \n            if (old_m == 0 && m > 0) {\n                if (--counts[occ.k] == 0) delta_c--;\n            } else if (old_m > 0 && m == 0) {\n                if (++counts[occ.k] == 1) delta_c++;\n            }\n            changes.push_back({occ.t, occ.line, occ.start, occ.len, occ.idx, occ.k, old_m, counts[occ.k]});\n        }\n\n        if (delta_c >= 0 || (T > 1e-9 && (double)rng() / rng.max() < exp(delta_c / T))) {\n            A[i][j] = new_v;\n            c_satisfied += delta_c;\n        } else {\n            for (int idx = (int)changes.size() - 1; idx >= 0; --idx) {\n                auto& ch = changes[idx];\n                mismatch_count[ch.t][ch.line][ch.start][ch.len][ch.idx] = ch.old_m;\n                counts[ch.k] = ch.old_count_k;\n            }\n        }\n    }\n\n    // Phase 2: Maximize density (number of '.') if all strings are satisfied\n    if (c_satisfied == M) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (A[i][j] != '.') {\n                    char old_v = A[i][j];\n                    vector<int> matching_occs_using_ij(M, 0);\n                    for (auto& occ : cell_occs[i][j]) {\n                        if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                            matching_occs_using_ij[occ.k]++;\n                        }\n                    }\n                    bool ok = true;\n                    for (int k = 0; k < M; ++k) {\n                        if (matching_occs_using_ij[k] > 0 && counts[k] == matching_occs_using_ij[k]) {\n                            ok = false; \n                            break;\n                        }\n                    }\n                    if (ok) {\n                        A[i][j] = '.';\n                        for (auto& occ : cell_occs[i][j]) {\n                            if (mismatch_count[occ.t][occ.line][occ.start][occ.len][occ.idx] == 0) {\n                                counts[occ.k]--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << A[i][j];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a shortest patrol route that visits road squares such that\n * all road squares become \"visible\" at least once.\n * A square is visible if it's in the same row/column and no obstacles are between.\n * \n * Strategy:\n * 1. Represent the map and precompute visibility (which squares can see each other).\n * 2. Use a greedy strategy to pick a subset of road squares (ToVisit) that covers\n *    the most \"uncovered\" road squares with the minimum distance.\n * 3. The greedy heuristic: Pick the \"hardest-to-cover\" square (one with fewest \n *    potential visitors) and then pick the best visitor (maximizing newly covered / distance).\n * 4. Once the set of points to visit is found, solve the Traveling Salesperson Problem (TSP)\n *    on these points using a Nearest Neighbor heuristic followed by 2-opt refinement.\n * 5. Convert the TSP tour into the actual move string (U, D, L, R).\n */\n\nconst int INF = 1e9;\n\nint N, si, sj;\nint grid[70][70];\nvector<int> C[5000], S[5000];\nbool is_road[5000];\nint dists[5000];\nint parent_node[5000];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Standard Dijkstra to find shortest path distances from a source node\nvoid dijkstra(int start, int n_size) {\n    for (int i = 0; i < n_size; ++i) dists[i] = INF;\n    dists[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n\n    while (!pq.empty()) {\n        int d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n\n        if (d > dists[u]) continue;\n\n        int r = u / N, c = u % N;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != -1) {\n                int v = nr * N + nc;\n                if (dists[u] + grid[nr][nc] < dists[v]) {\n                    dists[v] = dists[u] + grid[nr][nc];\n                    parent_node[v] = u;\n                    pq.push({dists[v], v});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> si >> sj)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            if (row[j] == '#') {\n                grid[i][j] = -1;\n                is_road[i * N + j] = false;\n            } else {\n                grid[i][j] = row[j] - '0';\n                is_road[i * N + j] = true;\n            }\n        }\n    }\n\n    // Precompute visibility\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!is_road[i * N + j]) continue;\n            int u = i * N + j;\n            C[u].push_back(u);\n            S[u].push_back(u);\n            // Horizontal\n            for (int k = j - 1; k >= 0 && grid[i][k] != -1; --k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = j + 1; k < N && grid[i][k] != -1; ++k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            // Vertical\n            for (int k = i - 1; k >= 0 && grid[k][j] != -1; --k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = i + 1; k < N && grid[k][j] != -1; ++k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n        }\n    }\n\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            sort(C[i].begin(), C[i].end());\n            C[i].erase(unique(C[i].begin(), C[i].end()), C[i].end());\n            sort(S[i].begin(), S[i].end());\n            S[i].erase(unique(S[i].begin(), S[i].end()), S[i].end());\n        }\n    }\n\n    // Set Cover Greedy\n    vector<bool> is_uncovered(N * N, false);\n    vector<int> uncovered_list;\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            is_uncovered[i] = true;\n            uncovered_list.push_back(i);\n        }\n    }\n\n    vector<int> ToVisit;\n    int curr = si * N + sj;\n    while (!uncovered_list.empty()) {\n        dijkstra(curr, N * N);\n        int best_r = -1;\n        int min_S_r = 1000000;\n        for (int r : uncovered_list) {\n            if ((int)S[r].size() < min_S_r) {\n                min_S_r = S[r].size();\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break;\n\n        int best_v = -1;\n        double best_gain = -1.0;\n        for (int v : S[best_r]) {\n            int gain = 0;\n            for (int road_idx : C[v]) {\n                if (is_uncovered[road_idx]) gain++;\n            }\n            double current_gain = (double)gain / (dists[v] + 1.0);\n            if (current_gain > best_gain) {\n                best_gain = current_gain;\n                best_v = v;\n            }\n        }\n        if (best_v == -1 || best_gain <= 0.0) break;\n\n        ToVisit.push_back(best_v);\n        for (int road_idx : C[best_v]) {\n            is_uncovered[road_idx] = false;\n        }\n        \n        vector<int> next_uncovered;\n        for (int r : uncovered_list) {\n            if (is_uncovered[r]) next_uncovered.push_back(r);\n        }\n        uncovered_list = next_uncovered;\n        curr = best_v;\n    }\n\n    // TSP Step: Nearest Neighbor + 2-opt\n    vector<int> P;\n    P.push_back(si * N + sj);\n    set<int> seen;\n    seen.insert(si * N + sj);\n    for (int v : ToVisit) {\n        if (seen.find(v) == seen.end()) {\n            P.push_back(v);\n            seen.insert(v);\n        }\n    }\n\n    int k_points = P.size();\n    vector<vector<int>> dist_matrix(k_points, vector<int>(k_points, INF));\n    for (int i = 0; i < k_points; ++i) {\n        dijkstra(P[i], N * N);\n        for (int j = 0; j < k_points; ++j) {\n            dist_matrix[i][j] = dists[P[j]];\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited_tsp(k_points, false);\n    int current_idx = 0;\n    tour.push_back(0);\n    visited_tsp[0] = true;\n    for (int step = 1; step < k_points; ++step) {\n        int next_idx = -1;\n        int min_d = INF;\n        for (int j = 0; j < k_points; ++j) {\n            if (!visited_tsp[j] && dist_matrix[current_idx][j] < min_d) {\n                min_d = dist_matrix[current_idx][j];\n                next_idx = j;\n            }\n        }\n        if (next_idx == -1) break;\n        tour.push_back(next_idx);\n        visited_tsp[next_idx] = true;\n        current_idx = next_idx;\n    }\n    tour.push_back(0);\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 1; i < sz - 2; ++i) {\n            for (int j = i + 1; j < sz - 1; ++j) {\n                if (dist_matrix[tour[i - 1]][tour[i]] + dist_matrix[tour[j]][tour[j + 1]] >\n                    dist_matrix[tour[i - 1]][tour[j]] + dist_matrix[tour[i]][tour[j + 1]]) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Final Path Reconstruction\n    string final_route = \"\";\n    for (int i = 0; i < (int)tour.size() - 1; ++i) {\n        int u = P[tour[i]];\n        int v = P[tour[i+1]];\n        if (u == v) continue;\n        dijkstra(u, N * N);\n        vector<int> path_nodes;\n        int curr_node = v;\n        while (curr_node != u) {\n            path_nodes.push_back(curr_node);\n            curr_node = parent_node[curr_node];\n        }\n        reverse(path_nodes.begin(), path_nodes.end());\n        \n        int prev_r = u / N, prev_c = u % N;\n        for (int node : path_nodes) {\n            int nr = node / N, nc = node % N;\n            if (nr == prev_r + 1) final_route += 'D';\n            else if (nr == prev_r - 1) final_route += 'U';\n            else if (nc == prev_c + 1) final_route += 'R';\n            else if (nc == prev_c - 1) final_route += 'L';\n            prev_r = nr;\n            prev_c = nc;\n        }\n    }\n    cout << final_route << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis & Improvements:\n * \n * 1. Skill Estimation:\n *    - We use Stochastic Gradient Descent (SGD) to update the skill level estimates.\n *    - The expected time E[t_{i,j}] is approx max(1, w_{i,j}), where w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k}).\n *    - If the actual time T_{i,j} differs from the estimated E[t_{i,j}], we update the skill s_{j,k}\n *      for all k where d_{i,k} > s_{j,k}.\n *    - Update rule: s_{j,k} = s_{j,k} - eta * (T_{i,j} - E[t_{i,j}]) * ( (d_{i,k} - s_{j,k}) / w_{i,j} ).\n * \n * 2. Task Prioritization (Critical Path Method):\n *    - Instead of a static rank, we use a dynamic Critical Path (CP) estimate.\n *    - CP(i) = AvgT(i) + max_{v in adj(i)} CP(v), where AvgT(i) is the average expected time for task i across all members.\n *    - This CP is recalculated every day to reflect our current understanding of the members' skills.\n * \n * 3. Greedy Scheduling Strategy:\n *    - We sort the available tasks by their dynamic CP value in descending order.\n *    - For each task in the sorted list, we assign it to the currently idle member who can complete it most quickly.\n *    - This ensures that critical tasks are prioritized and assigned to the most efficient available members.\n * \n * 4. Computational Efficiency:\n *    - Calculating CP and expected times takes O(N*M*K) per day.\n *    - Sorting and greedy matching take O(N*log N + N*M*K).\n *    - Total complexity is O(Days * N * M * K), which is roughly 2000 * 1000 * 20 * 20 = 8e8 operations.\n *    - This fits within the 3.0s time limit in C++.\n */\n\nint main() {\n    // Fast I/O for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task requirement skill levels\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    // Task dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // Topological sort to calculate CP in correct order\n    vector<int> topo_order;\n    vector<int> temp_in_degree = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (temp_in_degree[i] == 0) q.push(i);\n    }\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        topo_order.push_back(u);\n        for (int v : adj[u]) {\n            if (--temp_in_degree[v] == 0) q.push(v);\n        }\n    }\n\n    // State management\n    vector<vector<double>> s(M, vector<double>(K, 0.0)); // Skill level estimates\n    vector<int> task_status(N, 0);        // 0: not started, 1: in progress, 2: completed\n    vector<int> member_current_task(M, -1); // -1 if idle, else task index\n    vector<int> task_start_day(N, 0);     // Start day of task i\n    vector<vector<double>> E_t(N, vector<double>(M)); // Expected time for task i by member j\n    vector<double> avg_t(N);              // Average expected time for task i\n    vector<double> cp(N);                 // Critical path value for task i\n\n    int current_day = 1;\n    while (current_day <= 2000) {\n        // 1. Recalculate expected times and average task time\n        for (int i = 0; i < N; ++i) {\n            double sum_e = 0;\n            for (int j = 0; j < M; ++j) {\n                double w_ij = 0;\n                for (int k = 0; k < K; ++k) {\n                    double diff = (double)d[i][k] - s[j][k];\n                    if (diff > 0) w_ij += diff;\n                }\n                E_t[i][j] = (w_ij < 1.0 ? 1.0 : w_ij);\n                sum_e += E_t[i][j];\n            }\n            avg_t[i] = sum_e / M;\n        }\n\n        // 2. Recalculate Critical Path (CP) values using topological order\n        for (int i = N - 1; i >= 0; --i) {\n            int u = topo_order[i];\n            double max_next_cp = 0;\n            for (int v : adj[u]) {\n                if (cp[v] > max_next_cp) max_next_cp = cp[v];\n            }\n            cp[u] = avg_t[u] + max_next_cp;\n        }\n\n        // 3. Identify available tasks and idle members\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] == 0 && in_degree[i] == 0) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // 4. Greedy matching based on task priority (CP) and speed (E[t])\n        // Sort available tasks by Critical Path value descending\n        sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n            return cp[a] > cp[b];\n        });\n\n        struct Assignment {\n            int m, t;\n        };\n        vector<Assignment> current_day_assignments;\n        vector<bool> member_used_today(M, false);\n\n        for (int i : available_tasks) {\n            int best_j = -1;\n            double min_et = 1e18;\n\n            for (int j : idle_members) {\n                if (member_used_today[j]) continue;\n                if (E_t[i][j] < min_et) {\n                    min_et = E_t[i][j];\n                    best_j = j;\n                }\n            }\n\n            if (best_j != -1) {\n                current_day_assignments.push_back({best_j, i});\n                member_used_today[best_j] = true;\n                task_status[i] = 1;\n                member_current_task[best_j] = i;\n                task_start_day[i] = current_day;\n            }\n        }\n\n        // 5. Output the assignments\n        cout << current_day_assignments.size();\n        for (auto& assign : current_day_assignments) {\n            cout << \" \" << assign.m + 1 << \" \" << assign.t + 1;\n        }\n        cout << endl;\n\n        // 6. Read feedback on completed tasks\n        int num_completed;\n        if (!(cin >> num_completed)) break;\n        if (num_completed == -1) break;\n\n        // 7. Update skill estimates (SGD) and task dependencies\n        for (int idx = 0; idx < num_completed; ++idx) {\n            int f;\n            cin >> f;\n            --f; // 0-indexed member\n            int t_idx = member_current_task[f];\n            int actual_t = current_day - task_start_day[t_idx] + 1;\n\n            // Recalculate current w_ij estimate for error calculation\n            double w_ij_est = 0;\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) w_ij_est += diff;\n            }\n            if (w_ij_est < 1e-7) w_ij_est = 1e-7; // Prevent division by zero\n\n            double error = (double)actual_t - E_t[t_idx][f];\n            double eta = 0.2 / (1.0 + 0.005 * current_day); // Learning rate decay\n\n            // Refined SGD update for skill levels\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) {\n                    double contribution = diff / w_ij_est;\n                    s[f][k] -= eta * error * contribution;\n                    if (s[f][k] < 0) s[f][k] = 0;\n                }\n            }\n\n            // Mark task as completed and update dependency graph\n            task_status[t_idx] = 2;\n            member_current_task[f] = -1;\n            for (int v : adj[t_idx]) {\n                in_degree[v]--;\n            }\n        }\n        current_day++;\n    }\n\n    return 0;\n}\n","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Pickup and Delivery Problem (PDP)\n * Given 1000 orders, select 50 and find a Manhattan-distance route starting/ending at (400, 400).\n * Precedence constraint: For each selected order, pickup (a, b) must be visited before delivery (c, d).\n * \n * Strategy: Simulated Annealing (SA)\n * - Initial state: Pick 50 orders with the smallest individual round-trip distance.\n * - Moves:\n *   1. Swap: Swap two points in the current sequence.\n *   2. Reinsert: Move a point to a new position in the sequence.\n *   3. Replace: Replace one order's pickup/delivery with a new order's pickup/delivery at the same positions.\n * - Optimization:\n *   - Use fast total_dist calculation (O(N)).\n *   - Maintain posA and posC to check precedence in O(1).\n *   - Ensure all moves respect the precedence constraints.\n */\n\nstruct Order {\n    int a, b, c, d, id;\n};\n\nstruct Point {\n    int x, y, order_idx;\n    bool is_pickup;\n};\n\ninline int dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint total_dist(const vector<Point>& P) {\n    if (P.empty()) return 0;\n    int d = 0;\n    d += dist(400, 400, P[0].x, P[0].y);\n    for (size_t i = 0; i < P.size() - 1; ++i) {\n        d += dist(P[i].x, P[i].y, P[i + 1].x, P[i + 1].y);\n    }\n    d += dist(P.back().x, P.back().y, 400, 400);\n    return d;\n}\n\nint posA[1000], posC[1000];\n\nvoid update_all_pos(const vector<Point>& P) {\n    for (int i = 0; i < 1000; ++i) posA[i] = posC[i] = -1;\n    for (int i = 0; i < (int)P.size(); ++i) {\n        if (P[i].is_pickup) posA[P[i].order_idx] = i;\n        else posC[P[i].order_idx] = i;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<Order> all_orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        if (!(cin >> all_orders[i].a >> all_orders[i].b >> all_orders[i].c >> all_orders[i].d)) break;\n        all_orders[i].id = i + 1;\n    }\n\n    // Heuristic for initial subset selection\n    vector<pair<int, int>> costs;\n    for (int i = 0; i < 1000; ++i) {\n        int d = dist(400, 400, all_orders[i].a, all_orders[i].b) +\n                dist(all_orders[i].a, all_orders[i].b, all_orders[i].c, all_orders[i].d) +\n                dist(all_orders[i].c, all_orders[i].d, 400, 400);\n        costs.push_back({d, i});\n    }\n    sort(costs.begin(), costs.end());\n\n    vector<int> S, not_S;\n    vector<bool> in_S(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        S.push_back(costs[i].second);\n        in_S[costs[i].second] = true;\n    }\n    for (int i = 0; i < 1000; ++i) {\n        if (!in_S[i]) not_S.push_back(i);\n    }\n\n    // Initial sequence\n    vector<Point> P;\n    for (int idx : S) {\n        P.push_back({all_orders[idx].a, all_orders[idx].b, idx, true});\n        P.push_back({all_orders[idx].c, all_orders[idx].d, idx, false});\n    }\n    update_all_pos(P);\n\n    int current_dist = total_dist(P);\n    vector<Point> best_P = P;\n    vector<int> best_S = S;\n    int best_dist = current_dist;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 1000.0;\n    double T_end = 0.1;\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        if (iter % 2000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n            if (elapsed >= 1.0) break;\n        }\n\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n        double T = T_start * pow(T_end / T_start, elapsed);\n\n        int move_type = rng() % 100;\n        if (move_type < 40) { // Type 0: Swap two points\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            int ord_j = P[j].order_idx;\n            swap(P[i], P[j]);\n\n            // Check if swap satisfies precedence for involved orders\n            int pi = -1, ci = -1, pj = -1, cj = -1;\n            for(int k=0; k<(int)P.size(); ++k) {\n                if(P[k].order_idx == ord_i) {\n                    if(P[k].is_pickup) pi = k; else ci = k;\n                }\n                if(P[k].order_idx == ord_j) {\n                    if(P[k].is_pickup) pj = k; else cj = k;\n                }\n            }\n\n            if (pi != -1 && ci != -1 && pi < ci && pj != -1 && cj != -1 && pj < cj) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    update_all_pos(P);\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    swap(P[i], P[j]);\n                }\n            } else {\n                swap(P[i], P[j]);\n            }\n        } else if (move_type < 70) { // Type 1: Reinsert a point\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            Point p = P[i];\n            P.erase(P.begin() + i);\n            P.insert(P.begin() + j, p);\n\n            int pi = -1, ci = -1;\n            for(int k=0; k<(int)P.size(); ++k) {\n                if(P[k].order_idx == ord_i) {\n                    if(P[k].is_pickup) pi = k; else ci = k;\n                }\n            }\n            if (pi != -1 && ci != -1 && pi < ci) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    update_all_pos(P);\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    P.erase(P.begin() + j);\n                    P.insert(P.begin() + i, p);\n                }\n            } else {\n                P.erase(P.begin() + j);\n                P.insert(P.begin() + i, p);\n            }\n        } else { // Type 2: Replace order points\n            int i_idx = rng() % 50;\n            int j_idx = rng() % (int)not_S.size();\n            int old_ord = S[i_idx];\n            int new_ord = not_S[j_idx];\n\n            int pa = posA[old_ord];\n            int pc = posC[old_ord];\n            if (pa == -1 || pc == -1) continue;\n\n            vector<Point> old_P_state = P;\n            int old_S_val = S[i_idx];\n            int old_not_S_val = not_S[j_idx];\n\n            P[pa] = {all_orders[new_ord].a, all_orders[new_ord].b, new_ord, true};\n            P[pc] = {all_orders[new_ord].c, all_orders[new_ord].d, new_ord, false};\n            S[i_idx] = new_ord;\n            not_S[j_idx] = old_ord;\n\n            int new_dist = total_dist(P);\n            if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                current_dist = new_dist;\n                update_all_pos(P);\n                if (current_dist < best_dist) {\n                    best_dist = current_dist;\n                    best_P = P;\n                    best_S = S;\n                }\n            } else {\n                P = old_P_state;\n                S[i_idx] = old_S_val;\n                not_S[j_idx] = old_not_S_val;\n            }\n        }\n    }\n\n    cout << 50;\n    for (int idx : best_S) cout << \" \" << all_orders[idx].id;\n    cout << endl;\n    cout << best_P.size() + 2;\n    cout << \" 400 400\";\n    for (const auto& p : best_P) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \" 400 400\" << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem: Online Minimum Spanning Tree with uncertain future edge weights.\n * Strategy: Monte Carlo simulation to estimate the bottleneck weight of alternative paths.\n * Complexity: O(M * K * M log M), where M is the number of edges and K is the number of samples.\n * With M=2000 and K=10, total operations are approximately 4e8, fitting in 2s.\n */\n\n// Fast Disjoint Set Union (DSU) for bottleneck calculations\nstruct FastDSU {\n    int parent[405];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    int find(int i) {\n        int root = i;\n        while (parent[root] != root) root = parent[root];\n        while (parent[i] != root) {\n            int next = parent[i];\n            parent[i] = root;\n            i = next;\n        }\n        return root;\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v, d, l, id;\n};\n\nstruct SimEdge {\n    int u, v, w;\n    bool operator<(const SimEdge& other) const {\n        return w < other.w;\n    }\n};\n\n// Global buffers to avoid repeated allocations in the loop\nSimEdge sim_edges[2500];\nFastDSU dsu;\nFastDSU dsu_S;\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    const int N = 400;\n    const int M = 1995;\n    const int K = 10; // Number of Monte Carlo samples\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> coords[i].first >> coords[i].second)) break;\n    }\n\n    vector<Edge> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) break;\n        all_edges[i].u = u;\n        all_edges[i].v = v;\n        all_edges[i].id = i;\n        double dx = (double)coords[u].first - coords[v].first;\n        double dy = (double)coords[u].second - coords[v].second;\n        all_edges[i].d = (int)round(hypot(dx, dy));\n    }\n\n    vector<int> S;\n    S.reserve(N);\n    dsu_S.init(N);\n\n    // Random number generator for sampling future weights\n    mt19937 rng(42);\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n        all_edges[i].l = l_i;\n\n        int u_i = all_edges[i].u;\n        int v_i = all_edges[i].v;\n\n        // If u and v are already connected, adding this edge only adds cost.\n        if (dsu_S.find(u_i) == dsu_S.find(v_i)) {\n            cout << \"0\" << endl; // endl performs flush\n        } else {\n            int Ws[K];\n            for (int k = 0; k < K; ++k) {\n                int edge_count = 0;\n                // 1. Include edges already adopted in our MST\n                for (int idx : S) {\n                    sim_edges[edge_count++] = {all_edges[idx].u, all_edges[idx].v, all_edges[idx].l};\n                }\n                // 2. Include future edges with sampled weights\n                for (int j = i + 1; j < M; ++j) {\n                    int d_j = all_edges[j].d;\n                    // Sample weight uniformly from [d_j, 3*d_j]\n                    int weight = d_j + (rng() % (2 * d_j + 1));\n                    sim_edges[edge_count++] = {all_edges[j].u, all_edges[j].v, weight};\n                }\n\n                // 3. Sort edges to find the bottleneck weight using Kruskal's logic\n                sort(sim_edges, sim_edges + edge_count);\n\n                dsu.init(N);\n                int W_k = 2000000000; // Infinity placeholder\n                for (int e = 0; e < edge_count; ++e) {\n                    dsu.unite(sim_edges[e].u, sim_edges[e].v);\n                    if (dsu.find(u_i) == dsu.find(v_i)) {\n                        W_k = sim_edges[e].w;\n                        break;\n                    }\n                }\n                Ws[k] = W_k;\n            }\n\n            // 4. Use the median of simulated bottlenecks as the decision threshold\n            sort(Ws, Ws + K);\n            int W_median = Ws[K / 2];\n\n            if (l_i < W_median) {\n                cout << \"1\" << endl;\n                S.push_back(i);\n                dsu_S.unite(u_i, v_i);\n            } else {\n                cout << \"0\" << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * Goal: Maximize human satisfaction score.\n * Scoring: s_i = (|R_i| / 900) * 2^(-n_i), where |R_i| is the reachable area for human i \n * and n_i is the number of pets in that area.\n * Key Strategy:\n * 1. Maintain n_i = 0 by enclosing the human in a wall.\n * 2. The \"impassable\" action is powerful but restricted by the \"no pet or adjacent square has a pet\" rule.\n * 3. Use each human to target and build a boundary of a large rectangle containing them and no pets.\n * 4. Manage simultaneous actions and conflicts (two people building the same square, or moving into a square being blocked).\n */\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nstruct Pet {\n    Pos p;\n    int type;\n};\n\nstruct Human {\n    Pos p;\n    int id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool impassable[31][31];\n\nbool is_valid(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\n// Checks if a square is safe to make impassable\nbool is_safe(int x, int y, const vector<Pet>& cur_pets, const vector<Human>& cur_humans) {\n    if (!is_valid(x, y) || impassable[x][y]) return false;\n    for (const auto& p : cur_pets) {\n        if (p.p.x == x && p.p.y == y) return false;\n        // The square or any adjacent square cannot contain a pet.\n        if (abs(p.p.x - x) + abs(p.p.y - y) <= 1) return false;\n    }\n    for (const auto& h : cur_humans) {\n        if (h.p.x == x && h.p.y == y) return false;\n    }\n    return true;\n}\n\n// BFS to find a path of passable squares\nvector<Pos> get_path(Pos start, Pos end) {\n    if (start == end) return {};\n    queue<Pos> q;\n    q.push(start);\n    vector<vector<Pos>> parent(31, vector<Pos>(31, {0, 0}));\n    vector<vector<bool>> visited(31, vector<bool>(31, false));\n    visited[start.x][start.y] = true;\n    bool found = false;\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n        if (curr == end) {\n            found = true;\n            break;\n        }\n        int dx[] = {-1, 1, 0, 0};\n        int dy[] = {0, 0, -1, 1};\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.x + dx[i], ny = curr.y + dy[i];\n            if (is_valid(nx, ny) && !visited[nx][ny] && !impassable[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n    if (!found) return {};\n    vector<Pos> path;\n    Pos curr = end;\n    while (curr != start) {\n        path.push_back(curr);\n        curr = parent[curr.x][curr.y];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    pets.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pets[i].p.x >> pets[i].p.y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humans[i].p.x >> humans[i].p.y;\n        humans[i].id = i;\n    }\n\n    for (int i = 1; i <= 30; ++i)\n        for (int j = 1; j <= 30; ++j)\n            impassable[i][j] = false;\n\n    // Pre-calculate potential boundaries (rectangles with no pets containing the human)\n    vector<vector<Pos>> human_boundaries(M);\n    for (int i = 0; i < M; ++i) {\n        int max_area = 0;\n        Rect best_rect = {humans[i].p.x, humans[i].p.y, humans[i].p.x, humans[i].p.y};\n        for (int x1 = 1; x1 <= humans[i].p.x; ++x1) {\n            for (int x2 = humans[i].p.x; x2 <= 30; ++x2) {\n                for (int y1 = 1; y1 <= humans[i].p.y; ++y1) {\n                    for (int y2 = humans[i].p.y; y2 <= 30; ++y2) {\n                        bool has_pet = false;\n                        for (const auto& pet : pets) {\n                            if (pet.p.x >= x1 && pet.p.x <= x2 && pet.p.y >= y1 && pet.p.y <= y2) {\n                                has_pet = true; break;\n                            }\n                        }\n                        if (!has_pet) {\n                            int area = (x2 - x1 + 1) * (y2 - y1 + 1);\n                            if (area > max_area) {\n                                max_area = area;\n                                best_rect = {x1, y1, x2, y2};\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for (int x = best_rect.x1; x <= best_rect.x2; ++x) {\n            human_boundaries[i].push_back({x, best_rect.y1});\n            human_boundaries[i].push_back({x, best_rect.y2});\n        }\n        for (int y = best_rect.y1 + 1; y < best_rect.y2; ++y) {\n            human_boundaries[i].push_back({best_rect.x1, y});\n            human_boundaries[i].push_back({best_rect.x2, y});\n        }\n        sort(human_boundaries[i].begin(), human_boundaries[i].end(), [](Pos a, Pos b) {\n            return a.x < b.x || (a.x == b.x && a.y < b.y);\n        });\n        human_boundaries[i].erase(unique(human_boundaries[i].begin(), human_boundaries[i].end()), human_boundaries[i].end());\n    }\n\n    for (int turn = 0; turn < 300; ++turn) {\n        struct IntendedAction {\n            char type; // 'B' build, 'M' move, '.' nothing\n            Pos target_impassable;\n            Pos move_to;\n        };\n        vector<IntendedAction> intended(M, {'.', {0, 0}, {0, 0}});\n\n        for (int i = 0; i < M; ++i) {\n            Pos best_T = {0, 0};\n            int min_dist = 1000;\n            for (const auto& T : human_boundaries[i]) {\n                if (is_safe(T.x, T.y, pets, humans)) {\n                    int d = abs(humans[i].p.x - T.x) + abs(humans[i].p.y - T.y);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_T = T;\n                    }\n                }\n            }\n\n            if (best_T.x != 0) {\n                if (min_dist == 1) {\n                    intended[i].type = 'B';\n                    intended[i].target_impassable = best_T;\n                } else {\n                    intended[i].type = 'M';\n                    intended[i].target_impassable = best_T;\n                    vector<Pos> path = get_path(humans[i].p, best_T);\n                    if (!path.empty()) {\n                        intended[i].move_to = path[0];\n                    } else {\n                        intended[i].type = '.';\n                    }\n                }\n            }\n        }\n\n        vector<char> final_actions(M, '.');\n        vector<Pos> actual_build_targets(M, {0, 0});\n\n        // Resolve build conflicts\n        vector<bool> build_taken(31 * 31, false);\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'B') {\n                int idx = intended[i].target_impassable.x * 31 + intended[i].target_impassable.y;\n                if (!build_taken[idx]) {\n                    build_taken[idx] = true;\n                    Pos h = humans[i].p;\n                    Pos t = intended[i].target_impassable;\n                    if (t.x == h.x - 1 && t.y == h.y) final_actions[i] = 'u';\n                    else if (t.x == h.x + 1 && t.y == h.y) final_actions[i] = 'd';\n                    else if (t.x == h.x && t.y == h.y - 1) final_actions[i] = 'l';\n                    else if (t.x == h.x && t.y == h.y + 1) final_actions[i] = 'r';\n                    actual_build_targets[i] = t;\n                } else {\n                    intended[i].type = '.';\n                }\n            }\n        }\n\n        // Resolve move conflicts\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'M') {\n                Pos next_pos = intended[i].move_to;\n                bool blocked = false;\n                for (int j = 0; j < M; ++j) {\n                    if (intended[j].type == 'B' && intended[j].target_impassable == next_pos) {\n                        blocked = true; break;\n                    }\n                }\n                if (blocked) {\n                    final_actions[i] = '.';\n                } else {\n                    Pos h = humans[i].p;\n                    if (next_pos.x == h.x - 1 && next_pos.y == h.y) final_actions[i] = 'U';\n                    else if (next_pos.x == h.x + 1 && next_pos.y == h.y) final_actions[i] = 'D';\n                    else if (next_pos.x == h.x && next_pos.y == h.y - 1) final_actions[i] = 'L';\n                    else if (next_pos.x == h.x && next_pos.y == h.y + 1) final_actions[i] = 'R';\n                }\n            }\n        }\n\n        string out = \"\";\n        for (int i = 0; i < M; ++i) out += final_actions[i];\n        cout << out << endl;\n\n        for (int i = 0; i < M; ++i) {\n            if (final_actions[i] == 'U') humans[i].p.x--;\n            else if (final_actions[i] == 'D') humans[i].p.x++;\n            else if (final_actions[i] == 'L') humans[i].p.y--;\n            else if (final_actions[i] == 'R') humans[i].p.y++;\n            \n            if (final_actions[i] == 'u' || final_actions[i] == 'd' || final_actions[i] == 'l' || final_actions[i] == 'r') {\n                if (actual_build_targets[i].x != 0) {\n                    impassable[actual_build_targets[i].x][actual_build_targets[i].y] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; ++i) {\n            string move;\n            cin >> move;\n            for (char c : move) {\n                if (c == 'U') pets[i].p.x--;\n                else if (c == 'D') pets[i].p.x++;\n                else if (c == 'L') pets[i].p.y--;\n                else if (c == 'R') pets[i].p.y++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a sequence of moves (U, D, L, R) of length <= 200 that maximizes \n * the expected value of S = 401 - t, where t is the turn Takahashi reaches the office. \n * If he never reaches the office, S = 0.\n * \n * Insights:\n * 1. The error probability p makes the path's robustness crucial. Repeating moves \n *    (e.g., 'RRR' instead of 'R') can increase the probability of success.\n * 2. The expected value calculation can be modeled using dynamic programming:\n *    dp[t][r][c] is the probability of being at (r,c) at time t.\n * 3. The scoring function favors both reaching the office (high probability) \n *    and reaching it quickly (low t).\n * 4. To optimize, we use a simulated annealing approach on the string.\n * \n * Refined Strategy:\n * 1. Efficient DP: Use a list of active cells to speed up DP iterations.\n * 2. Better Initial String: Try the shortest path and its various k-repetition forms.\n * 3. Sophisticated Simulated Annealing (SA):\n *    - Neighbors: Add, Delete, Change, Duplicate, Remove Duplicate, and Swap characters.\n *    - Temperature schedule: Linear cooling.\n *    - Optimization: Focus on keeping the string length within 200.\n */\n\nint si, sj, ti, tj;\ndouble p;\nbool wall_h[20][20];\nbool wall_v[20][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\n// BFS to find the shortest path from home to office\nstring get_shortest_path() {\n    queue<pair<pair<int, int>, string>> q;\n    q.push({{si, sj}, \"\"});\n    bool visited[20][20] = {false};\n    visited[si][sj] = true;\n\n    while (!q.empty()) {\n        auto curr = q.front();\n        q.pop();\n        int r = curr.first.first;\n        int c = curr.first.second;\n        string path = curr.second;\n\n        if (r == ti && c == tj) return path;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            if (nr >= 0 && nr < 20 && nc >= 0 && nc < 20 && !visited[nr][nc]) {\n                bool blocked = false;\n                if (dr[i] == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n                if (!blocked) {\n                    visited[nr][nc] = true;\n                    q.push({{nr, nc}, path + dir_char[i]});\n                }\n            }\n        }\n    }\n    return \"\";\n}\n\n// Optimized DP for expected value calculation\ndouble calculate_expected_value(const string& S) {\n    int L = S.length();\n    if (L > 200) return 0;\n    \n    double dp[400]; \n    memset(dp, 0, sizeof(dp));\n    dp[si * 20 + sj] = 1.0;\n    \n    double expected_val = 0;\n    vector<int> active;\n    active.push_back(si * 20 + sj);\n\n    for (int t = 0; t < L; ++t) {\n        double next_dp[400];\n        memset(next_dp, 0, sizeof(next_dp));\n        \n        int move_dr = 0, move_dc = 0;\n        if (S[t] == 'U') move_dr = -1;\n        else if (S[t] == 'D') move_dr = 1;\n        else if (S[t] == 'L') move_dc = -1;\n        else if (S[t] == 'R') move_dc = 1;\n\n        for (int idx : active) {\n            int r = idx / 20;\n            int c = idx % 20;\n            if (r == ti && c == tj) continue;\n\n            double prob_stay = dp[idx] * p;\n            double prob_move = dp[idx] * (1.0 - p);\n\n            // Case 1: Stay (forgetting)\n            next_dp[idx] += prob_stay;\n\n            // Case 2: Move (attempting direction)\n            int nr = r + move_dr;\n            int nc = c + move_dc;\n            bool blocked = false;\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) {\n                blocked = true;\n            } else if (move_dr == 0) {\n                if (wall_h[r][min(c, nc)]) blocked = true;\n            } else {\n                if (wall_v[min(r, nr)][c]) blocked = true;\n            }\n\n            if (blocked) {\n                next_dp[idx] += prob_move;\n            } else {\n                if (nr == ti && nc == tj) {\n                    expected_val += prob_move * (401 - (t + 1));\n                } else {\n                    next_dp[nr * 20 + nc] += prob_move;\n                }\n            }\n        }\n\n        active.clear();\n        for (int i = 0; i < 400; ++i) {\n            dp[i] = next_dp[i];\n            if (dp[i] > 1e-18) active.push_back(i);\n        }\n        if (active.empty()) break;\n    }\n    return expected_val;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    for (int i = 0; i < 20; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < 19; ++j) wall_h[i][j] = (row[j] == '1');\n    }\n    for (int i = 0; i < 19; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < 20; ++j) wall_v[i][j] = (row[j] == '1');\n    }\n\n    string base_path = get_shortest_path();\n    string best_S = base_path;\n    double best_E = calculate_expected_value(best_S);\n\n    // Robust initial guesses: try repeating moves k times\n    for (int k = 2; k <= 5; ++k) {\n        string enriched = \"\";\n        for (char c : base_path) {\n            for (int count = 0; count < k; ++count) enriched += c;\n        }\n        if (enriched.length() <= 200) {\n            double e = calculate_expected_value(enriched);\n            if (e > best_E) {\n                best_E = e;\n                best_S = enriched;\n            }\n        }\n    }\n\n    // Simulated Annealing\n    string current_S = best_S;\n    double current_E = best_E;\n    mt19937 rng(42);\n    clock_t start_time = clock();\n    const double max_time = 1.88; \n\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > max_time) break;\n\n        double T = 2.0 * (1.0 - elapsed / max_time); \n\n        string next_S = current_S;\n        int type = uniform_int_distribution<int>(0, 5)(rng);\n\n        if (type == 0) { // Add random char\n            if (next_S.length() < 200) {\n                int pos = uniform_int_distribution<int>(0, next_S.length())(rng);\n                next_S.insert(pos, 1, dir_char[uniform_int_distribution<int>(0, 3)(rng)]);\n            } else type = 1;\n        } else if (type == 1) { // Delete random char\n            if (next_S.length() > 1) {\n                next_S.erase(uniform_int_distribution<int>(0, next_S.length() - 1)(rng), 1);\n            } else type = 0;\n        } else if (type == 2) { // Duplicate a char\n            if (next_S.length() < 200) {\n                int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.insert(pos, 1, next_S[pos]);\n            } else type = 3;\n        } else if (type == 3) { // Remove a duplicate char\n            if (next_S.length() > 1) {\n                int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                if (pos > 0 && next_S[pos] == next_S[pos - 1]) next_S.erase(pos, 1);\n                else if (pos < (int)next_S.length() - 1 && next_S[pos] == next_S[pos + 1]) next_S.erase(pos, 1);\n                else type = 2;\n            } else type = 2;\n        } else if (type == 4) { // Change a char\n            int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            next_S[pos] = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n        } else { // Swap two chars\n            if (next_S.length() > 1) {\n                int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                int j = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                swap(next_S[i], next_S[j]);\n            } else type = 4;\n        }\n\n        double next_E = calculate_expected_value(next_S);\n        if (next_E > current_E || (T > 1e-9 && exp((next_E - current_E) / T) > uniform_real_distribution<double>(0, 1)(rng))) {\n            current_S = next_S;\n            current_E = next_E;\n            if (current_E > best_E) {\n                best_E = current_E;\n                best_S = current_S;\n            }\n        }\n    }\n\n    cout << best_S << endl;\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// The directions: 0: Left, 1: Up, 2: Right, 3: Down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Initial connectivity table for the 8 types\nint base_to[8][4] = {\n    {1, 0, -1, -1}, // 0: one curve (Left, Up)\n    {3, -1, -1, 0}, // 1: one curve (Up, Down)\n    {-1, -1, 3, 2}, // 2: one curve (Right, Down)\n    {-1, 2, 1, -1}, // 3: one curve (Down, Left)\n    {1, 0, 3, 2},    // 4: two curves (Left-Up, Right-Down)\n    {3, 2, 1, 0},    // 5: two curves (Up-Down, Left-Right)\n    {2, -1, 0, -1}, // 6: one straight (Left, Right)\n    {-1, 3, -1, 1}, // 7: one straight (Up, Down)\n};\n\n// Precomputed rotation connectivity table\n// rot_to[t][r][d] is the direction to the next tile for type t, rotated r times CCW, \n// when entering from direction d.\nint rot_to[8][4][4];\n\n// Function to rotate a direction 90 degrees counterclockwise: \n// 0 (L) -> 3 (D), 3 (D) -> 2 (R), 2 (R) -> 1 (U), 1 (U) -> 0 (L)\ninline int rotate_dir(int d) { return (d + 3) % 4; }\n// Inverse rotation\ninline int inv_rotate_dir(int d) { return (d + 1) % 4; }\n\nvoid precompute() {\n    for (int t = 0; t < 8; ++t) {\n        for (int d = 0; d < 4; ++d) rot_to[t][0][d] = base_to[t][d];\n        for (int r = 1; r < 4; ++r) {\n            for (int d = 0; d < 4; ++d) {\n                int prev_d = inv_rotate_dir(d);\n                int prev_to = rot_to[t][r - 1][prev_d];\n                if (prev_to == -1) rot_to[t][r][d] = -1;\n                else rot_to[t][r][d] = rotate_dir(prev_to);\n            }\n        }\n    }\n}\n\nint current_to[30][30][4];\nint initial_type[30][30];\nint current_rot[30][30];\nint visited[30][30][4];\nint timer = 0;\n\nlong long get_score(int& L1, int& L2) {\n    vector<int> lengths;\n    timer++;\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                if (visited[i][j][d] != timer) {\n                    int ci = i, cj = j, cd = d;\n                    int len = 0;\n                    bool possible = true;\n                    while (visited[ci][cj][cd] != timer) {\n                        visited[ci][cj][cd] = timer;\n                        int cd2 = current_to[ci][cj][cd];\n                        if (cd2 == -1) {\n                            possible = false;\n                            break;\n                        }\n                        int ni = ci + di[cd2];\n                        int nj = cj + dj[cd2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            possible = false;\n                            break;\n                        }\n                        len++;\n                        ci = ni; cj = nj;\n                        cd = (cd2 + 2) % 4;\n                    }\n                    if (possible && len > 0) {\n                        lengths.push_back(len);\n                    }\n                }\n            }\n        }\n    }\n    if (lengths.size() < 2) {\n        L1 = 0; L2 = 0;\n        return 0;\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    L1 = lengths[0];\n    L2 = lengths[1];\n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precompute();\n\n    for (int i = 0; i < 30; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; ++j) {\n            initial_type[i][j] = s[j] - '0';\n            current_rot[i][j] = 0;\n            for (int d = 0; d < 4; ++d) {\n                current_to[i][j][d] = rot_to[initial_type[i][j]][0][d];\n            }\n        }\n    }\n\n    int L1, L2;\n    long long current_score = get_score(L1, L2);\n    \n    mt19937 rng(1337);\n    clock_t start_time = clock();\n    \n    // Use local time limit per test case (roughly 18ms)\n    // For competitive programming, we assume about 100 cases.\n    // We will check time roughly every 100 iterations.\n    int iterations = 0;\n    while (true) {\n        if (++iterations % 100 == 0) {\n            if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n        }\n\n        int ri = rng() % 30;\n        int rj = rng() % 30;\n        int old_r = current_rot[ri][rj];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        // Backup the current connectivity for this tile\n        int backup_to[4];\n        for (int d = 0; d < 4; ++d) backup_to[d] = current_to[ri][rj][d];\n\n        // Update connectivity\n        current_rot[ri][rj] = new_r;\n        for (int d = 0; d < 4; ++d) {\n            current_to[ri][rj][d] = rot_to[initial_type[ri][rj]][new_r][d];\n        }\n\n        int next_L1, next_L2;\n        long long next_score = get_score(next_L1, next_L2);\n\n        if (next_score >= current_score) {\n            current_score = next_score;\n            L1 = next_L1; L2 = next_L2;\n        } else {\n            // Simple Hill Climbing. For higher rank, use Simulated Annealing.\n            // Given the 20ms time limit, let's stick to Hill Climbing.\n            current_rot[ri][rj] = old_r;\n            for (int d = 0; d < 4; ++d) current_to[ri][rj][d] = backup_to[d];\n        }\n    }\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            cout << current_rot[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint N, T_limit;\nint board[10][10];\nint target_board[10][10];\nbool fixed_cell[10][10];\nstruct Pos { int r, c; bool operator==(const Pos& o) const { return r == o.r && c == o.c; } bool operator!=(const Pos& o) const { return !(*this == o); } };\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; // U, D, L, R\nchar dchar[] = {'U', 'D', 'L', 'R'};\n\nbool check_match(int t1, int t2, int dir) {\n    if (dir == 0) return (t1 & 8) && (t2 & 2); // U: t1 is (r,c), t2 is (r-1,c). t1 has U(2), t2 has D(8)\n    if (dir == 1) return (t1 & 2) && (t2 & 8); // D: t1 is (r,c), t2 is (r+1,c). t1 has D(8), t2 has U(2)\n    if (dir == 2) return (t1 & 1) && (t2 & 4); // L: t1 is (r,c), t2 is (r,c-1). t1 has L(1), t2 has R(4)\n    if (dir == 3) return (t1 & 4) && (t2 & 1); // R: t1 is (r,c), t2 is (r,c+1). t1 has R(4), t2 has L(1)\n    return false;\n}\n\n// The dir above is based on: if we move the tile from (r+dr, c+dc) to (r, c).\n// If dir=0 (Up), the tile at (r+1, c) moves to (r, c).\n// Let's just use the directions as: U means tile at (r+1, c) moves to (r, c).\n// D means tile at (r-1, c) moves to (r, c).\n// L means tile at (r, c+1) moves to (r, c).\n// R means tile at (r, c-1) moves to (r, c).\n\nint get_tile_dir(Pos from, Pos to) {\n    if (from.r == to.r + 1 && from.c == to.c) return 0; // Tile moves Up\n    if (from.r == to.r - 1 && from.c == to.c) return 1; // Tile moves Down\n    if (from.c == to.c + 1 && from.r == to.r) return 2; // Tile moves Left\n    if (from.c == to.c - 1 && from.r == to.r) return 3; // Tile moves Right\n    return -1;\n}\n\nint main() {\n    if (!(cin >> N >> T_limit)) return 0;\n    Pos empty_pos;\n    vector<int> all_tiles;\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) {\n            int val = stoi(s, nullptr, 16);\n            if (val == 0) empty_pos = {i, j};\n            else all_tiles.push_back(val);\n            board[i][j] = (val == 0 ? 0 : val);\n            target_board[i][j] = -1;\n        }\n    }\n\n    mt19937 rng(time(0));\n    vector<pair<Pos, Pos>> tree_edges;\n    vector<Pos> bfs_order;\n    while (true) {\n        tree_edges.clear(); bfs_order.clear();\n        vector<pair<Pos, Pos>> all_possible_edges;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (i == N - 1 && j == N - 1) continue;\n            if (i + 1 < N && !(i + 1 == N - 1 && j == N - 1)) all_possible_edges.push_back({{i, j}, {i + 1, j}});\n            if (j + 1 < N && !(i == N - 1 && j + 1 == N - 1)) all_possible_edges.push_back({{i, j}, {i, j + 1}});\n        }\n        shuffle(all_possible_edges.begin(), all_possible_edges.end(), rng);\n        vector<int> parent(N * N); for (int i = 0; i < N * N; ++i) parent[i] = i;\n        auto find = [&](auto self, int i) -> int { return parent[i] == i ? i : parent[i] = self(self, parent[i]); };\n        for (auto& e : all_possible_edges) {\n            int r1 = find(find, e.first.r * N + e.first.c), r2 = find(find, e.second.r * N + e.second.c);\n            if (r1 != r2) { parent[r1] = r2; tree_edges.push_back(e); }\n        }\n        bfs_order.push_back({0, 0});\n        vector<bool> visited(N * N, false); visited[0] = true;\n        queue<Pos> q; q.push({0, 0});\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = u.r + dr[i], nc = u.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !(nr == N - 1 && nc == N - 1) && !visited[nr * N + nc]) {\n                    visited[nr * N + nc] = true; bfs_order.push_back({nr, nc}); q.push({nr, nc});\n                }\n            }\n        }\n        auto backtrack = [&](auto self, int idx, vector<int>& used) -> bool {\n            if (idx == N * N - 1) return true;\n            Pos u = bfs_order[idx];\n            for (int i = 0; i < (int)all_tiles.size(); ++i) {\n                if (used[i]) continue;\n                int tile = all_tiles[i];\n                bool ok = true;\n                for (auto& edge : tree_edges) {\n                    if ((edge.first == u || edge.second == u)) {\n                        Pos other = (edge.first == u) ? edge.second : edge.first;\n                        if (target_board[other.r][other.c] != -1) {\n                            if (!check_match(tile, target_board[other.r][other.c], get_tile_dir(u, other))) { ok = false; break; }\n                        }\n                    }\n                }\n                if (ok) {\n                    target_board[u.r][u.c] = tile; used[i] = 1;\n                    if (self(self, idx + 1, used)) return true;\n                    used[i] = 0; target_board[u.r][u.c] = -1;\n                }\n            }\n            return false;\n        };\n        vector<int> used(all_tiles.size(), 0);\n        if (backtrack(backtrack, 0, used)) break;\n    }\n\n    vector<Pos> order;\n    for (int i = 0; i < N - 1; ++i) for (int j = 0; j < N; ++j) order.push_back({i, j});\n    for (int j = 0; j < N - 1; ++j) order.push_back({N - 1, j});\n\n    string res = \"\";\n    Pos cur_e = empty_pos;\n    for (auto p : order) {\n        int tr = -1, tc = -1;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (board[i][j] == target_board[p.r][p.c] && !fixed_cell[i][j]) { tr = i; tc = j; break; }\n        }\n        if (tr == p.r && tc == p.c) { fixed_cell[p.r][p.c] = true; continue; }\n\n        auto bfs_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            while (!q.empty()) {\n                auto [curr, path] = q.front(); q.pop();\n                if (curr == target) {\n                    res += path; cur_e = target;\n                    for (char c : path) {\n                        // To keep board in sync, we simulate. But easier to just swap.\n                    }\n                    return;\n                }\n                for (int i = 0; i < 4; ++i) {\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !v[nr][nc]) {\n                        v[nr][nc] = true;\n                        // If empty moves from (nr,nc) to (curr.r, curr.c), tile moves from (curr.r, curr.c) to (nr,nc)\n                        // The direction is the direction the TILE moves.\n                        // If empty moves (nr,nc) -> (curr.r, curr.c), tile moves (curr.r, curr.c) -> (nr,nc).\n                        // If nr = curr.r-1, tile moves Down. If nr = curr.r+1, tile moves Up.\n                        // If nc = curr.c-1, tile moves Right. If nc = curr.c+1, tile moves Left.\n                        char move_char;\n                        if (nr == curr.r - 1) move_char = 'D';\n                        else if (nr == curr.r + 1) move_char = 'U';\n                        else if (nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n        \n        // Correcting move: BFS to move empty to (tr, tc)\n        // But we must not move through the tile we are trying to move!\n        // No, we move the empty to (tr,tc) then to (p.r, p.c)? \n        // Let's do: 1. Move empty to (tr, tc) 2. Move empty to (p.r, p.c)\n        // Actually, to move tile from (tr,tc) to (p.r,p.c):\n        // Step 1: Move empty square to (p.r, p.c). Step 2: Move empty square to (tr, tc).\n        // Then the tile at (tr,tc) will be at (p.r, p.c).\n        \n        // Let's re-implement the BFS more simply.\n        auto move_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            // To move a tile to (p.r, p.c), we shouldn't let the empty square pass through (p.r, p.c)\n            // EXCEPT when it's the final step. But it's easier to say:\n            // During BFS, the empty square cannot pass through ANY fixed cell.\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply the moves to the board\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int nr = temp_e.r, nc = temp_e.c;\n                        int tr_idx = -1;\n                        if(c == 'U') tr_idx = 1; else if(c == 'D') tr_idx = 0;\n                        else if(c == 'L') tr_idx = 3; else tr_idx = 2;\n                        // Wait, the directions are for the TILE.\n                        // If tile moves Up, empty moves Down.\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char move_char;\n                        if(nr == curr.r - 1) move_char = 'D';\n                        else if(nr == curr.r + 1) move_char = 'U';\n                        else if(nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n\n        // 1. Move empty to (p.r, p.c)\n        // But we must avoid (tr, tc) during this, because it's the tile we want.\n        // Wait, the empty square can move through (tr, tc) if it's not fixed!\n        // Let's just move empty to (p.r, p.c) then to (tr, tc).\n        // Wait, the order is:\n        // 1. Move empty square to (p.r, p.c)\n        // 2. Move empty square to (tr, tc)\n        // Now the tile that was at (tr, tc) is at (p.r, p.c).\n        \n        // We'll use a slightly different approach: move empty to (tr, tc) and then to (p.r, p.c).\n        // Actually, the simplest: move empty to (p.r, p.c), then to (tr, tc).\n        // Let's use a modified BFS that avoids (tr, tc) if we are moving to (p.r, p.c).\n        // Wait, the current tile is at (tr, tc). The empty square should move to (p.r, p.c) \n        // without using (tr, tc) as an intermediate.\n        \n        // BFS to move empty to (p.r, p.c), avoiding (tr, tc) and all fixed cells.\n        auto bfs_with_avoid = [&](Pos target, Pos avoid) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            if(avoid.r != -1) v[avoid.r][avoid.c] = true;\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply moves\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char m;\n                        if(nr == curr.r - 1) m = 'D'; else if(nr == curr.r + 1) m = 'U';\n                        else if(nc == curr.c - 1) m = 'R'; else m = 'L';\n                        q.push({{nr, nc}, path + m});\n                    }\n                }\n            }\n        };\n\n        bfs_with_avoid(p, {tr, tc});\n        bfs_with_avoid({tr, tc}, {-1, -1});\n        fixed_cell[p.r][p.c] = true;\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Maximize the number of distributed pieces (sum_{d=1..10} min(a_d, b_d))\n * where a_d is the number of attendees with d years of experience, \n * and b_d is the number of pieces with exactly d strawberries.\n * Constraints: N <= 5500, K = 100.\n * Approach: Simulated Annealing (SA).\n * \n * Strategies:\n * 1. Represent each strawberry's position relative to K lines using an unsigned __int128 bitset.\n * 2. A piece is uniquely identified by its bitset signature.\n * 3. Use line-based updates for efficiency.\n * 4. Moves:\n *    - Random line.\n *    - Line through two strawberries (slightly jittered to avoid cutting through centers).\n *    - Jitter an existing line.\n */\n\ntypedef __int128_t int128;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct RobustLine {\n    long long a, b, c;\n    long long px, py, qx, qy;\n};\n\nstruct SigBitset {\n    unsigned __int128 bits;\n};\n\nRobustLine make_robust_line(long long px, long long py, long long qx, long long qy) {\n    RobustLine l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = qy - py;\n    l.b = px - qx;\n    l.c = (long long)(((__int128)px * qy) - ((__int128)qx * py));\n    return l;\n}\n\nint N, K;\nint a_years[11];\nPoint strawberries[5505];\nRobustLine robust_lines[105];\nSigBitset sigs[5505];\nint on_count[5505];\n\nint calculate_score() {\n    static vector<unsigned __int128> active_sigs;\n    active_sigs.clear();\n    for (int i = 0; i < N; ++i) {\n        if (on_count[i] == 0) {\n            active_sigs.push_back(sigs[i].bits);\n        }\n    }\n    if (active_sigs.empty()) return 0;\n    sort(active_sigs.begin(), active_sigs.end());\n\n    int b_counts[11] = {0};\n    int current_run = 1;\n    for (size_t i = 1; i < active_sigs.size(); ++i) {\n        if (active_sigs[i] == active_sigs[i-1]) {\n            current_run++;\n        } else {\n            if (current_run <= 10) b_counts[current_run]++;\n            current_run = 1;\n        }\n    }\n    if (current_run <= 10) b_counts[current_run]++;\n\n    int total = 0;\n    for (int d = 1; d <= 10; ++d) {\n        total += min(a_years[d], b_counts[d]);\n    }\n    return total;\n}\n\nvoid update_line(int idx, RobustLine new_line) {\n    for (int i = 0; i < N; ++i) {\n        long long val_old = robust_lines[idx].a * strawberries[i].x + \n                            robust_lines[idx].b * strawberries[i].y + \n                            robust_lines[idx].c;\n        if (val_old == 0) on_count[i]--;\n\n        long long val_new = new_line.a * strawberries[i].x + \n                            new_line.b * strawberries[i].y + \n                            new_line.c;\n        if (val_new == 0) {\n            on_count[i]++;\n        } else {\n            if (val_new > 0) sigs[i].bits |= ((unsigned __int128)1 << idx);\n            else sigs[i].bits &= ~((unsigned __int128)1 << idx);\n        }\n    }\n    robust_lines[idx] = new_line;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> K)) return 0;\n    for (int i = 1; i <= 10; ++i) cin >> a_years[i];\n    for (int i = 0; i < N; ++i) cin >> strawberries[i].x >> strawberries[i].y;\n\n    mt19937_64 rng(1337);\n    uniform_int_distribution<long long> dist_coord(-1000000, 1000000);\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    uniform_int_distribution<int> dist_K(0, K - 1);\n\n    // Initialize\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].bits = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        // Initialize with a line far outside the cake (y = -20000)\n        robust_lines[i] = make_robust_line(0, -20000, 1, -20000);\n        for (int j = 0; j < N; ++j) {\n            long long val = robust_lines[i].a * strawberries[j].x + \n                            robust_lines[i].b * strawberries[j].y + \n                            robust_lines[i].c;\n            if (val == 0) on_count[j]++;\n            else if (val > 0) sigs[j].bits |= ((unsigned __int128)1 << i);\n        }\n    }\n\n    int current_score = calculate_score();\n    int best_score = current_score;\n    vector<RobustLine> best_lines(robust_lines, robust_lines + K);\n\n    auto start_time = chrono::steady_clock::now();\n    double T = 1.0;\n    double factor = 0.99999;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n        }\n        iter++;\n\n        int idx = dist_K(rng);\n        RobustLine old_line = robust_lines[idx];\n        RobustLine new_line;\n        \n        int move_type = rng() % 100;\n        if (move_type < 40) { // Random Line\n            new_line = make_robust_line(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        } else if (move_type < 80) { // Two Strawberries\n            int s1 = dist_idx(rng);\n            int s2 = dist_idx(rng);\n            if (s1 == s2) {\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s1].x + 1, strawberries[s1].y + 1);\n            } else {\n                long long ox = (rng() % 3) - 1;\n                long long oy = (rng() % 3) - 1;\n                new_line = make_robust_line(strawberries[s1].x, strawberries[s1].y, strawberries[s2].x + ox, strawberries[s2].y + oy);\n            }\n        } else { // Jitter Existing Line\n            new_line = old_line;\n            new_line.px += (rng() % 3) - 1;\n            new_line.py += (rng() % 3) - 1;\n            new_line.qx += (rng() % 3) - 1;\n            new_line.qy += (rng() % 3) - 1;\n            if (new_line.px == new_line.qx && new_line.py == new_line.qy) continue;\n            new_line.a = new_line.qy - new_line.py;\n            new_line.b = new_line.px - new_line.qx;\n            new_line.c = (long long)(((__int128)new_line.px * new_line.qy) - ((__int128)new_line.qx * new_line.py));\n        }\n\n        update_line(idx, new_line);\n        int new_score = calculate_score();\n\n        if (new_score >= current_score || (exp((new_score - current_score) / T) > (double)rng() / mt19937_64::max())) {\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < K; ++i) best_lines[i] = robust_lines[i];\n            }\n        } else {\n            update_line(idx, old_line);\n        }\n        T *= factor;\n    }\n\n    cout << K << \"\\n\";\n    for (int i = 0; i < K; ++i) {\n        cout << best_lines[i].px << \" \" << best_lines[i].py << \" \" << best_lines[i].qx << \" \" << best_lines[i].qy << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The goal is to maximize the sum of weights of dots on an N x N grid.\n * Weight of (x, y) is (x-c)^2 + (y-c)^2 + 1, favoring points far from the center.\n * Rectangles can be axis-aligned or 45-degree inclined.\n * \n * REFINED STRATEGY:\n * Use a priority queue to store potential rectangles. Initially, find all possible\n * rectangles using an O(N^4) search. In each step, pop the best rectangle, check if \n * it's still valid (its new corner p1 is not a dot, its other corners are dots, \n * and its perimeter is valid), then add the new dot and its segments. \n * When a new dot is added, find new valid rectangles that use this new dot \n * as one of its existing-dot corners (p2, p3, or p4).\n * \n * Complexity: \n * Initial search: O(N^4)\n * Per step: O(N^2) new rectangles found, and O(N) to validate.\n * This fits well within the 5s time limit.\n */\n\nstruct Point {\n    int x, 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\nstruct RectCandidate {\n    Point p[4]; // p[0] is the new dot p1\n    double weight;\n    bool operator<(const RectCandidate& other) const { return weight < other.weight; }\n};\n\nint N, M;\nbool is_dot[65][65];\nbool used_h[65][65], used_v[65][65], used_d1[65][65], used_d2[65][65];\nvector<Point> dots;\nvector<int> dots_in_row[65], dots_in_col[65];\n\ndouble get_weight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1.0;\n}\n\nbool is_in_grid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool check_segments(const vector<Point>& rect, bool mark) {\n    for (int i = 0; i < 4; ++i) {\n        Point s = rect[i], e = rect[(i + 1) % 4];\n        int dx = (e.x > s.x ? 1 : (e.x < s.x ? -1 : 0));\n        int dy = (e.y > s.y ? 1 : (e.y < s.y ? -1 : 0));\n        int cx = s.x, cy = s.y;\n        while (cx != e.x || cy != e.y) {\n            int nx = cx + dx, ny = cy + dy;\n            if (dx != 0 && dy == 0) {\n                int mx = min(cx, nx);\n                if (used_h[mx][cy]) return false;\n                if (mark) used_h[mx][cy] = true;\n            } else if (dx == 0 && dy != 0) {\n                int my = min(cy, ny);\n                if (used_v[cx][my]) return false;\n                if (mark) used_v[cx][my] = true;\n            } else if (dx == 1 && dy == 1) {\n                if (used_d1[cx][cy]) return false;\n                if (mark) used_d1[cx][cy] = true;\n            } else if (dx == -1 && dy == -1) {\n                if (used_d1[cx - 1][cy - 1]) return false;\n                if (mark) used_d1[cx - 1][cy - 1] = true;\n            } else if (dx == -1 && dy == 1) {\n                if (used_d2[cx - 1][cy]) return false;\n                if (mark) used_d2[cx - 1][cy] = true;\n            } else if (dx == 1 && dy == -1) {\n                if (used_d2[cx][cy - 1]) return false;\n                if (mark) used_d2[cx][cy - 1] = true;\n            }\n            cx = nx; cy = ny;\n        }\n    }\n    return true;\n}\n\nbool check_no_other_dots(const vector<Point>& rect) {\n    for (int i = 0; i < 4; ++i) {\n        Point s = rect[i], e = rect[(i + 1) % 4];\n        int dx = (e.x > s.x ? 1 : (e.x < s.x ? -1 : 0));\n        int dy = (e.y > s.y ? 1 : (e.y < s.y ? -1 : 0));\n        int cx = s.x + dx, cy = s.y + dy;\n        while (cx != e.x || cy != e.y) {\n            if (is_dot[cx][cy]) {\n                bool is_corner = false;\n                for (int j = 1; j < 4; ++j) if (cx == rect[j].x && cy == rect[j].y) is_corner = true;\n                if (!is_corner) return false;\n            }\n            cx += dx; cy += dy;\n        }\n    }\n    return true;\n}\n\npriority_queue<RectCandidate> pq;\n\nvoid add_rect_to_pq(const vector<Point>& r) {\n    if (!is_in_grid(r[0].x, r[0].y)) return;\n    if (is_dot[r[0].x][r[0].y]) return;\n    for (int i = 1; i < 4; ++i) if (!is_dot[r[i].x][r[i].y]) return;\n    // We don't check no_other_dots or segments here because they can change.\n    // We'll check them when we pop from the pq.\n    pq.push({ {r[0], r[1], r[2], r[3]}, get_weight(r[0].x, r[0].y) });\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        is_dot[x][y] = true;\n        dots.push_back({x, y});\n        dots_in_row[y].push_back(x);\n        dots_in_col[x].push_back(y);\n    }\n\n    // Initial Search: Axis-aligned\n    for (int x1 = 0; x1 < N; ++x1) {\n        for (int x2 = x1 + 1; x2 < N; ++x2) {\n            for (int y1 = 0; y1 < N; ++y1) {\n                for (int y2 = y1 + 1; y2 < N; ++y2) {\n                    int x[] = {x1, x2, x2, x1};\n                    int y[] = {y1, y1, y2, y2};\n                    int dot_count = 0;\n                    int new_dot_idx = -1;\n                    for (int k = 0; k < 4; ++k) {\n                        if (is_dot[x[k]][y[k]]) dot_count++;\n                        else new_dot_idx = k;\n                    }\n                    if (dot_count == 3 && new_dot_idx != -1) {\n                        vector<Point> r(4);\n                        for (int k = 0; k < 4; ++k) r[k] = {x[k], y[k]};\n                        // Reorder so r[0] is the new dot\n                        vector<Point> ordered_r = {r[new_dot_idx], r[(new_dot_idx + 1) % 4], r[(new_dot_idx + 2) % 4], r[(new_dot_idx + 3) % 4]};\n                        add_rect_to_pq(ordered_r);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initial Search: 45-degree\n    for (int u1 = 0; u1 <= 2 * N - 2; ++u1) {\n        for (int u2 = u1 + 2; u2 <= 2 * N - 2; ++u2) {\n            for (int v1 = -(N - 1); v1 <= N - 1; ++v1) {\n                if ((u1 % 2 + 2) % 2 != (v1 % 2 + 2) % 2) continue;\n                for (int v2 = v1 + 2; v2 <= N - 1; v2 += 2) {\n                    int u[] = {u1, u2, u2, u1};\n                    int v[] = {v1, v1, v2, v2};\n                    int x[4], y[4];\n                    int dot_count = 0, new_dot_idx = -1;\n                    for (int k = 0; k < 4; ++k) {\n                        x[k] = (u[k] + v[k]) / 2;\n                        y[k] = (u[k] - v[k]) / 2;\n                        if (is_dot[x[k]][y[k]]) dot_count++;\n                        else new_dot_idx = k;\n                    }\n                    if (dot_count == 3 && new_dot_idx != -1) {\n                        vector<Point> r(4);\n                        for (int k = 0; k < 4; ++k) r[k] = {x[k], y[k]};\n                        vector<Point> ordered_r = {r[new_dot_idx], r[(new_dot_idx + 1) % 4], r[(new_dot_idx + 2) % 4], r[(new_dot_idx + 3) % 4]};\n                        add_rect_to_pq(ordered_r);\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<Point>> ops;\n    while (!pq.empty()) {\n        RectCandidate best = pq.top(); pq.pop();\n        vector<Point> r = {best.p[0], best.p[1], best.p[2], best.p[3]};\n        if (is_dot[r[0].x][r[0].y]) continue;\n        bool p_dots = true;\n        for (int i = 1; i < 4; ++i) if (!is_dot[r[i].x][r[i].y]) { p_dots = false; break; }\n        if (!p_dots) continue;\n        if (!check_no_other_dots(r) || !check_segments(r, false)) continue;\n\n        // Valid rectangle found\n        is_dot[r[0].x][r[0].y] = true;\n        dots.push_back(r[0]);\n        dots_in_row[r[0].y].push_back(r[0].x);\n        dots_in_col[r[0].x].push_back(r[0].y);\n        check_segments(r, true);\n        ops.push_back(r);\n\n        // Find new rectangles using the new dot as p2, p3, or p4\n        Point p_new = r[0];\n        // Case 1: p_new is p3 (the corner between p2 and p4)\n        for (int py : dots_in_col[p_new.x]) {\n            for (int px : dots_in_row[p_new.y]) {\n                Point p2 = {p_new.x, py}, p4 = {px, p_new.y}, p1 = {px, py};\n                if (p1 != p_new && p1 != p2 && p1 != p4) {\n                    add_rect_to_pq({p1, p2, p_new, p4});\n                }\n            }\n        }\n        // Case 2: p_new is p2 or p4 (p_new's neighbor is p3)\n        for (int py : dots_in_col[p_new.x]) {\n            Point p3 = {p_new.x, py};\n            for (int px : dots_in_row[p3.y]) {\n                Point p4 = {px, p3.y}, p1 = {px, p_new.y};\n                if (p1 != p_new && p1 != p3 && p1 != p4) {\n                    add_rect_to_pq({p1, p_new, p3, p4});\n                }\n            }\n        }\n        for (int px : dots_in_row[p_new.y]) {\n            Point p3 = {px, p_new.y};\n            for (int py : dots_in_col[p3.x]) {\n                Point p4 = {p3.x, py}, p1 = {p_new.x, py};\n                if (p1 != p_new && p1 != p3 && p1 != p4) {\n                    add_rect_to_pq({p1, p_new, p3, p4});\n                }\n            }\n        }\n        // Case 3: 45-degree rectangles with p_new as p3\n        for (auto& p_other : dots) {\n            int dx = p_other.x - p_new.x, dy = p_other.y - p_new.y;\n            if (abs(dx) == abs(dy) && dx != 0) {\n                // p_other could be p2 or p4. Let's say p2. \n                // Then p4 = p_new + rotate(p_new-p_other, 90) or rotate(p_new-p_other, -90)\n                int dirs[2][2] = {{-dy, dx}, {dy, -dx}};\n                for (int d = 0; d < 2; ++d) {\n                    Point p4 = {p_new.x + dirs[d][0], p_new.y + dirs[d][1]};\n                    if (is_in_grid(p4.x, p4.y) && is_dot[p4.x][p4.y]) {\n                        Point p1 = {p_other.x + p4.x - p_new.x, p_other.y + p4.y - p_new.y};\n                        if (is_in_grid(p1.x, p1.y)) {\n                            add_rect_to_pq({p1, p_other, p_new, p4});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (const auto& o : ops) {\n        cout << o[0].x << \" \" << o[0].y << \" \" << o[1].x << \" \" << o[1].y << \" \"\n             << o[2].x << \" \" << o[2].y << \" \" << o[3].x << \" \" << o[3].y << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global grid and flavors to store current state and input\nint grid[10][10];\nint flavors[100];\n\nstruct Point {\n    int r, c;\n};\n\n// Directions for adjacency\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n/**\n * Calculates the connectivity score (sum of n_i^2) for the current grid.\n * n_i is the size of the i-th connected component of the same flavor.\n */\nint calculate_score(int current_grid[10][10]) {\n    bool visited[10][10] = {false};\n    int total_score = 0;\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (current_grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = current_grid[r][c];\n                int size = 0;\n                queue<Point> q;\n                q.push({r, c});\n                visited[r][c] = true;\n                while (!q.empty()) {\n                    Point curr = q.front();\n                    q.pop();\n                    size++;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = curr.r + dr[i];\n                        int nc = curr.c + dc[i];\n                        if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 &&\n                            !visited[nr][nc] && current_grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n/**\n * Simulates the effect of tilting the box in a given direction.\n * F: Front (r decreases), B: Backward (r increases), L: Left (c decreases), R: Right (c increases)\n */\nvoid simulate_tilt(int current_grid[10][10], char dir, int next_grid[10][10]) {\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            next_grid[i][j] = 0;\n\n    if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 0; r < 10; ++r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 9; r >= 0; --r) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[9 - count++][c] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 0; c < 10; ++c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][count++] = current_grid[r][c];\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 9; c >= 0; --c) {\n                if (current_grid[r][c] != 0) {\n                    next_grid[r][9 - count++] = current_grid[r][c];\n                }\n            }\n        }\n    }\n}\n\n/**\n * Applies the selected tilt to the current grid.\n */\nvoid apply_tilt(int current_grid[10][10], char dir) {\n    int next_grid[10][10];\n    simulate_tilt(current_grid, dir, next_grid);\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            current_grid[i][j] = next_grid[i][j];\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read the flavors of the 100 candies\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    // Initialize the grid as empty\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            grid[i][j] = 0;\n\n    char directions[] = {'F', 'B', 'L', 'R'};\n\n    // Process each of the 100 candies\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        if (!(cin >> p_t)) break;\n\n        // Locate the p_t-th empty cell (1-indexed)\n        vector<Point> empty_cells;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    empty_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // Place the t-th candy in the determined cell\n        Point pos = empty_cells[p_t - 1];\n        grid[pos.r][pos.c] = flavors[t - 1];\n\n        // Greedy strategy: choose the tilt direction that maximizes the current score\n        int best_score = -1;\n        char best_dir = 'F';\n\n        for (char d : directions) {\n            int next_grid_temp[10][10];\n            simulate_tilt(grid, d, next_grid_temp);\n            int score = calculate_score(next_grid_temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        // Output the chosen direction and flush\n        cout << best_dir << endl;\n        // Apply the move to the actual grid state\n        apply_tilt(grid, best_dir);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis and Improvement Strategy:\n * \n * 1. Insight from Feedback:\n *    The previous score was relatively high but had many failures. The primary \n *    weakness was likely the susceptibility of the clique-based encoding to vertex\n *    shuffling and noise when epsilon is high, or being stuck in local minima \n *    during the permutation search.\n * \n * 2. Encoding Strategy:\n *    Keep the clique-based encoding with N=100. For each index i (0 to M-1), \n *    the graph G_i is a clique of size k = i+1. This maximizes the distinctness \n *    of edge counts and degree distributions.\n * \n * 3. Decoding Strategy (Prediction):\n *    - Candidate Selection: Instead of checking all M, use the edge count of the \n *      received graph H to select the top 35 most likely candidate graphs G_i.\n *    - Permutation Initialization: Use the degree distribution. Sort the \n *      degrees of H and G_i and create an initial permutation P mapping \n *      H's vertices to G_i's vertices.\n *    - Local Search: Use a Hill Climbing approach with many iterations \n *      (1500 iterations per candidate). To avoid local minima, allow \n *      swaps that result in zero change in mismatch count (delta <= 0).\n * \n * 4. Optimization:\n *    - Use a flat 1D array for G_adj to improve cache locality.\n *    - Use a pre-calculated degree array for all G_i.\n *    - Implement a time-limited search to ensure the program runs within the 5s limit.\n *    - The delta calculation in the local search is optimized to O(N) per iteration.\n * \n * 5. Complexity:\n *    Total complexity is approximately O(Queries * Candidates * Iterations * N).\n *    100 * 35 * 1500 * 100 = 5.25 * 10^8 operations, which fits within 5 seconds.\n */\n\n// Global arrays to fit into memory and avoid reallocation\nunsigned char G_adj[100 * 100 * 100]; // G_adj[i][u][v] flattened\nbool H_adj[100][100];\nint Gi_edges[100];\nint G_deg[100][100];\n\nint main() {\n    // Fast I/O setup\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double epsilon;\n    if (!(cin >> M >> epsilon)) return 0;\n\n    const int N = 100;\n    const int L = N * (N - 1) / 2;\n\n    // Encoding step\n    for (int i = 0; i < M; ++i) {\n        int k = i + 1; // Clique size\n        Gi_edges[i] = k * (k - 1) / 2;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (u < k && v < k && u != v) {\n                    G_adj[i * 10000 + u * 100 + v] = 1;\n                } else {\n                    G_adj[i * 10000 + u * 100 + v] = 0;\n                }\n            }\n        }\n    }\n\n    // Pre-calculate degrees for all encoded graphs\n    for (int i = 0; i < M; ++i) {\n        for (int u = 0; u < N; ++u) {\n            int d = 0;\n            for (int v = 0; v < N; ++v) {\n                if (G_adj[i * 10000 + u * 100 + v]) d++;\n            }\n            G_deg[i][u] = d;\n        }\n    }\n\n    // Output encoding\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        string s = \"\";\n        s.reserve(L);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s += (G_adj[i * 10000 + u * 100 + v] ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    mt19937 rng(42);\n    auto start_total = chrono::steady_clock::now();\n\n    // Query processing\n    for (int q = 0; q < 100; ++q) {\n        string H_str;\n        if (!(cin >> H_str)) break;\n\n        int h_edges = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) H_adj[u][v] = false;\n        }\n        int idx = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (H_str[idx++] == '1') {\n                    H_adj[u][v] = H_adj[v][u] = true;\n                    h_edges++;\n                }\n            }\n        }\n\n        // Degree distribution of H\n        vector<int> H_deg(N, 0);\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) {\n                if (H_adj[u][v]) H_deg[u]++;\n            }\n        }\n\n        // Select candidates based on expected edge counts\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < M; ++i) {\n            double expected_h_edges = (double)Gi_edges[i] * (1.0 - 2.0 * epsilon) + (double)L * epsilon;\n            candidates.push_back({abs((double)h_edges - expected_h_edges), i});\n        }\n        sort(candidates.begin(), candidates.end());\n\n        int best_i = 0;\n        int min_mismatches = 2e9;\n\n        // Iterate through candidates\n        for (int c = 0; c < min(M, 35); ++c) {\n            int i = candidates[c].second;\n\n            // Initialize permutation by sorting degrees\n            vector<int> H_idx(N), G_idx(N);\n            for (int j = 0; j < N; ++j) {\n                H_idx[j] = j;\n                G_idx[j] = j;\n            }\n            sort(H_idx.begin(), H_idx.end(), [&](int a, int b) { return H_deg[a] < H_deg[b]; });\n            sort(G_idx.begin(), G_idx.end(), [&](int a, int b) { return G_deg[i][a] < G_deg[i][b]; });\n\n            vector<int> P(N);\n            for (int j = 0; j < N; ++j) P[H_idx[j]] = G_idx[j];\n\n            // Initial mismatch count\n            int cur_mismatches = 0;\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (G_adj[i * 10000 + P[u] * 100 + P[v]] != H_adj[u][v]) cur_mismatches++;\n                }\n            }\n\n            // Hill Climbing optimization\n            for (int iter = 0; iter < 1500; ++iter) {\n                int u = rng() % N;\n                int v = rng() % N;\n                if (u == v) continue;\n\n                // Compute delta in O(N)\n                int delta = 0;\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    // Calculate old and new mismatch contributions for edges (u, k) and (v, k)\n                    int old_uk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[u][k]);\n                    int old_vk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[v][k]);\n                    int new_uk = (G_adj[i * 10000 + P[v] * 100 + P[k]] != H_adj[u][k]);\n                    int new_vk = (G_adj[i * 10000 + P[u] * 100 + P[k]] != H_adj[v][k]);\n                    delta += (new_uk + new_vk) - (old_uk + old_vk);\n                }\n\n                // Accept swap if it improves or maintains mismatch count\n                if (delta <= 0) {\n                    cur_mismatches += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n\n            if (cur_mismatches < min_mismatches) {\n                min_mismatches = cur_mismatches;\n                best_i = i;\n            }\n            \n            // Periodic check to avoid TLE\n            if (c % 10 == 0) {\n                auto now = chrono::steady_clock::now();\n                if (chrono::duration_cast<chrono::milliseconds>(now - start_total).count() > 4700) break;\n            }\n        }\n\n        // Predict and output\n        cout << best_i << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n// Use a large INF for Dijkstra to avoid overflow while still being larger than any possible path\nconst long long INF = 1e15;\n// The problem defines unreachable distance as 10^9\nconst long long DIST_INF = 1000000000LL;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct AdjEdge {\n    int to, w, id;\n};\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w, i});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w, i});\n    }\n\n    // Skip vertex coordinates as they are not required for the improved heuristic\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // edge_count[i] stores the number of pairs (start, target) such that edge i is on the shortest path in the Dijkstra forest\n    vector<long long> edge_count(M, 0);\n\n    // Phase 1: Calculate how many shortest paths pass through each edge\n    for (int start = 1; start <= N; ++start) {\n        vector<long long> dist(N + 1, INF);\n        vector<int> parent_node(N + 1, -1);\n        vector<int> parent_edge(N + 1, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n\n        dist[start] = 0;\n        pq.push({0, start});\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& e : adj[u]) {\n                if (dist[e.to] > dist[u] + e.w) {\n                    dist[e.to] = dist[u] + e.w;\n                    parent_node[e.to] = u;\n                    parent_edge[e.to] = e.id;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n\n        // Sort nodes by distance in descending order to propagate counts up the Dijkstra tree\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 1);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n\n        vector<long long> node_count(N + 1, 1);\n        for (int u : nodes) {\n            if (u != start && parent_edge[u] != -1) {\n                int p = parent_node[u];\n                int id = parent_edge[u];\n                edge_count[id] += node_count[u];\n                node_count[p] += node_count[u];\n            }\n        }\n    }\n\n    // Phase 2: Calculate the \"detour\" weight for each edge to refine the impact metric\n    vector<long long> I(M);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int w = edges[i].w;\n\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        vector<long long> dist_u(N + 1, INF);\n        dist_u[u] = 0;\n        pq.push({0, u});\n\n        while (!pq.empty()) {\n            auto [d, curr] = pq.top();\n            pq.pop();\n            if (d > dist_u[curr]) continue;\n            if (curr == v) break; // Optimization: stop once we reach the other endpoint\n            for (auto& e_adj : adj[curr]) {\n                if (e_adj.id == i) continue; // Ignore the edge being analyzed\n                if (dist_u[e_adj.to] > d + e_adj.w) {\n                    dist_u[e_adj.to] = d + e_adj.w;\n                    pq.push({dist_u[e_adj.to], e_adj.to});\n                }\n            }\n        }\n\n        long long w_prime = dist_u[v];\n        if (w_prime >= INF) w_prime = DIST_INF; // If unreachable, use the penalty value\n        \n        // Refined Impact: (number of shortest paths) * (increase in path length)\n        I[i] = edge_count[i] * (w_prime - w);\n    }\n\n    // Phase 3: Sort edges by impact and assign to days greedily to balance the total frustration\n    vector<int> edge_indices(M);\n    iota(edge_indices.begin(), edge_indices.end(), 0);\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return I[a] > I[b];\n    });\n\n    vector<int> assignment(M);\n    vector<int> day_count(D, 0);\n    vector<long long> day_sum_I(D, 0);\n    for (int idx : edge_indices) {\n        int best_day = -1;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K) {\n                if (best_day == -1 || day_sum_I[d] < day_sum_I[best_day]) {\n                    best_day = d;\n                }\n            }\n        }\n        assignment[idx] = best_day + 1;\n        day_count[best_day]++;\n        day_sum_I[best_day] += I[idx];\n    }\n\n    // Final Output\n    for (int i = 0; i < M; ++i) {\n        cout << assignment[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: AHC019 - Silhouette\n * \n * The objective is to construct two 3D objects that satisfy two sets of silhouettes (front and right)\n * using a shared set of blocks. The goal is to minimize:\n * 10^9 * (r1 + r2 + sum_{i in S} 1/vi), where r_i is the volume of unused blocks and S is the \n * set of blocks used in both objects.\n * \n * Strategy:\n * 1. For each z-layer, identify the required x-coordinates (Xz) and y-coordinates (Yz) for both \n *    object 1 and object 2 based on the silhouettes.\n * 2. To satisfy the silhouette, a layer's cells must cover all x in Xz and all y in Yz.\n *    The minimal way to do this is by a \"cross\" shape: {(x, y0) | x in Xz} U {(x0, y) | y in Yz}.\n * 3. For each z-layer, we brute-force all possible center points (x0, y0) for object 1 and \n *    (x0', y0') for object 2 to maximize the number of common cells in the intersection.\n *    This maximizes common blocks and their volumes, which helps minimize the score.\n * 4. After deciding the cells (B1 and B2) for each layer, we partition them into three sets:\n *    - C: Cells in both B1 and B2 (to be formed into common blocks).\n *    - O1: Cells in B1 but not in B2 (to be formed into \"only object 1\" blocks).\n *    - O2: Cells in B2 but not in B1 (to be formed into \"only object 2\" blocks).\n * 5. We find connected components in each set to form the blocks. Since components are \n *    connected, every block is valid.\n * 6. The complexity of the z-layer brute-force is O(D^7), which is roughly 10^8 operations.\n *    Given the 6-second time limit, this is well within limits.\n */\n\nstruct Cell {\n    int x, y, z;\n};\n\n// Function to find connected components in a given mask\nvoid find_components(const vector<vector<vector<bool>>>& mask, int D,\n                    vector<vector<vector<int>>>& b1, vector<vector<vector<int>>>& b2,\n                    int& block_id, int type) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    static const int dx[] = {1, -1, 0, 0, 0, 0};\n    static const int dy[] = {0, 0, 1, -1, 0, 0};\n    static const int dz[] = {0, 0, 0, 0, 1, -1};\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (mask[x][y][z] && !visited[x][y][z]) {\n                    block_id++;\n                    queue<Cell> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    while (!q.empty()) {\n                        Cell curr = q.front();\n                        q.pop();\n\n                        if (type == 0) { // Common blocks\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 1) { // Blocks only in object 1\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                        } else { // Blocks only in object 2\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        }\n\n                        for (int i = 0; i < 6; ++i) {\n                            int nx = curr.x + dx[i];\n                            int ny = curr.y + dy[i];\n                            int nz = curr.z + dz[i];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                                mask[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                visited[nx][ny][nz] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Function to count the size of the intersection for given cross-center coordinates\nint count_intersection(int x1, int y1, const vector<int>& X1, const vector<int>& Y1,\n                      int x2, int y2, const vector<int>& X2, const vector<int>& Y2, int D) {\n    static bool in_S1[15][15];\n    static bool in_S2[15][15];\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            in_S1[i][j] = false;\n            in_S2[i][j] = false;\n        }\n    }\n\n    for (int x : X1) in_S1[x][y1] = true;\n    for (int y : Y1) in_S1[x1][y] = true;\n    for (int x : X2) in_S2[x][y2] = true;\n    for (int y : Y2) in_S2[x2][y] = true;\n\n    int count = 0;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (in_S1[i][j] && in_S2[i][j]) count++;\n        }\n    }\n    return count;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n    for (int i = 0; i < D; ++i) cin >> f2[i];\n    for (int i = 0; i < D; ++i) cin >> r2[i];\n\n    vector<vector<vector<bool>>> B1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> B2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; ++z) {\n        vector<int> X1, Y1, X2, Y2;\n        for (int x = 0; x < D; ++x) if (f1[z][x] == '1') X1.push_back(x);\n        for (int y = 0; y < D; ++y) if (r1[z][y] == '1') Y1.push_back(y);\n        for (int x = 0; x < D; ++x) if (f2[z][x] == '1') X2.push_back(x);\n        for (int y = 0; y < D; ++y) if (r2[z][y] == '1') Y2.push_back(y);\n\n        int max_inter = -1;\n        int bx1 = 0, by1 = 0, bx2 = 0, by2 = 0;\n\n        // Brute-force to find optimal center points for each z-layer to maximize intersection\n        for (int x1 : X1) {\n            for (int y1 : Y1) {\n                for (int x2 : X2) {\n                    for (int y2 : Y2) {\n                        int inter = count_intersection(x1, y1, X1, Y1, x2, y2, X2, Y2, D);\n                        if (inter > max_inter) {\n                            max_inter = inter;\n                            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Set cells based on best found center coordinates\n        for (int x : X1) B1[x][by1][z] = true;\n        for (int y : Y1) B1[bx1][y][z] = true;\n        for (int x : X2) B2[x][by2][z] = true;\n        for (int y : Y2) B2[bx2][y][z] = true;\n    }\n\n    // Group cells into: Common (C), Only in 1 (O1), or Only in 2 (O2)\n    vector<vector<vector<bool>>> mask_C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> mask_O1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> mask_O2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (B1[x][y][z] && B2[x][y][z]) mask_C[x][y][z] = true;\n                else if (B1[x][y][z]) mask_O1[x][y][z] = true;\n                else if (B2[x][y][z]) mask_O2[x][y][z] = true;\n            }\n        }\n    }\n\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int block_id = 0;\n\n    // Form blocks by finding connected components in the masks\n    find_components(mask_C, D, b1, b2, block_id, 0);\n    find_components(mask_O1, D, b1, b2, block_id, 1);\n    find_components(mask_O2, D, b1, b2, block_id, 2);\n\n    // Output results\n    cout << block_id << \"\\n\";\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                cout << b1[x][y][z] << ( (x == D-1 && y == D-1 && z == D-1) ? \"\" : \" \" );\n            }\n        }\n    }\n    cout << \"\\n\";\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                cout << b2[x][y][z] << ( (x == D-1 && y == D-1 && z == D-1) ? \"\" : \" \" );\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\ntypedef long long ll;\nconst ll INF_LL = 1e18;\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int id;\n};\n\nstruct Resident {\n    int x, y;\n};\n\nstruct Station {\n    int x, y;\n};\n\nint main() {\n    // Optimize I/O speed\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) cin >> stations[i].x >> stations[i].y;\n\n    vector<Edge> edges(M);\n    vector<vector<ll>> dist_matrix(N, vector<ll>(N, INF_LL));\n    vector<vector<int>> next_node(N, vector<int>(N, -1));\n    vector<vector<int>> adj_edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) dist_matrix[i][i] = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        ll w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        if (w < dist_matrix[u][v]) {\n            dist_matrix[u][v] = dist_matrix[v][u] = w;\n            next_node[u][v] = v;\n            next_node[v][u] = u;\n            adj_edge_idx[u][v] = adj_edge_idx[v][u] = i;\n        }\n    }\n\n    // Floyd-Warshall to compute all-pairs shortest paths and paths reconstruction info\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (dist_matrix[i][k] == INF_LL) continue;\n            for (int j = 0; j < N; ++j) {\n                if (dist_matrix[k][j] == INF_LL) continue;\n                if (dist_matrix[i][k] + dist_matrix[k][j] < dist_matrix[i][j]) {\n                    dist_matrix[i][j] = dist_matrix[i][k] + dist_matrix[k][j];\n                    next_node[i][j] = next_node[i][k];\n                    adj_edge_idx[i][j] = adj_edge_idx[i][k]; // In case we need the exact edge index\n                    // Note: To correctly find the edge on the path, the next_node strategy is standard.\n                }\n            }\n        }\n    }\n\n    // We need to re-fill adj_edge_idx after Floyd-Warshall to ensure it stores the correct path edges\n    // But the simpler way to reconstruct paths is to use the edge matrix to find which neighbor is on the shortest path.\n    // Let's redefine next_node[i][j] to be the node v such that (i,v) is an edge and dist[i][j] = w(i,v) + dist[v][j].\n    // However, next_node[i][j] = next_node[i][k] already works for path reconstruction.\n    // Let's just update adj_edge_idx to be the direct edge index between i and next_node[i][j].\n\n    vector<Resident> residents(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    vector<vector<double>> res_dist(K, vector<double>(N));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 0; i < N; ++i) {\n            double dx = (double)stations[i].x - residents[k].x;\n            double dy = (double)stations[i].y - residents[k].y;\n            res_dist[k][i] = sqrt(dx * dx + dy * dy);\n        }\n    }\n\n    vector<int> assigned_to(K);\n    vector<multiset<double>> station_dists(N);\n    vector<int> station_count(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int best_i = 0;\n        double min_d = res_dist[k][0];\n        for (int i = 1; i < N; ++i) {\n            if (res_dist[k][i] < min_d) {\n                min_d = res_dist[k][i];\n                best_i = i;\n            }\n        }\n        assigned_to[k] = best_i;\n        station_count[best_i]++;\n        station_dists[best_i].insert(res_dist[k][best_i]);\n    }\n\n    auto get_P2_of_station = [&](int i) {\n        if (station_count[i] == 0) return 0LL;\n        double max_d = *station_dists[i].rbegin();\n        ll p = (ll)ceil(max_d - 1e-9);\n        return p * p;\n    };\n\n    auto get_mst_weight = [&](const vector<int>& counts, const vector<vector<ll>>& dm) {\n        vector<int> A;\n        for (int i = 0; i < N; ++i) {\n            if (i == 0 || counts[i] > 0) A.push_back(i);\n        }\n        if (A.size() <= 1) return 0LL;\n        int n = A.size();\n        vector<ll> min_d(n, INF_LL);\n        vector<bool> visited(n, false);\n        min_d[0] = 0;\n        ll total_w = 0;\n        for (int i = 0; i < n; ++i) {\n            int u = -1;\n            for (int j = 0; j < n; ++j) {\n                if (!visited[j] && (u == -1 || min_d[j] < min_d[u])) u = j;\n            }\n            if (u == -1 || min_d[u] == INF_LL) break;\n            visited[u] = true;\n            total_w += min_d[u];\n            for (int v = 0; v < n; ++v) {\n                if (!visited[v]) {\n                    ll d = dm[A[u]][A[v]];\n                    if (d < min_d[v]) min_d[v] = d;\n                }\n            }\n        }\n        return total_w;\n    };\n\n    ll current_P2 = 0;\n    for (int i = 0; i < N; ++i) current_P2 += get_P2_of_station(i);\n    ll current_W = get_mst_weight(station_count, dist_matrix);\n    ll current_S = current_P2 + current_W;\n\n    vector<int> best_assigned = assigned_to;\n    ll best_S = current_S;\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 127) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n        }\n        iter++;\n\n        int k = uniform_int_distribution<int>(0, K - 1)(rng);\n        int old_i = assigned_to[k];\n        int new_j = uniform_int_distribution<int>(0, N - 1)(rng);\n        if (old_i == new_j) continue;\n\n        bool a_changed = (old_i != 0 && station_count[old_i] == 1) || (new_j != 0 && station_count[new_j] == 0);\n\n        ll old_P2_i = get_P2_of_station(old_i);\n        ll old_P2_j = get_P2_of_station(new_j);\n\n        // Perform movement\n        station_count[old_i]--;\n        station_dists[old_i].erase(station_dists[old_i].find(res_dist[k][old_i]));\n        station_count[new_j]++;\n        station_dists[new_j].insert(res_dist[k][new_j]);\n        assigned_to[k] = new_j;\n\n        ll new_P2_i = get_P2_of_station(old_i);\n        ll new_P2_j = get_P2_of_station(new_j);\n        ll new_P2 = current_P2 - old_P2_i - old_P2_j + new_P2_i + new_P2_j;\n        ll new_W = a_changed ? get_mst_weight(station_count, dist_matrix) : current_W;\n        ll new_S = new_P2 + new_W;\n\n        if (new_S < current_S) {\n            current_S = new_S;\n            current_P2 = new_P2;\n            current_W = new_W;\n            if (current_S < best_S) {\n                best_S = current_S;\n                best_assigned = assigned_to;\n            }\n        } else {\n            // Revert\n            station_count[old_i]++;\n            station_dists[old_i].insert(res_dist[k][old_i]);\n            station_count[new_j]--;\n            station_dists[new_j].erase(station_dists[new_j].find(res_dist[k][new_j]));\n            assigned_to[k] = old_i;\n        }\n    }\n\n    // Reconstruction\n    vector<int> final_assigned = best_assigned;\n    vector<int> final_station_count(N, 0);\n    vector<multiset<double>> final_station_dists(N);\n    for (int k = 0; k < K; ++k) {\n        int i = final_assigned[k];\n        final_station_count[i]++;\n        final_station_dists[i].insert(res_dist[k][i]);\n    }\n\n    vector<int> P(N, 0);\n    for (int i = 0; i < N; ++i) {\n        if (final_station_count[i] > 0) {\n            double max_d = *final_station_dists[i].rbegin();\n            P[i] = (int)ceil(max_d - 1e-9);\n        }\n    }\n\n    vector<int> A;\n    for (int i = 0; i < N; ++i) {\n        if (i == 0 || final_station_count[i] > 0) A.push_back(i);\n    }\n\n    vector<int> B(M, 0);\n    if (A.size() > 1) {\n        int n = A.size();\n        vector<ll> min_d(n, INF_LL);\n        vector<int> parent(n, -1);\n        vector<bool> visited(n, false);\n        min_d[0] = 0;\n        for (int i = 0; i < n; ++i) {\n            int u = -1;\n            for (int j = 0; j < n; ++j) {\n                if (!visited[j] && (u == -1 || min_d[j] < min_d[u])) u = j;\n            }\n            if (u == -1 || min_d[u] == INF_LL) break;\n            visited[u] = true;\n            if (parent[u] != -1) {\n                int start_node = A[parent[u]];\n                int end_node = A[u];\n                int curr = start_node;\n                while (curr != end_node) {\n                    int nxt = next_node[curr][end_node];\n                    // Find the edge between curr and nxt\n                    for (int m = 0; m < M; ++m) {\n                        if ((edges[m].u == curr && edges[m].v == nxt) || (edges[m].u == nxt && edges[m].v == curr)) {\n                            if (edges[m].w == dist_matrix[curr][nxt] || edges[m].w >= 0) { // Check if this edge is actually on the shortest path\n                                // Since it's a simple graph, the first edge we find connecting them is the one\n                                B[m] = 1;\n                                break;\n                            }\n                        }\n                    }\n                    curr = nxt;\n                }\n            }\n            for (int v = 0; v < n; ++v) {\n                if (!visited[v]) {\n                    ll d = dist_matrix[A[u]][A[v]];\n                    if (d < min_d[v]) {\n                        min_d[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << P[i] << (i == N - 1 ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int i = 0; i < M; ++i) cout << B[i] << (i == M - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The problem asks us to transform a random N-tiered pyramid into a min-heap\n * where every ball (x, y) is smaller than its children (x+1, y) and (x+1, y+1).\n * Swaps are allowed only between adjacent balls in 6 directions.\n * \n * Goal: E = 0 (satisfy heap property) and minimize K (swaps), where K <= 10,000.\n * Score: 100,000 - 5K.\n * \n * Approach:\n * A standard heapify (sift-down) algorithm is very efficient (O(M) swaps),\n * where M = N(N+1)/2. For N=30, the maximum number of swaps is roughly 4,500,\n * which guarantees E=0 and a score of at least 100,000 - 5(4500) = 77,500.\n * \n * To improve this, we can use a greedy \"max-violation\" approach.\n * Instead of building the heap in a fixed order, we always pick the most\n * \"severe\" violation (the pair (parent, child) with the largest difference\n * b[parent] - b[child]) and swap them. This is essentially a hill-climbing\n * approach that directly addresses the largest heap property violations.\n * \n * This greedy approach is likely to reduce the total number of swaps K\n * compared to a standard bottom-up heapify, leading to a higher score.\n */\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nstruct Violation {\n    int diff;\n    int x, y;\n    int type; // 0 for child (x+1, y), 1 for child (x+1, y+1)\n\n    bool operator<(const Violation& other) const {\n        return diff < other.diff;\n    }\n};\n\nconst int N = 30;\nint pyramid[N][N];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> pyramid[i][j])) break;\n        }\n    }\n\n    vector<Swap> swaps;\n    priority_queue<Violation> pq;\n\n    // Function to check for a violation at (x, y) and add to pq\n    auto check_violation = [&](int x, int y) {\n        if (x < 0 || x >= N - 1) return;\n        // Check child 1: (x+1, y)\n        if (y <= x + 1 && pyramid[x][y] > pyramid[x + 1][y]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y], x, y, 0});\n        }\n        // Check child 2: (x+1, y+1)\n        if (y + 1 <= x + 1 && pyramid[x][y] > pyramid[x + 1][y + 1]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y + 1], x, y, 1});\n        }\n    };\n\n    // Initialize priority queue with all initial violations\n    for (int x = 0; x < N - 1; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            check_violation(x, y);\n        }\n    }\n\n    // Greedy swap approach\n    while (!pq.empty() && swaps.size() < 10000) {\n        Violation top = pq.top();\n        pq.pop();\n\n        int x = top.x;\n        int y = top.y;\n        int cx = x + 1;\n        int cy = y + top.type;\n\n        // Check if the violation is still valid and has the same difference\n        if (pyramid[x][y] - pyramid[cx][cy] != top.diff) continue;\n\n        // Perform the swap\n        swaps.push_back({x, y, cx, cy});\n        swap(pyramid[x][y], pyramid[cx][cy]);\n\n        // After swap, violations might have changed for:\n        // 1. (x, y) and its children\n        // 2. (cx, cy) and its children\n        // 3. (x, y)'s parents\n        // 4. (cx, cy)'s parents\n        \n        // Re-check (x, y) and its children\n        check_violation(x, y);\n        // Re-check (cx, cy) and its children\n        check_violation(cx, cy);\n        // Re-check parents of (x, y)\n        if (x > 0) {\n            check_violation(x - 1, y - 1);\n            check_violation(x - 1, y);\n        }\n        // Re-check parents of (cx, cy)\n        if (cx > 0) {\n            check_violation(cx - 1, cy - 1);\n            check_violation(cx - 1, cy);\n        }\n    }\n\n    // Output the results\n    cout << swaps.size() << \"\\n\";\n    for (const auto& s : swaps) {\n        cout << s.x1 << \" \" << s.y1 << \" \" << s.x2 << \" \" << s.y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int r, c;\n    bool operator==(const Pos& other) const { return r == other.r && c == other.c; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nint D, N;\nbool is_obstacle[10][10];\nbool is_occupied[10][10];\nint id_at_square[10][10];\nint dist_val[10][10];\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D && !is_obstacle[r][c];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            is_obstacle[i][j] = false;\n            is_occupied[i][j] = false;\n            id_at_square[i][j] = -1;\n            dist_val[i][j] = 1000;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        is_occupied[r][c] = true;\n    }\n\n    Pos entrance = {0, (D - 1) / 2};\n\n    vector<Pos> bfs_order;\n    queue<Pos> q_bfs;\n    q_bfs.push(entrance);\n    dist_val[entrance.r][entrance.c] = 0;\n    \n    vector<vector<bool>> visited_bfs(D, vector<bool>(D, false));\n    visited_bfs[entrance.r][entrance.c] = true;\n\n    while(!q_bfs.empty()){\n        Pos curr = q_bfs.front();\n        q_bfs.pop();\n        if (curr != entrance) bfs_order.push_back(curr);\n\n        for(int i=0; i<4; ++i){\n            int nr = curr.r + dr[i], nc = curr.c + dc[i];\n            if(is_valid(nr, nc) && !visited_bfs[nr][nc]){\n                visited_bfs[nr][nc] = true;\n                dist_val[nr][nc] = dist_val[curr.r][curr.c] + 1;\n                q_bfs.push({nr, nc});\n            }\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    for (int d = 0; d < M; ++d) {\n        int t_d;\n        if (!(cin >> t_d)) break;\n\n        int ideal_dist = 1000;\n        if (t_d < (int)bfs_order.size()) {\n            ideal_dist = dist_val[bfs_order[t_d].r][bfs_order[t_d].c];\n        } else if (!bfs_order.empty()) {\n            ideal_dist = dist_val[bfs_order.back().r][bfs_order.back().c];\n        }\n\n        vector<Pos> reachable_empty;\n        queue<Pos> rq;\n        rq.push(entrance);\n        vector<vector<bool>> visited_reach(D, vector<bool>(D, false));\n        visited_reach[entrance.r][entrance.c] = true;\n\n        while (!rq.empty()) {\n            Pos curr = rq.front();\n            rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                if (is_valid(nr, nc) && !visited_reach[nr][nc] && !is_occupied[nr][nc]) {\n                    visited_reach[nr][nc] = true;\n                    reachable_empty.push_back({nr, nc});\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        vector<Pos> safe_squares;\n        for (auto& s : reachable_empty) {\n            bool safe = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i], nc = s.c + dc[i];\n                if (is_valid(nr, nc) && dist_val[nr][nc] > dist_val[s.r][s.c] && !is_occupied[nr][nc]) {\n                    safe = false;\n                    break;\n                }\n            }\n            if (safe) safe_squares.push_back(s);\n        }\n\n        Pos best_s = {-1, -1};\n        auto pick_best = [&](const vector<Pos>& candidates) {\n            int min_diff = 1000;\n            int max_dist_found = -1;\n            for (auto& s : candidates) {\n                int diff = abs(dist_val[s.r][s.c] - ideal_dist);\n                if (diff < min_diff) {\n                    min_diff = diff;\n                    max_dist_found = dist_val[s.r][s.c];\n                    best_s = s;\n                } else if (diff == min_diff) {\n                    if (dist_val[s.r][s.c] > max_dist_found) {\n                        max_dist_found = dist_val[s.r][s.c];\n                        best_s = s;\n                    }\n                }\n            }\n        };\n\n        if (!safe_squares.empty()) pick_best(safe_squares);\n        else if (!reachable_empty.empty()) pick_best(reachable_empty);\n\n        if (best_s.r == -1) {\n            for(int r=0; r<D; ++r)\n                for(int c=0; c<D; ++c)\n                    if (is_valid(r, c) && !is_occupied[r][c] && !(r == entrance.r && c == entrance.c))\n                        { best_s = {r, c}; goto placed; }\n        }\n        placed:\n\n        is_occupied[best_s.r][best_s.c] = true;\n        id_at_square[best_s.r][best_s.c] = t_d;\n        cout << best_s.r << \" \" << best_s.c << endl;\n    }\n\n    vector<bool> transported(M, false);\n    for (int step = 0; step < M; ++step) {\n        vector<vector<bool>> reach_grid(D, vector<bool>(D, false));\n        queue<Pos> rq;\n        rq.push(entrance);\n        reach_grid[entrance.r][entrance.c] = true;\n        while (!rq.empty()) {\n            Pos curr = rq.front(); rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                if (is_valid(nr, nc) && !reach_grid[nr][nc] && !is_occupied[nr][nc]) {\n                    reach_grid[nr][nc] = true;\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        int best_id = 1e9;\n        Pos best_pos = {-1, -1};\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                int id = id_at_square[r][c];\n                if (id != -1 && !transported[id]) {\n                    bool can_reach = false;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r + dr[i], nc = c + dc[i];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && reach_grid[nr][nc]) {\n                            can_reach = true; break;\n                        }\n                    }\n                    if (can_reach && id < best_id) {\n                        best_id = id;\n                        best_pos = {r, c};\n                    }\n                }\n            }\n        }\n\n        if (best_id != 1e9) {\n            transported[best_id] = true;\n            is_occupied[best_pos.r][best_pos.c] = false;\n            id_at_square[best_pos.r][best_pos.c] = -1;\n            cout << best_pos.r << \" \" << best_pos.c << \"\\n\";\n        } else break;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to represent a given adjacency graph of colors (wards) on an n x n grid,\n * minimizing the number of tiles used for the wards (maximizing the number of color 0 tiles).\n * The adjacencies between any two colors (including color 0) must be identical to the original.\n * Each color must form a connected set of tiles.\n * \n * Since the adjacency graph is planar (derived from a map), and the grid (50x50) is much larger \n * than the number of colors (100), we can use a greedy approach.\n * We place each color one by one using a BFS-based path construction.\n * To maintain the \"identical adjacency\" property, we use a \"safe cell\" condition:\n * a cell is safe for color c if it is currently color 0 and all its non-zero neighbors \n * are colors that c is actually adjacent to in the original map.\n * \n * Algorithm:\n * 1. Construct the adjacency graph G from the input.\n * 2. Use a BFS order starting from color 0 to decide the order of placing colors.\n * 3. For each color c:\n *    a. Identify the set T of colors already placed that c is adjacent to in G.\n *    b. Find a path of \"safe\" cells that connects c to all colors in T.\n *    c. A cell is safe if it's 0 and all its neighbors in the current grid belong to T.\n *    d. Use BFS to find the shortest paths connecting these target colors.\n *    e. Update the grid by coloring these cells with c.\n * 4. Output the resulting grid.\n */\n\nconst int N = 50;\nint grid[N][N];\nint n, m;\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < n && c >= 0 && c < n;\n}\n\n// A cell is safe for color c if it's 0 and its non-0 neighbors are all in the target set T.\nbool is_safe(int r, int c, const set<int>& T) {\n    if (grid[r][c] != 0) return false;\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (is_valid(nr, nc)) {\n            if (grid[nr][nc] != 0) {\n                if (T.find(grid[nr][nc]) == T.end()) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> original_grid(n, vector<int>(n));\n    set<int> adj[105]; // m can be up to 100\n    \n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> original_grid[i][j];\n        }\n    }\n\n    // Build the adjacency graph from the input map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = original_grid[i][j];\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (is_valid(ni, nj)) {\n                    int nc = original_grid[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                        adj[nc].insert(c);\n                    }\n                } else {\n                    // Adjacent to the outside (represented by color 0)\n                    if (c != 0) {\n                        adj[c].insert(0);\n                        adj[0].insert(c);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initialize the output grid with 0\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            grid[i][j] = 0;\n        }\n    }\n\n    // Determine the order of placement using BFS from color 0\n    vector<int> bfs_order;\n    queue<int> q_bfs;\n    q_bfs.push(0);\n    vector<bool> visited_bfs(m + 1, false);\n    visited_bfs[0] = true;\n    while (!q_bfs.empty()) {\n        int u = q_bfs.front();\n        q_bfs.pop();\n        if (u != 0) bfs_order.push_back(u);\n        for (int v : adj[u]) {\n            if (v <= m && v != 0 && !visited_bfs[v]) {\n                visited_bfs[v] = true;\n                q_bfs.push(v);\n            }\n        }\n    }\n    // Add any unvisited colors just in case\n    for (int i = 1; i <= m; ++i) {\n        if (!visited_bfs[i]) bfs_order.push_back(i);\n    }\n\n    set<int> P = {0}; // Colors already placed in the output grid\n\n    for (int c : bfs_order) {\n        // T is the set of colors already in the grid that c must be adjacent to\n        set<int> T;\n        for (int neighbor : adj[c]) {\n            if (P.count(neighbor)) {\n                T.insert(neighbor);\n            }\n        }\n\n        if (T.empty()) continue;\n\n        vector<Pos> Sc; // Set of cells to be assigned color c\n        Pos start_pos = {-1, -1};\n        bool found_start = false;\n        \n        // Find a starting safe cell adjacent to the first color in T\n        int d_first = *T.begin();\n        if (d_first != 0) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (grid[i][j] == d_first) {\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && is_safe(ni, nj, T)) {\n                                start_pos = {ni, nj};\n                                found_start = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            // If the first color is 0, any safe cell adjacent to 0 works\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        bool adj_to_zero = false;\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && grid[ni][nj] == 0) {\n                                adj_to_zero = true;\n                                break;\n                            }\n                        }\n                        if (adj_to_zero) {\n                            start_pos = {i, j};\n                            found_start = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: if no specifically adjacent start cell is found, pick any safe cell\n        if (!found_start) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        start_pos = {i, j};\n                        found_start = true;\n                    }\n                }\n            }\n        }\n\n        if (found_start) {\n            Sc.push_back(start_pos);\n            // Iteratively connect Sc to every other color in T using BFS\n            for (int d : T) {\n                if (d == d_first) continue;\n                \n                // Check if Sc is already adjacent to color d\n                bool already_adj = false;\n                for (auto p : Sc) {\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = p.r + dr[k], nj = p.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            already_adj = true;\n                            break;\n                        }\n                    }\n                    if (already_adj) break;\n                }\n                if (already_adj) continue;\n\n                // BFS to find the shortest path of safe cells to color d\n                queue<Pos> q;\n                vector<vector<int>> dist(n, vector<int>(n, -1));\n                vector<vector<Pos>> parent(n, vector<Pos>(n, {-1, -1}));\n                for (auto p : Sc) {\n                    q.push(p);\n                    dist[p.r][p.c] = 0;\n                }\n                Pos end_pos = {-1, -1};\n                while (!q.empty()) {\n                    Pos curr = q.front(); q.pop();\n                    bool adj_to_d = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = curr.r + dr[k], nj = curr.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            adj_to_d = true; \n                            break;\n                        }\n                    }\n                    if (adj_to_d) {\n                        end_pos = curr;\n                        break;\n                    }\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = curr.r + dr[k], nc = curr.c + dc[k];\n                        if (is_valid(nr, nc) && dist[nr][nc] == -1 && is_safe(nr, nc, T)) {\n                            dist[nr][nc] = dist[curr.r][curr.c] + 1;\n                            parent[nr][nc] = curr;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                // If a path is found, add it to the set Sc\n                if (end_pos.r != -1) {\n                    Pos curr = end_pos;\n                    while (dist[curr.r][curr.c] != 0) {\n                        Sc.push_back(curr);\n                        curr = parent[curr.r][curr.c];\n                    }\n                }\n            }\n            // Update grid with color c\n            for (auto p : Sc) grid[p.r][p.c] = c;\n            P.insert(c);\n        }\n    }\n\n    // Print the resulting map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc025":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to divide N items into D sets of equal total weight as much as possible, \n * given that item weights are unknown and we can only query the balance.\n * \n * Strategy:\n * 1. Estimate item weights: Use a gradient descent-based approach (specifically, Adam optimizer) \n *    to find weights that satisfy the comparison queries. We use the logarithm of weights \n *    (x_i = log(w_i)) to ensure weights are always positive and to handle potential scale issues.\n * 2. Intelligent Queries: In each step, pick items for the balance that make the sums on both sides \n *    as close as possible. This maximizes information gain when the balance result is unexpected.\n * 3. Partitioning: Once weights are estimated, use a Greedy approach combined with local \n *    search (hill climbing) to minimize the variance of the sums of weights in each set.\n */\n\nstruct Query {\n    vector<int> L, R;\n    char res;\n};\n\nint main() {\n    // Speed up input and output\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // x_i stores the log of the estimated weight w_i\n    vector<double> x(N, 0.0);\n    // Adam optimizer parameters\n    vector<double> m(N, 0.0); // First moment\n    vector<double> v(N, 0.0); // Second moment\n    double beta1 = 0.9, beta2 = 0.999, eps = 1e-8, alpha = 0.01;\n    double lambda = 0.01; // Regularization constant\n    vector<Query> queries;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int t_adam = 0; // Time step for Adam\n\n    for (int q = 0; q < Q; ++q) {\n        // Step 1: Select L and R for the query. \n        // We want |sum(L) - sum(R)| to be small.\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n\n        vector<int> best_L, best_R;\n        double best_diff = 1e18;\n\n        // Try multiple randomized greedy attempts to find good L and R\n        for (int attempt = 0; attempt < 40; ++attempt) {\n            vector<int> L, R;\n            double sumL = 0, sumR = 0;\n\n            // Ensure sets are non-empty\n            int i1 = indices[0], i2 = indices[1];\n            L.push_back(i1); sumL += exp(x[i1]);\n            R.push_back(i2); sumR += exp(x[i2]);\n\n            for (int i = 2; i < N; ++i) {\n                int idx = indices[i];\n                double val = exp(x[idx]);\n                double diff_L = abs(sumL + val - sumR);\n                double diff_R = abs(sumL - (sumR + val));\n                double diff_none = abs(sumL - sumR);\n\n                // Greedily decide to add item to L, R, or skip it\n                if (diff_L < diff_R && diff_L < diff_none) {\n                    L.push_back(idx);\n                    sumL += val;\n                } else if (diff_R < diff_none) {\n                    R.push_back(idx);\n                    sumR += val;\n                }\n            }\n\n            double diff = abs(sumL - sumR);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_L = L;\n                best_R = R;\n            }\n        }\n\n        // Output selected sets for the balance query\n        cout << best_L.size() << \" \" << best_R.size();\n        for (int idx : best_L) cout << \" \" << idx;\n        for (int idx : best_R) cout << \" \" << idx;\n        cout << endl;\n\n        char res;\n        if (!(cin >> res)) break;\n        queries.push_back({best_L, best_R, res});\n\n        // Step 2: Update weight estimates using Adam optimizer on recent queries\n        int M_window = min((int)queries.size(), 150);\n        int K_steps = 4;\n        for (int k_step = 0; k_step < K_steps; ++k_step) {\n            t_adam++;\n            vector<double> g(N, 0.0);\n            for (int i = 0; i < M_window; ++i) {\n                const auto& query = queries[queries.size() - 1 - i];\n                double sumL = 0, sumR = 0;\n                for (int idx : query.L) sumL += exp(x[idx]);\n                for (int idx : query.R) sumR += exp(x[idx]);\n                double d = sumL - sumR;\n\n                // Calculate gradient of squared loss function\n                if (query.res == '<') {\n                    if (d > 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '>') {\n                    if (d < 0) {\n                        for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                        for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                    }\n                } else if (query.res == '=') {\n                    for (int idx : query.L) g[idx] += 2 * d * exp(x[idx]);\n                    for (int idx : query.R) g[idx] -= 2 * d * exp(x[idx]);\n                }\n            }\n            // Add regularization gradient to prevent x_i from exploding\n            for (int i = 0; i < N; ++i) g[i] += 2 * lambda * x[i];\n\n            // Adam update step\n            for (int i = 0; i < N; ++i) {\n                m[i] = beta1 * m[i] + (1.0 - beta1) * g[i];\n                v[i] = beta2 * v[i] + (1.0 - beta2) * g[i] * g[i];\n                double m_hat = m[i] / (1.0 - pow(beta1, t_adam));\n                double v_hat = v[i] / (1.0 - pow(beta2, t_adam));\n                x[i] -= alpha * m_hat / (sqrt(v_hat) + eps);\n            }\n        }\n    }\n\n    // Step 3: Final Division\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = exp(x[i]);\n\n    vector<int> d(N);\n    vector<double> set_sum(D, 0.0);\n\n    // Initial division using a greedy approach\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    for (int idx : p) {\n        int best_s = 0;\n        for (int s = 1; s < D; ++s) {\n            if (set_sum[s] < set_sum[best_s]) best_s = s;\n        }\n        d[idx] = best_s;\n        set_sum[best_s] += w[idx];\n    }\n\n    // Refine partition using hill climbing to minimize sum of squares (proportional to variance)\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            int old_s = d[i];\n            for (int new_s = 0; new_s < D; ++new_s) {\n                if (old_s == new_s) continue;\n                \n                double old_sum_sq = 0;\n                for (int s = 0; s < D; ++s) old_sum_sq += set_sum[s] * set_sum[s];\n                \n                double temp_sum_old = set_sum[old_s] - w[i];\n                double temp_sum_new = set_sum[new_s] + w[i];\n                double new_sum_sq_val = old_sum_sq - set_sum[old_s]*set_sum[old_s] - set_sum[new_s]*set_sum[new_s] + temp_sum_old*temp_sum_old + temp_sum_new*temp_sum_new;\n                \n                // If moving item i to new_s reduces the sum of squared set weights, accept move\n                if (new_sum_sq_val < old_sum_sq - 1e-7) {\n                    set_sum[old_s] -= w[i];\n                    set_sum[new_s] += w[i];\n                    d[i] = new_s;\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Output the final division\n    for (int i = 0; i < N; ++i) cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <deque>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to remove boxes in order 1, 2, ..., n.\n * - A box can be removed (Operation 2, cost 0) only if it is at the top of its stack.\n * - If a box v is not at the top, we must move all boxes above it to another stack (Operation 1, cost k+1).\n * - Our goal is to minimize total energy (sum of k+1).\n * \n * Key Insight:\n * - To minimize future costs, we want stacks to be in \"descending order\" from bottom to top.\n * - If a stack is [..., 5, 4, 3, 2, 1] (top is 1), then after removing 1, 2 becomes the top, then 3, etc.\n * - This way, many boxes can be removed using Operation 2 (cost 0) instead of Operation 1.\n * - A \"violation\" is defined as a pair (x, y) where x is below y but x < y.\n * - We use a greedy approach: when moving boxes above v to another stack, we pick the stack\n *   that minimizes the number of violations in the resulting stack, with a tie-breaker\n *   of minimizing the total stack size.\n * \n * Complexity:\n * - n=200, m=10.\n * - For each of the n boxes, we check m-1 possible target stacks.\n * - Each check takes O(n) to count violations.\n * - Total complexity: O(n^2 * m), which is ~400,000 operations. Well within 2.0s.\n */\n\n// Function to count the number of violations (x < y where x is below y) in a stack\nint count_violations(const deque<int>& s) {\n    int violations = 0;\n    for (size_t i = 0; i + 1 < s.size(); ++i) {\n        if (s[i] < s[i + 1]) {\n            violations++;\n        }\n    }\n    return violations;\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    // stacks[i] stores the boxes in stack i (bottom to top)\n    vector<deque<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n\n    // Record all operations to output at the end\n    // (v, 0) for Operation 2, (v, i) for Operation 1 (i is 1-indexed)\n    vector<pair<int, int>> operations;\n\n    for (int v = 1; v <= n; ++v) {\n        int current_stack_idx = -1;\n        int v_pos = -1;\n\n        // Step 1: Find the current position and stack of box v\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                    current_stack_idx = i;\n                    v_pos = j;\n                    break;\n                }\n            }\n            if (current_stack_idx != -1) break;\n        }\n\n        // Step 2: If v is not at the top, move all boxes above it to another stack\n        if (v_pos < (int)stacks[current_stack_idx].size() - 1) {\n            // The box immediately above v is our target for Operation 1\n            int u_idx = v_pos + 1;\n            int u = stacks[current_stack_idx][u_idx];\n\n            // Collect all boxes to be moved (from u to the current top)\n            vector<int> to_move;\n            for (int k = u_idx; k < (int)stacks[current_stack_idx].size(); ++k) {\n                to_move.push_back(stacks[current_stack_idx][k]);\n            }\n\n            // Greedy decision: Which stack to move these boxes to?\n            int best_target_idx = -1;\n            long long min_cost = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == current_stack_idx) continue;\n\n                // Simulate adding the moved part to stack i\n                deque<int> simulated_stack = stacks[i];\n                for (int val : to_move) {\n                    simulated_stack.push_back(val);\n                }\n\n                // Cost function: prioritize minimizing violations, then minimize stack size\n                // Large weight for violations to ensure it is the primary objective\n                long long cost = (long long)count_violations(simulated_stack) * 10000LL + (long long)simulated_stack.size();\n\n                if (best_target_idx == -1 || cost < min_cost) {\n                    min_cost = cost;\n                    best_target_idx = i;\n                }\n            }\n\n            // Perform the chosen move\n            // Remove the moved boxes from the current stack\n            for (size_t k = 0; k < to_move.size(); ++k) {\n                stacks[current_stack_idx].pop_back();\n            }\n            // Add the moved boxes to the target stack\n            for (int val : to_move) {\n                stacks[best_target_idx].push_back(val);\n            }\n\n            // Record Operation 1 (u, target_stack_1_indexed)\n            operations.push_back({u, best_target_idx + 1});\n        }\n\n        // Step 3: v is now at the top of its stack, remove it using Operation 2\n        operations.push_back({v, 0});\n        stacks[current_stack_idx].pop_back();\n    }\n\n    // Step 4: Output the operations\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize the average dirtiness over an infinite period.\n * The average dirtiness of a square (i, j) is given by (d_{i,j} * (T_{i,j} - 1) / 2),\n * where T_{i,j} is the interval between visits to square (i, j).\n * If we have a cleaning route of length L, and m_{i,j} is the number of visits to \n * square (i, j), then T_{i,j} = L / m_{i,j}.\n * The total average dirtiness is S = sum_{i,j} [d_{i,j} * (L/m_{i,j} - 1) / 2].\n * S = (L/2) * sum_{i,j} (d_{i,j}/m_{i,j}) - (1/2) * sum_{i,j} d_{i,j}.\n * To minimize this, the frequency f_{i,j} = m_{i,j}/L should be proportional to sqrt(d_{i,j}).\n *\n * Algorithm:\n * 1. Generate an initial cleaning route using DFS that visits all reachable squares \n *    and returns to (0, 0). This route ensures each edge is traversed twice.\n * 2. Use a greedy approach to add \"detours\" to this route. A detour on edge (u, v) \n *    consists of moves u -> v -> u -> v, which increases m_u and m_v by 1 and \n *    increases the total length L by 2.\n * 3. The benefit (change in S) of adding a detour to edge (u, v) is:\n *    Delta S = -((L/2) + 1) * (d_u / (m_u * (m_u + 1)) + d_v / (m_v * (m_v + 1))) + Sigma,\n *    where Sigma = sum_{i,j} (d_{i,j}/m_{i,j}).\n * 4. We use a priority queue to greedily select the edge that provides the most \n *    negative Delta S, updating Sigma and L as we add detours, until the length \n *    reaches 10^5 or no more improvements are possible.\n */\n\nstruct Square {\n    int r, c;\n};\n\nint N;\nvector<string> h_walls;\nvector<string> v_walls;\nvector<vector<int>> d;\nbool visited[40][40];\nvector<Square> path;\nvector<char> move_chars;\n\n// DFS to generate a route that visits all reachable squares and returns to (0,0).\nvoid dfs(int r, int c) {\n    visited[r][c] = true;\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n    char move_c[] = {'R', 'D', 'L', 'U'};\n    char back_c[] = {'L', 'U', 'R', 'D'};\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {\n            bool wall = false;\n            if (i == 0) wall = (v_walls[r][c] == '1'); // Right\n            else if (i == 1) wall = (h_walls[r][c] == '1'); // Down\n            else if (i == 2) wall = (v_walls[nr][nc] == '1'); // Left\n            else if (i == 3) wall = (h_walls[nr][nc] == '1'); // Up\n\n            if (!wall) {\n                move_chars.push_back(move_c[i]);\n                path.push_back({nr, nc});\n                dfs(nr, nc);\n                move_chars.push_back(back_c[i]);\n                path.push_back({r, c});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[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    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited[i][j] = false;\n        }\n    }\n\n    path.push_back({0, 0});\n    dfs(0, 0);\n\n    int L = move_chars.size();\n    vector<int> m(N * N, 0);\n    for (int i = 0; i < L; ++i) {\n        m[path[i].r * N + path[i].c]++;\n    }\n\n    double sigma = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sigma += (double)d[i][j] / m[i * N + j];\n        }\n    }\n\n    auto get_delta = [&](int k, int current_L) {\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double term1 = (double)d[u / N][u % N] / (m[u] * (m[u] + 1.0));\n        double term2 = (double)d[v / N][v % N] / (m[v] * (m[v] + 1.0));\n        double delta = -(current_L / 2.0 + 1.0) * (term1 + term2) + sigma;\n        return delta;\n    };\n\n    priority_queue<pair<double, int>> pq;\n    for (int k = 0; k < L; ++k) {\n        pq.push({-get_delta(k, L), k});\n    }\n\n    vector<int> detours(L, 0);\n    int current_L = L;\n\n    while (current_L + 2 <= 100000 && !pq.empty()) {\n        pair<double, int> top = pq.top();\n        pq.pop();\n\n        int k = top.second;\n        double neg_delta = top.first;\n\n        double current_delta = get_delta(k, current_L);\n        if (current_delta > -1e-9) break; \n\n        // Lazy update check\n        if (abs(neg_delta - (-current_delta)) > 1e-7) {\n            pq.push({-current_delta, k});\n            continue;\n        }\n\n        // Add detour\n        detours[k]++;\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double du = (double)d[u / N][u % N];\n        double dv = (double)d[v / N][v % N];\n        double mu = (double)m[u];\n        double mv = (double)m[v];\n\n        sigma = sigma - du / mu - dv / mv + du / (mu + 1.0) + dv / (mv + 1.0);\n        m[u]++;\n        m[v]++;\n        current_L += 2;\n\n        pq.push({-get_delta(k, current_L), k});\n    }\n\n    string final_route = \"\";\n    for (int k = 0; k < L; ++k) {\n        final_route += move_chars[k];\n        if (detours[k] > 0) {\n            char move_k = move_chars[k];\n            char rev_move_k;\n            if (move_k == 'R') rev_move_k = 'L';\n            else if (move_k == 'L') rev_move_k = 'R';\n            else if (move_k == 'U') rev_move_k = 'D';\n            else rev_move_k = 'U';\n\n            for (int i = 0; i < detours[k]; ++i) {\n                final_route += rev_move_k;\n                final_route += move_k;\n            }\n        }\n    }\n\n    cout << final_route << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Kakizome Taikai\n * Strategy:\n * 1. Precompute distances and overlaps between strings.\n * 2. Precompute the minimum cost to add a suffix of each target string t[k]\n *    starting from any (r_s, c_s) and ending at any (r_e, c_e).\n *    Since the number of states (M * 5 * N^2 * N^2) is around 5 * 10^7,\n *    we store it in an unsigned short array of about 100 MB.\n * 3. Use Simulated Annealing to optimize the order in which we attempt to cover the target strings.\n *    The scoring function for SA prioritizes covering all M strings (K=M) \n *    and then minimizes the total cost T.\n * 4. Reconstruct the final path using the best order found.\n */\n\nconst int MAX_N = 15;\nconst int MAX_M = 200;\nconst int MAX_S = 225;\nconst unsigned short INF = 32767;\n\nint N, M;\nint si, sj;\nstring A[MAX_N];\nstring t[MAX_M];\nint dist[MAX_N][MAX_N][MAX_N][MAX_N];\nint overlap_mat[MAX_M][MAX_M];\n\n// pre[k][p][r_s*N+c_s][r_e*N+c_e]\nunsigned short pre[MAX_M][5][MAX_S][MAX_S];\n\nvoid precompute() {\n    for (int r1 = 0; r1 < N; ++r1)\n        for (int c1 = 0; c1 < N; ++c1)\n            for (int r2 = 0; r2 < N; ++r2)\n                for (int c2 = 0; c2 < N; ++c2)\n                    dist[r1][c1][r2][c2] = abs(r1 - r2) + abs(c1 - c2) + 1;\n\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            int max_ov = 0;\n            for (int len = 1; len <= 4; ++len) {\n                if (t[i].substr(5 - len) == t[j].substr(0, len)) {\n                    max_ov = len;\n                }\n            }\n            overlap_mat[i][j] = max_ov;\n        }\n    }\n\n    for (int k = 0; k < M; ++k) {\n        for (int p = 0; p < 5; ++p) {\n            string suffix = t[k].substr(p);\n            int L = suffix.length();\n            for (int rs = 0; rs < N; ++rs) {\n                for (int cs = 0; cs < N; ++cs) {\n                    vector<vector<unsigned short>> dp(L + 1, vector<unsigned short>(N * N, INF));\n                    // Base case: first character of suffix\n                    for (int r = 0; r < N; ++r) {\n                        for (int c = 0; c < N; ++c) {\n                            if (A[r][c] == suffix[0]) {\n                                if (L == 1) {\n                                    // if L=1, dp[1][r][c] is already the cost to type first char.\n                                    // But we need it relative to (rs, cs).\n                                    // To simplify, let's just let dp[1][r][c] be the movement + 1.\n                                }\n                                dp[1][r * N + c] = dist[rs][cs][r][c];\n                            }\n                        }\n                    }\n\n                    for (int idx = 2; idx <= L; ++idx) {\n                        for (int curr = 0; curr < N * N; ++curr) {\n                            int r = curr / N, c = curr % N;\n                            if (A[r][c] == suffix[idx - 1]) {\n                                for (int prev = 0; prev < N * N; ++prev) {\n                                    if (dp[idx - 1][prev] != INF) {\n                                        int pr = prev / N, pc = prev % N;\n                                        int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                        if (d < dp[idx][curr]) dp[idx][curr] = (unsigned short)d;\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    for (int re = 0; re < N; ++re) {\n                        for (int ce = 0; ce < N; ++ce) {\n                            if (L == 0) pre[k][p][rs * N + cs][re * N + ce] = 0;\n                            else pre[k][p][rs * N + cs][re * N + ce] = dp[L][re * N + ce];\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nstruct EvalResult {\n    long long score;\n    int total_cost;\n    int covered_count;\n    vector<pair<int, int>> sequence;\n};\n\nint get_overlap(const string& S, const string& target) {\n    int max_ov = 0;\n    int len_s = S.length();\n    int len_t = target.length();\n    for (int len = 1; len <= min(4, min(len_s, len_t - 1)); ++len) {\n        if (S.substr(len_s - len) == target.substr(0, len)) {\n            max_ov = len;\n        }\n    }\n    // The problem says overlap is suffix of S and prefix of target.\n    // Since target length is 5, the prefix can be up to 4 chars.\n    // But a 5-char overlap means the target is already a substring.\n    // However, the problem states the target string is length 5.\n    // A 5-char overlap would only happen if target is exactly S.suffix(5).\n    // Let's check len=4, 3, 2, 1.\n    return max_ov;\n}\n\n// More robust overlap\nint get_overlap_robust(const string& S, const string& target) {\n    int max_ov = 0;\n    int s_len = S.length();\n    int t_len = target.length();\n    for (int len = 1; len <= 4; ++len) {\n        if (len <= s_len && len < t_len) {\n            if (S.substr(s_len - len) == target.substr(0, len)) {\n                max_ov = len;\n            }\n        }\n    }\n    return max_ov;\n}\n\nEvalResult evaluate(const vector<int>& order) {\n    string S = \"\";\n    int curr_r = si, curr_c = sj;\n    int cost = 0;\n    int covered_count = 0;\n    vector<bool> covered(M, false);\n    vector<pair<int, int>> sequence;\n\n    for (int k : order) {\n        if (covered[k]) continue;\n\n        int p = get_overlap_robust(S, t[k]);\n        string suffix = t[k].substr(p);\n        \n        int best_cost = 30000;\n        int best_r = -1, best_c = -1;\n        \n        int rs_idx = curr_r * N + curr_c;\n        for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n            if (pre[k][p][rs_idx][re_idx] < best_cost) {\n                best_cost = pre[k][p][rs_idx][re_idx];\n                best_r = re_idx / N;\n                best_c = re_idx % N;\n            }\n        }\n\n        if (best_r == -1) continue;\n\n        cost += best_cost;\n        for (int i = 0; i < suffix.length(); ++i) {\n            // This is tricky: we need to find the exact path to add to S.\n            // But for SA, we only need the cost and end position.\n            // We'll reconstruct the string S in a simpler way for SA.\n        }\n        // To keep SA fast, we won't build the full S, just track its end.\n        // But we need to know which strings are covered. \n        // Let's just build S. It's not that slow.\n        // Actually, to find which strings are covered, we need the characters.\n        // Let's use a simplified approach for SA.\n        // Since we only need to know if t[j] is a substring, and strings have len 5:\n        // A new t[j] can only be formed if it overlaps with the current S and the added suffix.\n        // Let's just build the added string characters. \n        // We can precompute the path if needed, but let's see.\n        \n        // Wait, a better way: instead of building S, let's just build the *suffix*\n        // that we actually added.\n        \n        // For simplicity, we'll find the path using the DP.\n        // However, doing this in evaluate is too slow.\n        // Let's just track the last 4 characters of S.\n        \n        // Re-calculating S in evaluate:\n        // To make it fast, we need to know what characters were added.\n        // Instead of the full path, let's just track the last 4 chars of S.\n        // But that's not enough to check if a *new* t[j] is covered.\n        // A new t[j] could be covered if it's entirely within the new suffix, \n        // or if it overlaps with the old S.\n        \n        // Let's use a simpler SA: only track cost and covered_count.\n        // To find covered_count, we'll just assume every string is covered in order.\n        // That's not correct. Let's build S.\n        // To build S without full path, we can precompute the added characters.\n        // But the path can be different for different (rs, cs, re, ce).\n        // Let's just use the current get_min_cost_to_add to build the string.\n    }\n    return {0, 0, 0, {}};\n}\n\n// Due to the complexity of the evaluate function, let's use a simpler greedy\n// and then optimize it with SA. The key is a very efficient evaluate.\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    precompute();\n\n    // Since the SA with full string building is slow, let's use a greedy\n    // with a bit of randomness and several restarts.\n\n    auto solve = [&]() {\n        string S = \"\";\n        int curr_r = si, curr_c = sj;\n        int total_cost = 0;\n        vector<bool> covered(M, false);\n        int covered_count = 0;\n        vector<pair<int, int>> final_path;\n\n        while (covered_count < M && final_path.size() < 5000) {\n            int best_k = -1;\n            int best_p = -1;\n            int best_r = -1, best_c = -1;\n            int best_cost = 1e9;\n            double best_ratio = 1e18;\n\n            for (int k = 0; k < M; ++k) {\n                if (covered[k]) continue;\n                int p = get_overlap_robust(S, t[k]);\n                int rs_idx = curr_r * N + curr_c;\n                \n                // We need to find the (re, ce) that minimizes pre[k][p][rs_idx][re_idx]\n                // but also considers how many new strings are covered.\n                // For speed, let's just pick the one with minimum cost.\n                int min_c = 1e9;\n                int min_re = -1, min_ce = -1;\n                for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n                    if (pre[k][p][rs_idx][re_idx] < min_c) {\n                        min_c = pre[k][p][rs_idx][re_idx];\n                        min_re = re_idx / N;\n                        min_ce = re_idx % N;\n                    }\n                }\n\n                if (min_re == -1) continue;\n\n                // To correctly calculate newly_covered, we need the actual added characters.\n                // Since we don't have the path in 'pre', we must reconstruct it.\n                // But we can only do this for the *best* k.\n                \n                // For now, let's use a simple ratio: min_c / (1.0 + epsilon)\n                double ratio = (double)min_c; \n                if (ratio < best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    best_p = p;\n                    best_r = min_re;\n                    best_c = min_ce;\n                    best_cost = min_c;\n                }\n            }\n\n            if (best_k == -1) break;\n\n            // Reconstruct path for best_k\n            string suffix = t[best_k].substr(best_p);\n            int L = suffix.length();\n            vector<pair<int, int>> path;\n            int tr = best_r, tc = best_c;\n            \n            // Use DP to find the path\n            vector<vector<int>> dp(L + 1, vector<int>(N * N, 1e9));\n            vector<vector<int>> parent(L + 1, vector<int>(N * N, -1));\n            \n            // Re-run the DP for the specific suffix and start pos\n            int rs_idx = curr_r * N + curr_c;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (A[r][c] == suffix[0]) {\n                        dp[1][r * N + c] = dist[curr_r][curr_c][r][c];\n                    }\n                }\n            }\n            for (int idx = 2; idx <= L; ++idx) {\n                for (int curr = 0; curr < N * N; ++curr) {\n                    int r = curr / N, c = curr % N;\n                    if (A[r][c] == suffix[idx - 1]) {\n                        for (int prev = 0; prev < N * N; ++prev) {\n                            if (dp[idx - 1][prev] != 1e9) {\n                                int pr = prev / N, pc = prev % N;\n                                int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                if (d < dp[idx][curr]) {\n                                    dp[idx][curr] = d;\n                                    parent[idx][curr] = prev;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int cur_idx = best_r * N + best_c;\n            for (int i = L; i >= 1; --i) {\n                path.push_back({cur_idx / N, cur_idx % N});\n                cur_idx = parent[i][cur_idx];\n            }\n            reverse(path.begin(), path.end());\n\n            string added_chars = \"\";\n            for (auto p_idx : path) added_chars += A[p_idx.first][p_idx.second];\n            \n            S += added_chars;\n            for (auto p_idx : path) final_path.push_back(p_idx);\n            total_cost += best_cost;\n            curr_r = best_r;\n            curr_c = best_c;\n\n            for (int i = 0; i < M; ++i) {\n                if (!covered[i] && S.find(t[i]) != string::npos) {\n                    covered[i] = true;\n                    covered_count++;\n                }\n            }\n        }\n\n        for (auto p_idx : final_path) cout << p_idx.first << \" \" << p_idx.second << \"\\n\";\n    };\n\n    solve();\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The problem asks to identify all squares (i, j) with oil reserves v(i, j) > 0.\n * We have three operations:\n * 1. Drill: Costs 1, reveals exact v(i, j).\n * 2. Divine: Costs 1/sqrt(|S|), returns noisy sum of v(S).\n * 3. Guess: Costs 1, identifies all v(i, j) > 0.\n * \n * The operational limit is 2 * N^2. For N=20, this is 800.\n * \n * STRATEGY:\n * A direct and robust strategy is to drill every square in the N x N island.\n * Total drills: N^2.\n * Total guesses: 1.\n * Total operations: N^2 + 1, which is <= 2 * N^2 for N >= 1.\n * \n * This strategy is guaranteed to find all oil-containing squares because \n * drilling provides exact values.\n */\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n\n    // Read initial parameters: island size, number of fields, and error parameter\n    if (!(cin >> N >> M >> eps)) {\n        return 0;\n    }\n\n    // Read field shapes. These are not required for the N^2 drill strategy.\n    for (int m = 0; m < M; ++m) {\n        int d;\n        if (!(cin >> d)) break;\n        for (int i = 0; i < d; ++i) {\n            int r, c;\n            if (!(cin >> r >> c)) break;\n        }\n    }\n\n    // List to store all squares discovered to have oil\n    vector<pair<int, int>> oil_squares;\n\n    // Drill every square (i, j) from (0,0) to (N-1, N-1)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // Command to drill square (i, j)\n            // Using endl ensures the output is flushed to the judge\n            cout << \"q 1 \" << i << \" \" << j << endl;\n\n            int v;\n            // Read the exact revealed value v(i, j)\n            if (!(cin >> v)) {\n                return 0;\n            }\n\n            // If v(i, j) is greater than 0, square (i, j) is identified as having oil\n            if (v > 0) {\n                oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // After drilling all squares, we know the exact set of oil-containing squares.\n    // Output the final guess in the specified format.\n    cout << \"a \" << oil_squares.size();\n    for (const auto& sq : oil_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n\n    // Read the final response from the judge (1 if correct, 0 if not)\n    int response;\n    if (!(cin >> response)) {\n        return 0;\n    }\n\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to minimize the total cost: 100 * area shortfall + partition change cost.\n * Partition change cost is proportional to the length of partition segments that change between days.\n * \n * Strategy:\n * 1. A robust strategy is to use either a single column of full-width rectangles or a \n *    two-column layout of rectangles.\n * 2. In a two-column layout, we pick a split index 'n1' and a width 'w'.\n *    - Column 1: Rectangles 0 to n1-1 with width 'w'.\n *    - Column 2: Rectangles n1 to N-1 with width 'W-w'.\n * 3. The vertical boundary at x=w is kept constant to incur zero partition cost.\n * 4. For each column, we use Dynamic Programming to find the optimal y-coordinates for \n *    the horizontal boundaries to maximize shared boundaries with the previous day,\n *    which minimizes the partition change cost.\n * 5. The error in previous attempts was a potential division by zero in the configuration\n *    search and some indexing issues.\n */\n\nint W, D, N;\nvector<vector<int>> a;\n\n// solve_dp computes the optimal y-coordinates for the boundaries in a single column.\nvoid solve_dp(int n, int width, const vector<int>& areas, const vector<int>& prev_y, vector<int>& res_y) {\n    res_y.assign(n + 1, 0);\n    res_y[0] = 0;\n    res_y[n] = W;\n    if (n <= 1) return;\n\n    vector<int> H(n);\n    for (int k = 0; k < n; ++k) H[k] = (areas[k] + width - 1) / width;\n\n    vector<int> PreH(n + 1, 0);\n    for (int k = 0; k < n; ++k) PreH[k + 1] = PreH[k] + H[k];\n\n    vector<int> SufH(n + 1, 0);\n    for (int k = n - 1; k >= 0; --k) SufH[k] = SufH[k + 1] + H[k];\n\n    vector<bool> is_in_S_prev(W + 1, false);\n    for (int k = 1; k < n; ++k) {\n        if (prev_y[k] >= 0 && prev_y[k] <= W)\n            is_in_S_prev[prev_y[k]] = true;\n    }\n\n    // dp[k][y] = max shared boundaries in {y_{d,1}, ..., y_{d,k}} with y_{d,k} = y.\n    // k ranges from 0 to n-1. Boundary 0 is always at y=0.\n    vector<vector<int>> dp(n, vector<int>(W + 1, -1000000000));\n    vector<vector<int>> parent(n, vector<int>(W + 1, -1));\n\n    dp[0][0] = 0;\n\n    for (int k = 1; k < n; ++k) {\n        // Prefix max optimization to make transitions O(1)\n        vector<int> pref_max(W + 1, -1000000000);\n        vector<int> pref_max_idx(W + 1, -1);\n        int cur_max = -1000000000;\n        int cur_idx = -1;\n        for (int i = 0; i <= W; ++i) {\n            if (dp[k - 1][i] > cur_max) {\n                cur_max = dp[k - 1][i];\n                cur_idx = i;\n            }\n            pref_max[i] = cur_max;\n            pref_max_idx[i] = cur_idx;\n        }\n\n        for (int y = PreH[k]; y <= W - SufH[k]; ++y) {\n            int max_y_prev = y - H[k - 1];\n            if (max_y_prev >= 0) {\n                int val = pref_max[max_y_prev];\n                if (val > -500000000) {\n                    dp[k][y] = val + (is_in_S_prev[y] ? 1 : 0);\n                    parent[k][y] = pref_max_idx[max_y_prev];\n                }\n            }\n        }\n    }\n\n    int best_y = -1, max_val = -1000000000;\n    for (int y = PreH[n - 1]; y <= W - SufH[n - 1]; ++y) {\n        if (dp[n - 1][y] > max_val) {\n            max_val = dp[n - 1][y];\n            best_y = y;\n        }\n    }\n\n    if (best_y != -1) {\n        res_y[n - 1] = best_y;\n        for (int k = n - 1; k >= 1; --k) {\n            res_y[k - 1] = parent[k][res_y[k]];\n        }\n    } else {\n        // Fallback if no valid y found\n        for (int k = 1; k < n; ++k) res_y[k] = PreH[k];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> W >> D >> N)) return 0;\n    a.assign(D, vector<int>(N));\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i][j];\n        }\n    }\n\n    // Find best (n1, w) configuration\n    int best_n1 = N, best_w = W;\n    bool found = false;\n    for (int w = 1; w < W; ++w) {\n        for (int n1 = 1; n1 < N; ++n1) {\n            bool ok = true;\n            for (int d = 0; d < D; ++d) {\n                long long h1 = 0;\n                for (int k = 0; k < n1; ++k) h1 += (a[d][k] + w - 1) / w;\n                long long h2 = 0;\n                for (int k = n1; k < N; ++k) h2 += (a[d][k] + (W - w) - 1) / (W - w);\n                if (h1 > W || h2 > W) { ok = false; break; }\n            }\n            if (ok) {\n                best_n1 = n1;\n                best_w = w;\n                found = true;\n                goto configuration_found;\n            }\n        }\n    }\n    configuration_found:;\n\n    vector<vector<int>> col1_y(D), col2_y(D);\n\n    for (int d = 0; d < D; ++d) {\n        if (best_n1 == N || best_n1 == 0) {\n            vector<int> prev_y = (d == 0) ? vector<int>(N + 1, -1) : col1_y[d - 1];\n            solve_dp(N, W, a[d], prev_y, col1_y[d]);\n        } else {\n            // Column 1 (0 to n1-1)\n            vector<int> areas1;\n            for (int k = 0; k < best_n1; ++k) areas1.push_back(a[d][k]);\n            vector<int> prev_y1 = (d == 0) ? vector<int>(best_n1 + 1, -1) : col1_y[d - 1];\n            solve_dp(best_n1, best_w, areas1, prev_y1, col1_y[d]);\n\n            // Column 2 (n1 to N-1)\n            vector<int> areas2;\n            for (int k = best_n1; k < N; ++k) areas2.push_back(a[d][k]);\n            vector<int> prev_y2 = (d == 0) ? vector<int>(N - best_n1 + 1, -1) : col2_y[d - 1];\n            solve_dp(N - best_n1, W - best_w, areas2, prev_y2, col2_y[d]);\n        }\n    }\n\n    // Output results\n    for (int d = 0; d < D; ++d) {\n        if (best_n1 == N || best_n1 == 0) {\n            for (int k = 0; k < N; ++k) {\n                cout << col1_y[d][k] << \" \" << 0 << \" \" << col1_y[d][k + 1] << \" \" << W << \"\\n\";\n            }\n        } else {\n            // Column 1\n            for (int k = 0; k < best_n1; ++k) {\n                cout << col1_y[d][k] << \" \" << 0 << \" \" << col1_y[d][k + 1] << \" \" << best_w << \"\\n\";\n            }\n            // Column 2\n            for (int k = best_n1; k < N; ++k) {\n                cout << col2_y[d][k - best_n1] << \" \" << best_w << \" \" << col2_y[d][k - best_n1 + 1] << \" \" << W << \"\\n\";\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\nlong long a[N][N];\nlong long s[M][3][3];\nlong long b[N][N];\n\nstruct Operation {\n    int m, p, q;\n};\n\nOperation slots[K];\nbool occupied[K];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in, k_in;\n    if (!(cin >> n_in >> m_in >> k_in)) return 0;\n\n    // Input initial board\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    // Input stamps\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 >> s[m][i][j];\n\n    // Initialize board and current score\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            b[i][j] = a[i][j];\n\n    long long current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            current_score += b[i][j] % P;\n\n    mt19937_64 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    long long best_score = current_score;\n    vector<Operation> best_ops;\n    for (int i = 0; i < K; ++i) occupied[i] = false;\n\n    // SA parameters\n    double T_start = 1e9;\n    double T_end = 1e-1;\n\n    // Pre-allocate buffers to speed up loop\n    bool is_aff[N][N];\n    pair<int, int> affected[18];\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.85) break; // Leave time for final output\n\n        double T = T_start * pow(T_end / T_start, elapsed / 1.85);\n\n        int i = rng() % K;\n\n        if (occupied[i]) {\n            // Decide between REMOVE or MODIFY\n            int move_type = rng() % 100;\n            if (move_type < 30) { // REMOVE move\n                int m = slots[i].m;\n                int p = slots[i].p;\n                int q = slots[i].q;\n\n                long long delta = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v - s[m][di][dj];\n                        delta += (new_v % P) - (old_v % P);\n                    }\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int r = p + di, c = q + dj;\n                            b[r][c] -= s[m][di][dj];\n                        }\n                    }\n                    occupied[i] = false;\n                    current_score += delta;\n                }\n            } else { // MODIFY move\n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n                int m_old = slots[i].m;\n                int p_old = slots[i].p;\n                int q_old = slots[i].q;\n\n                if (m_new == m_old && p_new == p_old && q_new == q_old) continue;\n\n                // Identify union of cells affected by old and new stamp\n                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) is_aff[r][c] = false;\n                int aff_cnt = 0;\n\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_old + di, c = q_old + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n\n                long long delta = 0;\n                for (int k = 0; k < aff_cnt; ++k) {\n                    int r = affected[k].first, c = affected[k].second;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v;\n                    if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                        new_v -= s[m_old][r - p_old][c - q_old];\n                    if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                        new_v += s[m_new][r - p_new][c - q_new];\n                    delta += (new_v % P) - (old_v % P);\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int k = 0; k < aff_cnt; ++k) {\n                        int r = affected[k].first, c = affected[k].second;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v;\n                        if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                            new_v -= s[m_old][r - p_old][c - q_old];\n                        if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                            new_v += s[m_new][r - p_new][c - q_new];\n                        b[r][c] = new_v;\n                    }\n                    slots[i] = {m_new, p_new, q_new};\n                    current_score += delta;\n                }\n            }\n        } else { // ADD move\n            int m_new = rng() % M;\n            int p_new = rng() % (N - 2);\n            int q_new = rng() % (N - 2);\n\n            long long delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int r = p_new + di, c = q_new + dj;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v + s[m_new][di][dj];\n                    delta += (new_v % P) - (old_v % P);\n                }\n            }\n\n            if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        b[r][c] += s[m_new][di][dj];\n                    }\n                }\n                slots[i] = {m_new, p_new, q_new};\n                occupied[i] = true;\n                current_score += delta;\n            }\n        }\n\n        // Update best known solution\n        if (current_score > best_score) {\n            best_score = current_score;\n            best_ops.clear();\n            for (int k = 0; k < K; ++k) {\n                if (occupied[k]) best_ops.push_back(slots[k]);\n            }\n        }\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/*\nProblem Analysis:\n- The goal is to dispatch N^2 = 25 containers from specific Dispatch Gates.\n- Containers must be dispatched in a specific order: 0, 1, ..., 24.\n- The scoring favors minimizing the total turns (M0), the number of inversions (M1),\n  wrong dispatch gates (M2), and undispatched containers (M3).\n- To minimize M1, M2, and M3, the most important thing is to dispatch containers\n  in the correct order 0, 1, ..., 24 at their respective correct gates (c/N, N-1).\n- We use a single large crane (crane 0) to pick up each container one by one in \n  increasing order.\n- All other cranes are immediately bombed to ensure they don't block the path.\n- The large crane is capable of moving through squares with other containers.\n- BFS is used to find the shortest path for the large crane between target locations.\n*/\n\nint N;\nint A[5][5];\nint grid[5][5];\nint arrival_idx[5];\nint crane_x[5], crane_y[5];\nint crane_holding[5];\nbool container_on_grid[25];\nint container_pos_x[25], container_pos_y[25];\nbool container_dispatched[25];\nint target_c = 0;\n\n// Returns the direction char to move from (sx, sy) to (nx, ny)\nchar get_move_char(int sx, int sy, int nx, int ny) {\n    if (nx < sx) return 'U';\n    if (nx > sx) return 'D';\n    if (ny < sy) return 'L';\n    if (ny > sy) return 'R';\n    return '.';\n}\n\n// BFS to find the next step towards (tx, ty) on a 5x5 grid\npair<int, int> get_next_step(int sx, int sy, int tx, int ty) {\n    if (sx == tx && sy == ty) return {sx, sy};\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    queue<pair<int, int>> q;\n    q.push({sx, sy});\n    int dist[5][5];\n    pair<int, int> parent[5][5];\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    dist[sx][sy] = 0;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        if (curr.first == tx && curr.second == ty) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.first + dx[i];\n            int ny = curr.second + dy[i];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n\n    if (dist[tx][ty] == -1) return {sx, sy};\n\n    // Backtrack to find the first step along the path from (sx, sy)\n    int cx = tx, cy = ty;\n    while (parent[cx][cy].first != sx || parent[cx][cy].second != sy) {\n        pair<int, int> p = parent[cx][cy];\n        cx = p.first;\n        cy = p.second;\n    }\n    return {cx, cy};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            grid[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        arrival_idx[i] = 0;\n        crane_x[i] = i;\n        crane_y[i] = 0;\n        crane_holding[i] = -1;\n    }\n    crane_x[0] = 0;\n    crane_y[0] = 0;\n    for (int i = 0; i < 25; ++i) {\n        container_on_grid[i] = false;\n        container_dispatched[i] = false;\n    }\n\n    // Pre-allocate strings for outputs\n    vector<string> actions(N, string(10000, '.'));\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // 1. Arrivals (Step 1)\n        for (int i = 0; i < N; ++i) {\n            bool crane_holding_at_gate = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_holding[k] != -1 && crane_x[k] == i && crane_y[k] == 0) {\n                    crane_holding_at_gate = true;\n                    break;\n                }\n            }\n            if (arrival_idx[i] < N && grid[i][0] == -1 && !crane_holding_at_gate) {\n                int c = A[i][arrival_idx[i]];\n                grid[i][0] = c;\n                container_on_grid[c] = true;\n                container_pos_x[c] = i;\n                container_pos_y[c] = 0;\n                arrival_idx[i]++;\n            }\n        }\n\n        // 2. Crane Actions (Step 2)\n        // First turn: Bomb all small cranes to clear paths\n        if (turn == 1) {\n            for (int i = 1; i < N; ++i) {\n                actions[i][0] = 'B';\n                // Small cranes are effectively removed from the simulation now\n            }\n        }\n\n        // Decision for the large crane (crane 0)\n        if (crane_holding[0] == -1) {\n            if (target_c < 25) {\n                // Check if target container is on the grid\n                if (container_on_grid[target_c]) {\n                    int rx = container_pos_x[target_c];\n                    int ry = container_pos_y[target_c];\n                    if (crane_x[0] == rx && crane_y[0] == ry) {\n                        // If at the container, pick it up\n                        actions[0][turn - 1] = 'P';\n                        crane_holding[0] = target_c;\n                        grid[rx][ry] = -1;\n                        container_on_grid[target_c] = false;\n                    } else {\n                        // Otherwise, move towards it\n                        pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                        actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                        crane_x[0] = next_pos.first;\n                        crane_y[0] = next_pos.second;\n                    }\n                } else {\n                    // Target container hasn't arrived yet\n                    actions[0][turn - 1] = '.';\n                }\n            } else {\n                actions[0][turn - 1] = '.';\n            }\n        } else {\n            // Large crane is holding a container\n            int c = crane_holding[0];\n            int rx = c / N, ry = N - 1;\n            if (crane_x[0] == rx && crane_y[0] == ry) {\n                // If at target dispatch gate, release it\n                actions[0][turn - 1] = 'Q';\n                grid[rx][ry] = c;\n                crane_holding[0] = -1;\n                target_c++;\n            } else {\n                // Move towards the dispatch gate\n                pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                crane_x[0] = next_pos.first;\n                crane_y[0] = next_pos.second;\n            }\n        }\n\n        // 3. Dispatches (Step 3)\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][N - 1] != -1) {\n                int c = grid[i][N - 1];\n                grid[i][N - 1] = -1;\n                container_on_grid[c] = false;\n                container_dispatched[c] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - The goal is to make all h[i][j] = 0 by loading and unloading soil.\n * - Costs: \n *   - Loading/unloading d units: d.\n *   - Moving to an adjacent square: 100 + current_load.\n * - Strategy:\n *   1. At the current square (r, c), if h[r][c] > 0, we load all the soil (d = h[r][c]).\n *   2. If h[r][c] < 0 and we have soil (cur_load > 0), we unload as much as possible (d = min(cur_load, |h[r][c]|)).\n *   3. If neither is possible (e.g., h[r][c] is 0 or we don't have soil to unload), we move towards:\n *      - The nearest sink (h[i][j] < 0) if we currently have soil (cur_load > 0).\n *      - The nearest source (h[i][j] > 0) if we currently have no soil (cur_load == 0).\n *   4. Repeat until all h[i][j] are 0 and cur_load is 0.\n * - The sum of h[i][j] is guaranteed to be 0, ensuring that we can always find a source or a sink\n *   unless all heights are 0.\n * - The number of turns will be well within the limit of 100,000 because there are N^2 = 400 squares\n *   and the distance between any two squares is at most 40.\n */\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n\n    int cur_r = 0, cur_c = 0, cur_load = 0;\n    vector<string> ops;\n\n    while (true) {\n        if (h[cur_r][cur_c] > 0) {\n            // Step 1: Load soil from the current source\n            int d = h[cur_r][cur_c];\n            h[cur_r][cur_c] = 0;\n            cur_load += d;\n            ops.push_back(\"+\" + to_string(d));\n        } else if (h[cur_r][cur_c] < 0 && cur_load > 0) {\n            // Step 2: Unload soil to the current sink\n            int d = min(cur_load, -h[cur_r][cur_c]);\n            h[cur_r][cur_c] += d;\n            cur_load -= d;\n            ops.push_back(\"-\" + to_string(d));\n        } else {\n            // Step 3: Find the nearest target to move towards\n            int target_r = -1, target_c = -1;\n            int min_dist = 1000000;\n\n            // Greedy search for the nearest relevant square\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (cur_load > 0) {\n                        // If carrying soil, look for a sink\n                        if (h[i][j] < 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    } else {\n                        // If empty, look for a source\n                        if (h[i][j] > 0) {\n                            int d = abs(i - cur_r) + abs(j - cur_c);\n                            if (d < min_dist) {\n                                min_dist = d;\n                                target_r = i;\n                                target_c = j;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // If no valid target square is found, we are finished.\n            if (target_r == -1) break;\n\n            // Step 4: Move one step toward the target square\n            if (target_r < cur_r) {\n                ops.push_back(\"U\");\n                cur_r--;\n            } else if (target_r > cur_r) {\n                ops.push_back(\"D\");\n                cur_r++;\n            } else if (target_c < cur_c) {\n                ops.push_back(\"L\");\n                cur_c--;\n            } else if (target_c > cur_c) {\n                ops.push_back(\"R\");\n                cur_c++;\n            } else {\n                // This part should ideally not be reached given the logic above.\n                break;\n            }\n        }\n        \n        // Safety limit for the number of operations\n        if (ops.size() >= 100000) break;\n    }\n\n    // Output the list of operations\n    for (const string& s : ops) {\n        cout << s << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Final Strategy:\n * 1. SA with Geometric Cooling on a hybrid selection + placement problem.\n * 2. Objective function: max_v + 0.001 * sum_v.\n * 3. Greedy refinement after SA to improve the single best seed.\n * 4. Efficient score calculation by scanning all 60 pairs.\n */\n\nconst int MAX_N = 6;\nconst int MAX_M = 15;\nconst int MAX_SEEDS = 60;\nconst int MAX_PAIRS = 60;\n\nint N, M, T;\nint seed_count;\nint grid_size;\n\nstruct Seed {\n    int x[MAX_M];\n    int v;\n};\n\nSeed seeds[MAX_SEEDS];\nint grid[MAX_N][MAX_N];\nint pos[MAX_SEEDS]; \n\nstruct Pair {\n    int r1, c1, r2, c2;\n};\nPair adj_pairs[MAX_PAIRS];\nint cell_to_pairs[MAX_N][MAX_N][4];\nint cell_to_pairs_size[MAX_N][MAX_N];\ndouble pair_scores[MAX_PAIRS];\n\ninline double calculate_pair_vmax(int k1, int k2) {\n    double vmax = 0;\n    const int* x1 = seeds[k1].x;\n    const int* x2 = seeds[k2].x;\n    for (int l = 0; l < M; ++l) {\n        vmax += (x1[l] > x2[l] ? x1[l] : x2[l]);\n    }\n    return vmax;\n}\n\nstruct Score {\n    double max_v;\n    double sum_v;\n    double total() const { return max_v + 0.001 * sum_v; }\n};\n\nint pair_idx_global;\n\ninline Score calculate_score() {\n    double max_v = 0;\n    double sum_v = 0;\n    for (int i = 0; i < pair_idx_global; ++i) {\n        if (pair_scores[i] > max_v) max_v = pair_scores[i];\n        sum_v += pair_scores[i];\n    }\n    return {max_v, sum_v};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> T)) return 0;\n\n    seed_count = 2 * N * (N - 1);\n    grid_size = N * N;\n\n    for (int i = 0; i < seed_count; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> seeds[i].x[j];\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    int pair_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cell_to_pairs_size[i][j] = 0;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            adj_pairs[pair_idx] = {i, j, i, j + 1};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i][j + 1][cell_to_pairs_size[i][j + 1]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            adj_pairs[pair_idx] = {i, j, i + 1, j};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i + 1][j][cell_to_pairs_size[i + 1][j]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    pair_idx_global = pair_idx;\n\n    mt19937 rng(1337);\n\n    for (int t = 0; t < T; ++t) {\n        for (int i = 0; i < seed_count; ++i) pos[i] = -1;\n        for (int i = 0; i < grid_size; ++i) {\n            grid[i / N][i % N] = i;\n            pos[i] = i;\n        }\n\n        for (int i = 0; i < pair_idx; ++i) {\n            pair_scores[i] = calculate_pair_vmax(grid[adj_pairs[i].r1][adj_pairs[i].c1], grid[adj_pairs[i].r2][adj_pairs[i].c2]);\n        }\n\n        Score current_score = calculate_score();\n        auto start_time = chrono::steady_clock::now();\n        const double time_limit = 0.175;\n        const double initial_temp = 5.0;\n        const double final_temp = 0.01;\n\n        int iter = 0;\n        while (true) {\n            if ((iter & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - start_time).count();\n                if (elapsed > time_limit) break;\n            }\n            iter++;\n\n            int r = uniform_int_distribution<int>(0, N - 1)(rng);\n            int c = uniform_int_distribution<int>(0, N - 1)(rng);\n            int s = uniform_int_distribution<int>(0, seed_count - 1)(rng);\n\n            int r2 = -1, c2 = -1;\n            if (pos[s] != -1) {\n                r2 = pos[s] / N; c2 = pos[s] % N;\n            }\n\n            if (r == r2 && c == c2) continue;\n\n            int old_seed_rc = grid[r][c];\n            int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n\n            int changed_pairs[10];\n            double old_pair_scores[10];\n            int cp_cnt = 0;\n\n            auto record_affected_pairs = [&](int row, int col) {\n                for (int i = 0; i < cell_to_pairs_size[row][col]; ++i) {\n                    int p_idx = cell_to_pairs[row][col][i];\n                    bool already_recorded = false;\n                    for (int k = 0; k < cp_cnt; ++k) {\n                        if (changed_pairs[k] == p_idx) {\n                            already_recorded = true;\n                            break;\n                        }\n                    }\n                    if (!already_recorded) {\n                        changed_pairs[cp_cnt] = p_idx;\n                        old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                        cp_cnt++;\n                    }\n                }\n            };\n\n            record_affected_pairs(r, c);\n            if (r2 != -1) record_affected_pairs(r2, c2);\n\n            if (r2 != -1) {\n                grid[r][c] = s; grid[r2][c2] = old_seed_rc;\n                pos[s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n            } else {\n                grid[r][c] = s; pos[old_seed_rc] = -1; pos[s] = r * N + c;\n            }\n\n            for (int i = 0; i < cp_cnt; ++i) {\n                int p_idx = changed_pairs[i];\n                pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n            }\n\n            Score next_score = calculate_score();\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double temp = initial_temp * pow(final_temp / initial_temp, elapsed / time_limit);\n\n            if (next_score.total() > current_score.total() || exp((next_score.total() - current_score.total()) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_score = next_score;\n            } else {\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc; grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2; pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc; pos[s] = -1; pos[old_seed_rc] = r * N + c;\n                }\n                for (int i = 0; i < cp_cnt; ++i) pair_scores[changed_pairs[i]] = old_pair_scores[i];\n            }\n        }\n\n        // Greedy Refinement\n        for (int i = 0; i < grid_size; ++i) {\n            int r = i / N, c = i % N;\n            int original_seed = grid[r][c];\n            int best_s = original_seed;\n            Score best_score = current_score;\n\n            for (int s = 0; s < seed_count; ++s) {\n                if (s == original_seed) continue;\n\n                int r2 = -1, c2 = -1;\n                if (pos[s] != -1) { r2 = pos[s] / N; c2 = pos[s] % N; }\n\n                int old_seed_rc = grid[r][c];\n                int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n                int changed_pairs[10];\n                double old_pair_scores[10];\n                int cp_cnt = 0;\n\n                auto record_affected_pairs_greedy = [&](int row, int col) {\n                    for (int k = 0; k < cell_to_pairs_size[row][col]; ++k) {\n                        int p_idx = cell_to_pairs[row][col][k];\n                        bool already_recorded = false;\n                        for (int m = 0; m < cp_cnt; ++m) {\n                            if (changed_pairs[m] == p_idx) { already_recorded = true; break; }\n                        }\n                        if (!already_recorded) {\n                            changed_pairs[cp_cnt] = p_idx;\n                            old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                            cp_cnt++;\n                        }\n                    }\n                };\n\n                record_affected_pairs_greedy(r, c);\n                if (r2 != -1) record_affected_pairs_greedy(r2, c2);\n\n                if (r2 != -1) {\n                    grid[r][c] = s; grid[r2][c2] = old_seed_rc;\n                    pos[s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n                } else {\n                    grid[r][c] = s; pos[old_seed_rc] = -1; pos[s] = r * N + c;\n                }\n\n                for (int k = 0; k < cp_cnt; ++k) {\n                    int p_idx = changed_pairs[k];\n                    pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n                }\n\n                Score next_score = calculate_score();\n                if (next_score.total() > best_score.total()) {\n                    best_score = next_score;\n                    best_s = s;\n                }\n\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc; grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2; pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc; pos[s] = -1; pos[old_seed_rc] = r * N + c;\n                }\n                for (int k = 0; k < cp_cnt; ++k) pair_scores[changed_pairs[k]] = old_pair_scores[k];\n            }\n\n            if (best_s != original_seed) {\n                int r2 = -1, c2 = -1;\n                if (pos[best_s] != -1) { r2 = pos[best_s] / N; c2 = pos[best_s] % N; }\n                int old_seed_rc = grid[r][c];\n                int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n                if (r2 != -1) {\n                    grid[r][c] = best_s; grid[r2][c2] = old_seed_rc;\n                    pos[best_s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n                } else {\n                    grid[r][c] = best_s; pos[old_seed_rc] = -1; pos[best_s] = r * N + c;\n                }\n                for (int k = 0; k < pair_idx; ++k) {\n                    pair_scores[k] = calculate_pair_vmax(grid[adj_pairs[k].r1][adj_pairs[k].c1], grid[adj_pairs[k].r2][adj_pairs[k].c2]);\n                }\n                current_score = calculate_score();\n            }\n        }\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        for (int i = 0; i < seed_count; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                cin >> seeds[i].x[j];\n                seeds[i].v += seeds[i].x[j];\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// State of the robotic arm\nstruct State {\n    int rx, ry, dir_idx;\n};\n\nint N, M, V;\nvector<string> s_grid, t_grid;\nint curr_rx, curr_ry, curr_dir_idx;\n\n// Directions: 0: Down (1,0), 1: Right (0,1), 2: Up (-1,0), 3: Left (0,-1)\nint dx[] = {1, 0, -1, 0};\nint dy[] = {0, 1, 0, -1};\n\n// Calculate the minimum turns required to move from one state to another\nint dist(State s1, State s2) {\n    int D = abs(s1.rx - s2.rx) + abs(s1.ry - s2.ry);\n    int rot_ccw = (s2.dir_idx - s1.dir_idx + 4) % 4;\n    int rot_cw = (s1.dir_idx - s2.dir_idx + 4) % 4;\n    int R = min(rot_ccw, rot_cw);\n    return max(D, R);\n}\n\n// Find the root position and direction required to place the fingertip at (sx, sy)\nState find_state(int sx, int sy) {\n    for (int d = 0; d < 4; ++d) {\n        int rx = sx - dx[d];\n        int ry = sy - dy[d];\n        if (rx >= 0 && rx < N && ry >= 0 && ry < N) {\n            return {rx, ry, d};\n        }\n    }\n    return {0, 0, 0};\n}\n\n// Execute moves, rotations, and actions to reach a target state\nvoid move_to(State target, bool is_action) {\n    int dr = abs(target.rx - curr_rx);\n    int dc = abs(target.ry - curr_ry);\n    int D = dr + dc;\n    \n    int rot_ccw = (target.dir_idx - curr_dir_idx + 4) % 4;\n    int rot_cw = (curr_dir_idx - target.dir_idx + 4) % 4;\n    \n    int R, rot_char;\n    if (rot_ccw <= rot_cw) {\n        R = rot_ccw;\n        rot_char = 'L';\n    } else {\n        R = rot_cw;\n        rot_char = 'R';\n    }\n    \n    int turns = max(D, R);\n    // If the target is already reached but we need to perform an action (grab/release), take one turn.\n    if (is_action && turns == 0) turns = 1;\n\n    for (int i = 0; i < turns; ++i) {\n        char move_char = '.';\n        if (curr_rx < target.rx) { move_char = 'D'; curr_rx++; }\n        else if (curr_rx > target.rx) { move_char = 'U'; curr_rx--; }\n        else if (curr_ry < target.ry) { move_char = 'R'; curr_ry++; }\n        else if (curr_ry > target.ry) { move_char = 'L'; curr_ry--; }\n\n        char cur_rot_char = '.';\n        if (R > 0) {\n            cur_rot_char = rot_char;\n            if (rot_char == 'L') curr_dir_idx = (curr_dir_idx + 1) % 4;\n            else curr_dir_idx = (curr_dir_idx + 3) % 4;\n            R--;\n        }\n\n        char action_char = (is_action && i == turns - 1) ? 'P' : '.';\n        // Output turn format: Move(1) + Rotation(1) + RootAction(1) + LeafAction(1)\n        // For V=2, root is vertex 0, leaf is vertex 1.\n        cout << move_char << cur_rot_char << '.' << action_char << \"\\n\";\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    s_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Design: 2 vertices (root 0 and fingertip 1), edge length 1.\n    cout << 2 << \"\\n\";\n    cout << \"0 1\" << \"\\n\";\n    cout << \"0 0\" << \"\\n\";\n\n    curr_rx = 0;\n    curr_ry = 0;\n    curr_dir_idx = 1; // Initial direction is Right\n\n    vector<pair<int, int>> s_only, t_only;\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') s_only.push_back({i, j});\n            if (s_grid[i][j] == '0' && t_grid[i][j] == '1') t_only.push_back({i, j});\n        }\n    }\n\n    // Greedy matching: Always pick the (takoyaki, target) pair that minimizes travel distance.\n    while (!s_only.empty()) {\n        int best_si = -1, best_tj = -1;\n        int min_dist = 1e9;\n        State curr_state = {curr_rx, curr_ry, curr_dir_idx};\n        \n        for (int i = 0; i < (int)s_only.size(); ++i) {\n            State si_state = find_state(s_only[i].first, s_only[i].second);\n            int d_to_si = dist(curr_state, si_state);\n            for (int j = 0; j < (int)t_only.size(); ++j) {\n                State tj_state = find_state(t_only[j].first, t_only[j].second);\n                int d_si_to_tj = dist(si_state, tj_state);\n                if (d_to_si + d_si_to_tj < min_dist) {\n                    min_dist = d_to_si + d_si_to_tj;\n                    best_si = i;\n                    best_tj = j;\n                }\n            }\n        }\n\n        if (best_si != -1) {\n            // 1. Move to pick up takoyaki\n            State pick_state = find_state(s_only[best_si].first, s_only[best_si].second);\n            move_to(pick_state, true);\n            // 2. Move to drop off takoyaki\n            State drop_state = find_state(t_only[best_tj].first, t_only[best_tj].second);\n            move_to(drop_state, true);\n\n            // Remove the used takoyaki and target position\n            s_only.erase(s_only.begin() + best_si);\n            t_only.erase(t_only.begin() + best_tj);\n        } else {\n            break;\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We are given N mackerels (weight +1) and N sardines (weight -1).\n * We need to find an axis-parallel polygon that maximizes the sum of weights of fish inside it.\n * The polygon must have at most 1000 vertices, edge length at most 4*10^5, \n * and coordinates between 0 and 10^5. It must not self-intersect.\n * \n * The maximum weight rectangle problem can be solved in O(N^2) by iterating \n * through all pairs of y-coordinates and using Kadane's algorithm on x-coordinates.\n * With N = 5000, O(N^2) is approximately 2.5 * 10^7, which fits within the 2-second limit.\n * Specifically, if we collect unique x and y coordinates, the complexity becomes O(L^2 + LN),\n * where L is the number of unique y-coordinates and N is the total number of fish.\n */\n\nstruct Fish {\n    int x, y, weight;\n};\n\nint main() {\n    // Speed up I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Fish> all_fish;\n    vector<int> all_x, all_y;\n\n    // Read mackerels\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    // Read sardines\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Pre-process unique coordinates for compression\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n\n    int K = all_x.size();\n    int L = all_y.size();\n\n    // Group fish by their unique y-coordinate index\n    vector<vector<pair<int, int>>> fish_at_y(L);\n    for (const auto& f : all_fish) {\n        int xi = lower_bound(all_x.begin(), all_x.end(), f.x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), f.y) - all_y.begin();\n        fish_at_y[yi].push_back({xi, f.weight});\n    }\n\n    // Initialize with a single mackerel to ensure a minimum score of 2 (a-b+1 = 1-0+1 = 2)\n    // (assuming mackerels are the first N fish)\n    int best_sum = 0;\n    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n\n    // A single mackerel at index i (0 <= i < N) provides sum 1\n    for (int i = 0; i < N; ++i) {\n        // Since all_fish[0...N-1] are mackerels\n        int xi = lower_bound(all_x.begin(), all_x.end(), all_fish[i].x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), all_fish[i].y) - all_y.begin();\n        if (1 > best_sum) {\n            best_sum = 1;\n            bx1 = xi; bx2 = xi;\n            by1 = yi; by2 = yi;\n        }\n    }\n\n    // O(L^2 + LN) algorithm to find the maximum weight rectangle\n    vector<int> f(K, 0);\n    for (int i = 0; i < L; ++i) {\n        // Reset x-coordinate weights for the new starting y-coordinate\n        fill(f.begin(), f.end(), 0);\n        for (int j = i; j < L; ++j) {\n            // Add fish at current y-coordinate j to the weights\n            for (auto& p : fish_at_y[j]) {\n                f[p.first] += p.second;\n            }\n            \n            // Find maximum subarray sum of weights in f using Kadane's\n            int cur_sum = 0;\n            int start = 0;\n            for (int k = 0; k < K; ++k) {\n                cur_sum += f[k];\n                if (cur_sum > best_sum) {\n                    best_sum = cur_sum;\n                    bx1 = start; bx2 = k;\n                    by1 = i; by2 = j;\n                }\n                if (cur_sum < 0) {\n                    cur_sum = 0;\n                    start = k + 1;\n                }\n            }\n        }\n    }\n\n    // Convert the discrete indices back to actual coordinates\n    int x1 = all_x[bx1], x2 = all_x[bx2];\n    int y1 = all_y[by1], y2 = all_y[by2];\n\n    // Ensure we form a valid non-zero area polygon\n    if (x1 == x2) {\n        if (x1 < 100000) x2 = x1 + 1;\n        else { x1 = x1 - 1; x2 = x1 + 1; }\n    }\n    if (y1 == y2) {\n        if (y1 < 100000) y2 = y1 + 1;\n        else { y1 = y1 - 1; y2 = y1 + 1; }\n    }\n\n    // Output the 4 vertices of the rectangle\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << endl;\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Rectangular packing in a single cardboard box.\n * Goal: Minimize W + H + Sum(unused rectangles' dimensions).\n * Method: Randomized Greedy approach with time-limited iterations.\n * \n * Rules:\n * - Rectangles must be placed in increasing order of indices.\n * - Each can be rotated 90 degrees.\n * - Directions: U (upward, move towards y=0) or L (leftward, move towards x=0).\n * - U with reference b: x_left_new = x_right_b (or 0).\n * - L with reference b: y_top_new = y_bottom_b (or 0).\n * - Movement stops when it hits an edge of a previously placed rectangle or axis.\n */\n\nstruct Rect {\n    int id;\n    long long w, h;\n    long long x, y;\n    long long x_right, y_bottom;\n};\n\nstruct Placement {\n    int p, r, d, b; \n};\n\nstruct State {\n    vector<Rect> placed;\n    vector<Placement> placements;\n    long long W, H;\n    long long score;\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<pair<long long, long long>> measured_wh(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> measured_wh[i].first >> measured_wh[i].second;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Time management to avoid TLE in system tests\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 2.7) break;\n\n        State best_state;\n        best_state.score = 4e18; \n\n        // Perform randomized greedy iterations in batches\n        for (int batch = 0; batch < 100; ++batch) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) break;\n\n            for (int iter = 0; iter < 5; ++iter) {\n                State current_state;\n                current_state.W = 0;\n                current_state.H = 0;\n                long long unused_sum = 0;\n                for (int i = 0; i < N; ++i) unused_sum += (measured_wh[i].first + measured_wh[i].second);\n\n                for (int i = 0; i < N; ++i) {\n                    long long wi = measured_wh[i].first;\n                    long long hi = measured_wh[i].second;\n\n                    struct Option {\n                        int r, d, b;\n                        long long new_W, new_H;\n                    };\n                    static Option options[405];\n                    int opt_count = 0;\n                    long long best_new_W_H = 4e18;\n\n                    for (int r : {0, 1}) {\n                        long long w = (r == 0 ? wi : hi);\n                        long long h = (r == 0 ? hi : wi);\n                        \n                        for (int d : {0, 1}) { // 0 for U, 1 for L\n                            // Try Case 1: Reference rectangle b = -1\n                            long long x_l, x_r, y_t, y_b;\n                            if (d == 0) { // U\n                                x_l = 0; x_r = w; y_t = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                }\n                                y_b = y_t + h;\n                            } else { // L\n                                y_t = 0; y_b = h; x_l = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                }\n                                x_r = x_l + w;\n                            }\n                            long long nw = max(current_state.W, x_r);\n                            long long nh = max(current_state.H, y_b);\n                            if (nw + nh < best_new_W_H) {\n                                best_new_W_H = nw + nh;\n                                opt_count = 0;\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            } else if (nw + nh == best_new_W_H) {\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            }\n\n                            // Try Case 2: Reference rectangle b is a previously placed rectangle\n                            for (const auto& prev : current_state.placed) {\n                                int b_id = prev.id;\n                                if (d == 0) { // U\n                                    x_l = prev.x_right; x_r = x_l + w; y_t = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                    }\n                                    y_b = y_t + h;\n                                } else { // L\n                                    y_t = prev.y_bottom; y_b = y_t + h; x_l = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                    }\n                                    x_r = x_l + w;\n                                }\n                                nw = max(current_state.W, x_r);\n                                nh = max(current_state.H, y_b);\n                                if (nw + nh < best_new_W_H) {\n                                    best_new_W_H = nw + nh;\n                                    opt_count = 0;\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                } else if (nw + nh == best_new_W_H) {\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                }\n                            }\n                        }\n                    }\n\n                    // Greedy decision: Include rectangle i if the score improvement is worth it.\n                    long long delta = best_new_W_H - (current_state.W + current_state.H);\n                    if (delta < wi + hi && opt_count > 0) {\n                        uniform_int_distribution<int> dist(0, opt_count - 1);\n                        Option opt = options[dist(rng)];\n                        long long w = (opt.r == 0 ? wi : hi);\n                        long long h = (opt.r == 0 ? hi : wi);\n                        Rect nr; nr.id = i; nr.w = w; nr.h = h;\n                        if (opt.d == 0) { // Direction U\n                            if (opt.b == -1) nr.x = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.x = p.x_right; break; }\n                            }\n                            nr.x_right = nr.x + w;\n                            long long yt = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.x_right <= p.x || nr.x >= p.x_right)) yt = max(yt, p.y_bottom);\n                            nr.y = yt; nr.y_bottom = yt + h;\n                        } else { // Direction L\n                            if (opt.b == -1) nr.y = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.y = p.y_bottom; break; }\n                            }\n                            nr.y_bottom = nr.y + h;\n                            long long xl = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.y_bottom <= p.y || nr.y >= p.y_bottom)) xl = max(xl, p.x_right);\n                            nr.x = xl; nr.x_right = xl + w;\n                        }\n                        current_state.placed.push_back(nr);\n                        current_state.placements.push_back({i, opt.r, opt.d, opt.b});\n                        current_state.W = max(current_state.W, nr.x_right);\n                        current_state.H = max(current_state.H, nr.y_bottom);\n                        unused_sum -= (wi + hi);\n                    }\n                }\n                current_state.score = current_state.W + current_state.H + unused_sum;\n                if (current_state.score < best_state.score) best_state = current_state;\n            }\n        }\n\n        // Output the best arrangement found for the current turn.\n        cout << best_state.placed.size() << \"\\n\";\n        for (const auto& pl : best_state.placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << (pl.d == 0 ? \"U\" : \"L\") << \" \" << pl.b << \"\\n\";\n        }\n        cout.flush();\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n    }\n\n    return 0;\n}\n","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Partition a planar graph into rooted trees to maximize sum (h_v + 1) * A_v,\n * subject to height constraint h_v <= H.\n * \n * The main reason for the previous WRONG_ANSWER was the incorrect update of subtree \n * properties (subtree_sum_A and max_rel_depth) in the initial greedy construction \n * and during simulated annealing. If the properties were not updated correctly, \n * the height constraint check could fail.\n * \n * Strategy:\n * 1. Initial Solution: Greedy approach. Sort nodes by beauty (A_v) ascending.\n *    For each node, try to attach it to an existing node in a tree that has \n *    the maximum depth < H. This aims to put high-beauty nodes at greater depths.\n * 2. Optimization: Simulated Annealing (SA).\n *    Moves: Change the parent of a node v to a neighbor u (or -1 for root).\n *    Constraints:\n *      - No cycles: u must not be in v's subtree.\n *      - Height: new_depth_v + max_rel_depth_v <= H.\n *    Efficiency:\n *      - Depth and ancestor check in O(H).\n *      - Maintain subtree_sum_A and max_rel_depth for each node.\n *      - Updating these values takes O(H * average_degree) by walking up ancestors.\n *    Since H is small (H=10), this allows for millions of SA iterations.\n */\n\nconst int MAXN = 1005;\nint N, M, H;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_rel_depth[MAXN];\n\n// Returns the distance from node v to its root (root distance is 0)\nint get_depth(int v) {\n    int d = 0;\n    while (v != -1) {\n        v = parent[v];\n        d++;\n    }\n    return d - 1;\n}\n\n// Checks if node v is an ancestor of node u\nbool is_ancestor(int v, int u) {\n    int curr = u;\n    while (curr != -1) {\n        if (curr == v) return true;\n        curr = parent[curr];\n    }\n    return false;\n}\n\n// Updates subtree_sum_A and max_rel_depth for node v and all its ancestors.\n// Since height is at most H, the path to the root is at most H+1.\nvoid update_subtree_info(int v) {\n    if (v == -1) return;\n    int curr = v;\n    while (curr != -1) {\n        long long new_sum = A[curr];\n        int new_max_rd = 0;\n        for (int c : children[curr]) {\n            new_sum += subtree_sum_A[c];\n            new_max_rd = max(new_max_rd, max_rel_depth[c] + 1);\n        }\n        \n        // If the node's properties don't change, the ancestors won't change either.\n        // However, in the initial greedy construction, we must ensure we actually\n        // update the ancestors even if the initial values were already set.\n        // Using a simple update loop without a premature break should be safe and fast.\n        subtree_sum_A[curr] = new_sum;\n        max_rel_depth[curr] = new_max_rd;\n        curr = parent[curr];\n    }\n}\n\nint main() {\n    // Optimization for faster standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> H)) return 0;\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // Skip coordinate input as they aren't needed for this approach\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Initialize state\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_rel_depth[i] = 0;\n    }\n\n    // Initial greedy construction\n    vector<int> order(N);\n    for (int i = 0; i < N; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return A[a] < A[b];\n    });\n\n    vector<bool> processed(N, false);\n    for (int v : order) {\n        int best_u = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (processed[u]) {\n                int d = get_depth(u);\n                if (d < H && d > max_d) {\n                    max_d = d;\n                    best_u = u;\n                }\n            }\n        }\n        \n        // v's own info is already set to A[v] and 0\n        subtree_sum_A[v] = A[v];\n        max_rel_depth[v] = 0;\n\n        if (best_u != -1) {\n            parent[v] = best_u;\n            children[best_u].push_back(v);\n            // Update ancestors of the new parent\n            update_subtree_info(best_u);\n        }\n        processed[v] = true;\n    }\n\n    // Simulated Annealing (SA) refinement\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 rng(42);\n    \n    double T_start = 100.0;\n    double T_end = 0.01;\n    int iterations = 1000000;\n    double cooling_rate = pow(T_end / T_start, 1.0 / iterations);\n    double T = T_start;\n\n    for (int iter = 0; iter < iterations; ++iter) {\n        if ((iter & 1023) == 0) { // Periodic time check\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n        }\n\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int u_idx = uniform_int_distribution<int>(-1, (int)adj[v].size() - 1)(rng);\n        int u = (u_idx == -1) ? -1 : adj[v][u_idx];\n\n        if (u == parent[v]) {\n            T *= cooling_rate;\n            continue;\n        }\n        if (u != -1 && is_ancestor(v, u)) {\n            T *= cooling_rate;\n            continue;\n        }\n\n        int old_p = parent[v];\n        int new_p = u;\n        int old_depth_v = get_depth(v);\n        int new_depth_v = (new_p == -1) ? 0 : get_depth(new_p) + 1;\n\n        // Constraint check: ensures no node in v's subtree exceeds height H\n        if (new_depth_v + max_rel_depth[v] > H) {\n            T *= cooling_rate;\n            continue;\n        }\n\n        // Change in score\n        long long delta = (long long)(new_depth_v - old_depth_v) * subtree_sum_A[v];\n\n        if (delta > 0 || uniform_real_distribution<double>(0, 1)(rng) < exp((double)delta / T)) {\n            // Accept the move\n            if (old_p != -1) {\n                auto& old_children = children[old_p];\n                old_children.erase(remove(old_children.begin(), old_children.end(), v), old_children.end());\n                update_subtree_info(old_p);\n            }\n            parent[v] = new_p;\n            if (new_p != -1) {\n                children[new_p].push_back(v);\n                update_subtree_info(new_p);\n            }\n        }\n        T *= cooling_rate;\n    }\n\n    // Final output\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: Oni wa Soto, Fuku wa Uchi\n * Objective: Remove all Oni ('x') from an NxN board without removing any Fukunokami ('o').\n * Strategy:\n * 1. Identify all Oni positions.\n * 2. Identify all possible \"efficient\" moves:\n *    - For each row/column, if a contiguous sequence of squares from an edge does not contain 'o', \n *      we can remove all 'x' in that sequence using a single group of shifts and a restoration sequence.\n *    - For example, shifting row i Left k times and then Right k times removes all 'x' in (i, 0) to (i, k-1)\n *      and restores the remaining pieces to their original positions.\n * 3. Use a Greedy Set Cover heuristic to select the minimum-cost set of moves that covers all 'x'.\n * 4. Output the sequence of moves.\n */\n\nstruct Oni {\n    int r, c;\n};\n\nstruct Move {\n    char d;\n    int p;\n    int k;\n    vector<int> covered_indices; // Indices in the initial Oni list\n    int cost;\n};\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> board(N);\n    vector<Oni> oni_list;\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_list.push_back({i, j});\n            }\n        }\n    }\n\n    vector<Move> all_possible_moves;\n\n    // Generate possible moves for each column (Up and Down)\n    for (int j = 0; j < N; ++j) {\n        // Up moves\n        int max_up = 0;\n        while (max_up < N && board[max_up][j] != 'o') {\n            max_up++;\n        }\n        for (int k = 1; k <= max_up; ++k) {\n            Move m;\n            m.d = 'U'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Down moves\n        int max_down = 0;\n        while (max_down < N && board[N - 1 - max_down][j] != 'o') {\n            max_down++;\n        }\n        for (int k = 1; k <= max_down; ++k) {\n            Move m;\n            m.d = 'D'; m.p = j; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].c == j && oni_list[idx].r >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Generate possible moves for each row (Left and Right)\n    for (int i = 0; i < N; ++i) {\n        // Left moves\n        int max_left = 0;\n        while (max_left < N && board[i][max_left] != 'o') {\n            max_left++;\n        }\n        for (int k = 1; k <= max_left; ++k) {\n            Move m;\n            m.d = 'L'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c < k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n\n        // Right moves\n        int max_right = 0;\n        while (max_right < N && board[i][N - 1 - max_right] != 'o') {\n            max_right++;\n        }\n        for (int k = 1; k <= max_right; ++k) {\n            Move m;\n            m.d = 'R'; m.p = i; m.k = k; m.cost = 2 * k;\n            for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n                if (oni_list[idx].r == i && oni_list[idx].c >= N - k) {\n                    m.covered_indices.push_back(idx);\n                }\n            }\n            if (!m.covered_indices.empty()) all_possible_moves.push_back(m);\n        }\n    }\n\n    // Greedy Set Cover\n    vector<bool> uncovered(oni_list.size(), true);\n    int remaining_oni = oni_list.size();\n    vector<Move> chosen_moves;\n\n    while (remaining_oni > 0) {\n        int best_m_idx = -1;\n        double best_ratio = -1.0;\n\n        for (int i = 0; i < (int)all_possible_moves.size(); ++i) {\n            int count = 0;\n            for (int idx : all_possible_moves[i].covered_indices) {\n                if (uncovered[idx]) count++;\n            }\n            if (count > 0) {\n                double ratio = (double)count / all_possible_moves[i].cost;\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_m_idx = i;\n                }\n            }\n        }\n\n        if (best_m_idx == -1) break; // Should not happen given problem guarantees\n\n        chosen_moves.push_back(all_possible_moves[best_m_idx]);\n        for (int idx : all_possible_moves[best_m_idx].covered_indices) {\n            if (uncovered[idx]) {\n                uncovered[idx] = false;\n                remaining_oni--;\n            }\n        }\n    }\n\n    // Output moves\n    for (const auto& m : chosen_moves) {\n        char d1 = m.d, d2 = (m.d == 'U' ? 'D' : (m.d == 'D' ? 'U' : (m.d == 'L' ? 'R' : 'L')));\n        for (int step = 0; step < m.k; ++step) cout << d1 << \" \" << m.p << \"\\n\";\n        for (int step = 0; step < m.k; ++step) cout << d2 << \" \" << m.p << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Global variables for efficiency in the optimization loop\nint N;\nlong long L;\nvector<long long> T;\nvector<int> a, b;\nvector<long long> S;\nlong long current_err = 0;\n\n// Function to update the sum of T_j for the nodes a[j] and b[j]\n// We maintain the error term 'current_err' = sum |S_i - 2*T_i| in O(1)\nvoid apply_a(int j, int new_a) {\n    int old_a = a[j];\n    if (old_a == new_a) return;\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] -= T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] += T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    a[j] = new_a;\n}\n\nvoid revert_a(int j, int old_a, int new_a) {\n    if (old_a == new_a) return;\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] -= T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] += T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    a[j] = old_a;\n}\n\nvoid apply_b(int j, int new_b) {\n    int old_b = b[j];\n    if (old_b == new_b) return;\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] -= T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] += T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    b[j] = new_b;\n}\n\nvoid revert_b(int j, int old_b, int new_b) {\n    if (old_b == new_b) return;\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] -= T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] += T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    b[j] = old_b;\n}\n\nint visited[105];\nint timestamp = 0;\nint q[105];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> L)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    a.resize(N);\n    b.resize(N);\n    S.assign(N, 0);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Initial random assignment\n    for (int i = 0; i < N; ++i) {\n        a[i] = rng() % N;\n        b[i] = rng() % N;\n        S[a[i]] += T[i];\n        S[b[i]] += T[i];\n    }\n\n    current_err = 0;\n    for (int i = 0; i < N; ++i) {\n        current_err += abs(S[i] - 2 * T[i]);\n    }\n\n    // BFS-based reachability check to calculate the penalty\n    auto get_total_cost = [&]() {\n        timestamp++;\n        int head = 0, tail = 0;\n        q[tail++] = 0;\n        visited[0] = timestamp;\n        while (head < tail) {\n            int u = q[head++];\n            if (visited[a[u]] != timestamp) {\n                visited[a[u]] = timestamp;\n                q[tail++] = a[u];\n            }\n            if (visited[b[u]] != timestamp) {\n                visited[b[u]] = timestamp;\n                q[tail++] = b[u];\n            }\n        }\n        long long penalty = 0;\n        for (int i = 0; i < N; ++i) {\n            // If an employee with assigned duties is not reachable, penalize heavily\n            if (T[i] > 0 && visited[i] != timestamp) {\n                penalty += 1000000LL;\n            }\n        }\n        return current_err + penalty;\n    };\n\n    long long current_cost = get_total_cost();\n    \n    // Simulated Annealing parameters\n    int total_iters = 1000000;\n    double T_start = 1000000.0;\n    double T_end = 0.5;\n\n    for (int iter = 0; iter < total_iters; ++iter) {\n        int j = rng() % N;\n        int old_a = a[j], old_b = b[j];\n        int type = rng() % 3; // 0: change a, 1: change b, 2: change both\n        int new_a = old_a, new_b = old_b;\n        \n        if (type == 0) new_a = rng() % N;\n        else if (type == 1) new_b = rng() % N;\n        else { new_a = rng() % N; new_b = rng() % N; }\n\n        if (new_a == old_a && new_b == old_b) continue;\n\n        bool a_changed = (new_a != old_a);\n        bool b_changed = (new_b != old_b);\n\n        if (a_changed) apply_a(j, new_a);\n        if (b_changed) apply_b(j, new_b);\n\n        long long next_cost = get_total_cost();\n        double temp = T_start * pow(T_end / T_start, (double)iter / total_iters);\n\n        if (next_cost < current_cost || dist(rng) < exp((double)(current_cost - next_cost) / temp)) {\n            current_cost = next_cost;\n        } else {\n            // Revert changes if not accepted\n            if (b_changed) revert_b(j, old_b, new_b);\n            if (a_changed) revert_a(j, old_a, new_a);\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Strategy Refinement:\n * \n * 1. Coordinate Estimation & Spatial Locality:\n *    Estimate city coordinates using the center of their given rectangular bounds.\n *    Sort cities using a Morton curve (Z-order) to ensure that cities near each other\n *    in 2D space are likely to be placed in the same or adjacent groups.\n * \n * 2. Improved Grouping via Local Search:\n *    Initial grouping follows the Morton order.\n *    We use a Randomized Local Search (swap heuristic) to optimize the grouping.\n *    In each iteration, we swap two cities from different groups if the swap reduces\n *    the total estimated Minimum Spanning Tree (MST) cost (calculated using center coordinates).\n *    This is done within a time limit to avoid TLE.\n * \n * 3. Optimized Query Strategy:\n *    The query limit Q=400 and N=800 allows for roughly 2 cities per query if we want to cover all.\n *    We use a sliding window approach within each group. \n *    For a group of size G_i:\n *    - If G_i <= L, one query covers the group.\n *    - If G_i > L, we use a sliding window where each subsequent query adds exactly \n *      S = 2 new cities. This is achieved by having an overlap of (L - S) = (L - 2) cities.\n *    - Total queries: Sum_{G_i > 1} (1 + max(0, ceil((G_i - L) / 2))) is guaranteed \n *      to be <= 400 for N=800, Q=400, and L >= 3.\n * \n * 4. Final Road Selection:\n *    Within each group, we collect all edges returned by the queries.\n *    To ensure we choose \"good\" edges, we sort these edges by their estimated distance \n *    and use Kruskal's algorithm to find the MST for that group.\n *    If connectivity is not achieved (unlikely with S=2), we add fallback edges.\n */\n\n// Morton (Z-order) curve encoding for 2D points.\nuint64_t interleave(uint32_t x, uint32_t y) {\n    uint64_t z = 0;\n    for (int i = 0; i < 32; ++i) {\n        z |= (static_cast<uint64_t>((x >> i) & 1) << (2 * i));\n        z |= (static_cast<uint64_t>((y >> i) & 1) << (2 * i + 1));\n    }\n    return z;\n}\n\nstruct City {\n    int id;\n    uint64_t morton;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int i) {\n        if (parent[i] == i) return i;\n        return parent[i] = find(parent[i]);\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\ndouble estimated_dist(int i, int j, const vector<pair<int, int>>& centers) {\n    double dx = (double)centers[i].first - centers[j].first;\n    double dy = (double)centers[i].second - centers[j].second;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Prim's algorithm for calculating MST cost of a group of cities using center points.\ndouble calculate_group_mst_cost(const vector<int>& group_cities, const vector<pair<int, int>>& centers) {\n    int n = group_cities.size();\n    if (n <= 1) return 0;\n    vector<double> min_dist(n, 1e18);\n    vector<bool> visited(n, false);\n    min_dist[0] = 0;\n    double total_cost = 0;\n    for (int i = 0; i < n; ++i) {\n        int u = -1;\n        for (int j = 0; j < n; ++j) {\n            if (!visited[j] && (u == -1 || min_dist[j] < min_dist[u]))\n                u = j;\n        }\n        if (u == -1 || min_dist[u] == 1e18) break; \n        visited[u] = true;\n        total_cost += min_dist[u];\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v]) {\n                double d = estimated_dist(group_cities[u], group_cities[v], centers);\n                if (d < min_dist[v]) min_dist[v] = d;\n            }\n        }\n    }\n    return total_cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<pair<int, int>> centers(N);\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        int cx = (lx + rx) / 2;\n        int cy = (ly + ry) / 2;\n        centers[i] = {cx, cy};\n        cities[i] = {i, interleave((uint32_t)cx, (uint32_t)cy)};\n    }\n\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        return a.morton < b.morton;\n    });\n\n    vector<int> current_assignment(N);\n    vector<vector<int>> groups(M);\n    int curr_idx = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            int city_id = cities[curr_idx++].id;\n            groups[i].push_back(city_id);\n            current_assignment[city_id] = i;\n        }\n    }\n\n    vector<double> group_mst_costs(M);\n    for (int i = 0; i < M; ++i) {\n        group_mst_costs[i] = calculate_group_mst_cost(groups[i], centers);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 600) {\n        int u = uniform_int_distribution<int>(0, N - 1)(rng);\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int gu = current_assignment[u];\n        int gv = current_assignment[v];\n        if (gu == gv) continue;\n\n        vector<int> new_group_u, new_group_v;\n        for (int city : groups[gu]) if (city != u) new_group_u.push_back(city);\n        new_group_u.push_back(v);\n        for (int city : groups[gv]) if (city != v) new_group_v.push_back(city);\n        new_group_v.push_back(u);\n\n        double new_cost_u = calculate_group_mst_cost(new_group_u, centers);\n        double new_cost_v = calculate_group_mst_cost(new_group_v, centers);\n\n        if (new_cost_u + new_cost_v < group_mst_costs[gu] + group_mst_costs[gv]) {\n            groups[gu] = new_group_u;\n            groups[gv] = new_group_v;\n            current_assignment[u] = gv;\n            current_assignment[v] = gu;\n            group_mst_costs[gu] = new_cost_u;\n            group_mst_costs[gv] = new_cost_v;\n        }\n    }\n\n    vector<vector<pair<int, int>>> edges_in_group(M);\n    int S = 2; // Number of new cities per query\n\n    for (int i = 0; i < M; ++i) {\n        int g_size = groups[i].size();\n        if (g_size <= 1) continue;\n\n        vector<pair<int, int>> collected_edges;\n        \n        int start = 0;\n        int end = min(L - 1, g_size - 1);\n        \n        auto perform_query = [&](int s, int e) {\n            int subset_size = e - s + 1;\n            cout << \"? \" << subset_size;\n            for (int k = s; k <= e; ++k) cout << \" \" << groups[i][k];\n            cout << endl;\n            for (int k = 0; k < subset_size - 1; ++k) {\n                int u_e, v_e;\n                cin >> u_e >> v_e;\n                collected_edges.push_back({u_e, v_e});\n            }\n        };\n\n        perform_query(start, end);\n\n        // Sliding window: each query adds S = 2 new cities. \n        // To add 2 new cities, the overlap must be (L - 2).\n        int overlap = L - S;\n        while (end < g_size - 1) {\n            start = end - overlap + 1;\n            end = min(start + L - 1, g_size - 1);\n            perform_query(start, end);\n        }\n\n        DSU dsu(N);\n        sort(collected_edges.begin(), collected_edges.end(), [&](const pair<int,int>& a, const pair<int,int>& b) {\n            return estimated_dist(a.first, a.second, centers) < estimated_dist(b.first, b.second, centers);\n        });\n\n        for (auto& edge : collected_edges) {\n            if (dsu.unite(edge.first, edge.second)) {\n                edges_in_group[i].push_back(edge);\n            }\n        }\n        for (int k = 1; k < g_size; ++k) {\n            if (dsu.unite(groups[i][0], groups[i][k])) {\n                edges_in_group[i].push_back({groups[i][0], groups[i][k]});\n            }\n        }\n    }\n\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            cout << groups[i][j] << (j == (int)groups[i].size() - 1 ? \"\" : \" \");\n        }\n        cout << endl;\n        for (auto& edge : edges_in_group[i]) {\n            cout << edge.first << \" \" << edge.second << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size: 20x20.\n * - Number of target squares: M-1 = 39.\n * - Total turns allowed: 1600.\n * - Score formula: M + 2NM - T, where T is the number of turns.\n * - Goals: Visit all targets in order and minimize T.\n * \n * Insights from Initial Approach:\n * - The 'Move' (M) only strategy achieves a score of ~1100.\n * - A better strategy should utilize 'Slide' (S) to reduce the number of turns T.\n * - 'Slide' is useful when it can cover a large distance by hitting a boundary or a block.\n * - Boundary sliding can be used to jump from (r, c) to (0, c) or (N-1, c) in one turn.\n * \n * Refined Strategy:\n * - Use Dijkstra's algorithm to find the shortest path between consecutive target squares.\n * - The state for Dijkstra will be the current (row, col) position.\n * - Transitions include:\n *   1. Move (M) in 4 cardinal directions (cost 1, only if the cell is in bounds and not a block).\n *   2. Slide (S) in 4 cardinal directions (cost 1, stops at the first block or boundary encountered).\n * - This approach naturally optimizes both 'Move' and 'Slide' actions, including boundary jumps.\n * - Since the grid is small (20x20), Dijkstra is computationally efficient.\n */\n\nconst int INF = 1e9;\n\n// State for Dijkstra\nstruct State {\n    int d, r, c;\n    bool operator>(const State& other) const {\n        return d > other.d;\n    }\n};\n\n// Parent pointer to reconstruct the path\nstruct Parent {\n    int r, c;\n    char action;\n    int dir;\n};\n\nint N, M;\nbool G[20][20]; // Grid representing block positions\nint dr[] = {-1, 1, 0, 0}; // Directions: Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar dir_chars[] = {'U', 'D', 'L', 'R'};\n\nvoid solve() {\n    // Input N and M\n    if (!(cin >> N >> M)) return;\n    int r0, c0;\n    if (!(cin >> r0 >> c0)) return;\n    \n    // Read the sequence of target squares\n    vector<pair<int, int>> targets(M);\n    targets[0] = {r0, c0};\n    for (int i = 1; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    // Initialize grid (initially no blocks)\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            G[i][j] = false;\n\n    int curr_r = r0, curr_c = c0;\n\n    // Iterate through target squares in order\n    for (int k = 1; k < M; ++k) {\n        int tr = targets[k].first;\n        int tc = targets[k].second;\n\n        // Dijkstra algorithm to find the shortest path from curr to target\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<Parent>> parent(N, vector<Parent>(N, {-1, -1, ' ', -1}));\n\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[curr_r][curr_c] = 0;\n        pq.push({0, curr_r, curr_c});\n\n        while (!pq.empty()) {\n            State top = pq.top();\n            pq.pop();\n            int d = top.d, r = top.r, c = top.c;\n\n            if (d > dist[r][c]) continue;\n            if (r == tr && c == tc) break;\n\n            for (int i = 0; i < 4; ++i) {\n                // Action 1: Move (M)\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !G[nr][nc]) {\n                    if (dist[nr][nc] > d + 1) {\n                        dist[nr][nc] = d + 1;\n                        parent[nr][nc] = {r, c, 'M', i};\n                        pq.push({dist[nr][nc], nr, nc});\n                    }\n                }\n\n                // Action 2: Slide (S)\n                int sr = r, sc = c;\n                while (true) {\n                    int next_r = sr + dr[i], next_c = sc + dc[i];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                // A Slide is only considered if it actually results in a movement\n                if (sr != r || sc != c) {\n                    if (dist[sr][sc] > d + 1) {\n                        dist[sr][sc] = d + 1;\n                        parent[sr][sc] = {r, c, 'S', i};\n                        pq.push({dist[sr][sc], sr, sc});\n                    }\n                }\n            }\n        }\n\n        // Reconstruct the sequence of actions taken to reach target (tr, tc)\n        vector<pair<char, int>> path;\n        if (dist[tr][tc] == INF) {\n            // Safety fallback: manual Manhattan movement if Dijkstra fails\n            int temp_r = curr_r, temp_c = curr_c;\n            while (temp_r != tr) {\n                int d_dir = (tr > temp_r) ? 1 : 0;\n                path.push_back({'M', d_dir});\n                temp_r += dr[d_dir];\n            }\n            while (temp_c != tc) {\n                int d_dir = (tc > temp_c) ? 3 : 2;\n                path.push_back({'M', d_dir});\n                temp_c += dc[d_dir];\n            }\n        } else {\n            int pr = tr, pc = tc;\n            while (pr != curr_r || pc != curr_c) {\n                Parent p = parent[pr][pc];\n                path.push_back({p.action, p.dir});\n                pr = p.r; pc = p.c;\n            }\n            reverse(path.begin(), path.end());\n        }\n\n        // Output the actions and update current position\n        for (auto& step : path) {\n            cout << step.first << \" \" << dir_chars[step.second] << \"\\n\";\n            if (step.first == 'M') {\n                curr_r += dr[step.second];\n                curr_c += dc[step.second];\n            } else if (step.first == 'S') {\n                int sr = curr_r, sc = curr_c;\n                while (true) {\n                    int next_r = sr + dr[step.second], next_c = sc + dc[step.second];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                curr_r = sr; curr_c = sc;\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    solve();\n    return 0;\n}\n"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    int x, y, r, id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const {\n        return (ll)(x2 - x1) * (y2 - y1);\n    }\n};\n\nstruct RectTask {\n    Rect R;\n    vector<Point> P;\n    ll sum_r;\n    ll error;\n\n    // Max-priority queue to pick the rectangle with the largest error\n    bool operator<(const RectTask& other) const {\n        return error < other.error;\n    }\n};\n\nstruct SplitResult {\n    bool vertical;\n    int k;\n    int j; \n    double score;\n    ll sum_r_L;\n};\n\nint N;\nPoint points_orig[205];\nRect ans[205];\n\nvoid solve() {\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 gen(42);\n\n    double best_total_sat = -1.0;\n    Rect best_ans_res[205];\n\n    // Main loop: perform multiple randomized greedy constructions\n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 4500) break;\n\n        priority_queue<RectTask> pq;\n        ll total_r = 0;\n        vector<Point> P_init;\n        for (int i = 0; i < N; ++i) {\n            total_r += points_orig[i].r;\n            P_init.push_back(points_orig[i]);\n        }\n\n        // Initial task: the entire 10000x10000 area\n        pq.push({ {0, 0, 10000, 10000}, P_init, total_r, abs(100000000LL - total_r) });\n\n        Rect current_ans[205];\n\n        while (!pq.empty()) {\n            RectTask curr = pq.top();\n            pq.pop();\n\n            if (curr.P.size() == 1) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            int n = curr.P.size();\n            ll area_R = curr.R.area();\n            ll sum_r_P = curr.sum_r;\n            vector<SplitResult> possible_splits;\n\n            // Vertical splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.x < b.x;\n            });\n            ll sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].x < curr.P[j].x) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int H = curr.R.y2 - curr.R.y1;\n                    int target_k = curr.R.x1 + (int)round((double)target_area_L / H);\n                    int k = max(curr.P[j - 1].x + 1, min(curr.P[j].x, target_k));\n                    \n                    ll area_L = (ll)(k - curr.R.x1) * H;\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ true, k, j, score, sum_r_L });\n                }\n            }\n\n            // Horizontal splits evaluation\n            sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                return a.y < b.y;\n            });\n            sum_r_L = 0;\n            for (int j = 1; j < n; ++j) {\n                sum_r_L += curr.P[j - 1].r;\n                if (curr.P[j - 1].y < curr.P[j].y) {\n                    long double target_area_L = (long double)area_R * sum_r_L / sum_r_P;\n                    int W = curr.R.x2 - curr.R.x1;\n                    int target_k = curr.R.y1 + (int)round((double)target_area_L / W);\n                    int k = max(curr.P[j - 1].y + 1, min(curr.P[j].y, target_k));\n\n                    ll area_L = (ll)W * (k - curr.R.y1);\n                    double score = abs((double)area_L - (double)target_area_L);\n                    possible_splits.push_back({ false, k, j, score, sum_r_L });\n                }\n            }\n\n            if (possible_splits.empty()) {\n                current_ans[curr.P[0].id] = curr.R;\n                continue;\n            }\n\n            // Randomized selection from the best splits\n            sort(possible_splits.begin(), possible_splits.end(), [](const SplitResult& a, const SplitResult& b) {\n                return a.score < b.score;\n            });\n\n            int top_count = min((int)possible_splits.size(), 3);\n            uniform_int_distribution<int> dist(0, top_count - 1);\n            SplitResult best = possible_splits[dist(gen)];\n\n            // Re-sort points to correctly divide them\n            if (best.vertical) {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.x < b.x;\n                });\n            } else {\n                sort(curr.P.begin(), curr.P.end(), [](const Point& a, const Point& b) {\n                    return a.y < b.y;\n                });\n            }\n\n            vector<Point> P_L, P_R;\n            for (int i = 0; i < best.j; ++i) P_L.push_back(curr.P[i]);\n            for (int i = best.j; i < n; ++i) P_R.push_back(curr.P[i]);\n\n            Rect R_L, R_R;\n            if (best.vertical) {\n                R_L = { curr.R.x1, curr.R.y1, best.k, curr.R.y2 };\n                R_R = { best.k, curr.R.y1, curr.R.x2, curr.R.y2 };\n            } else {\n                R_L = { curr.R.x1, curr.R.y1, curr.R.x2, best.k };\n                R_R = { curr.R.x1, best.k, curr.R.x2, curr.R.y2 };\n            }\n\n            ll sum_r_R = sum_r_P - best.sum_r_L;\n            pq.push({ R_L, P_L, best.sum_r_L, abs(R_L.area() - best.sum_r_L) });\n            pq.push({ R_R, P_R, sum_r_R, abs(R_R.area() - sum_r_R) });\n        }\n\n        // Evaluate the total satisfaction level\n        double current_sat = 0;\n        for (int i = 0; i < N; ++i) {\n            int xi = points_orig[i].x, yi = points_orig[i].y, ri = points_orig[i].r;\n            Rect r = current_ans[i];\n            if (xi >= r.x1 && xi < r.x2 && yi >= r.y1 && yi < r.y2) {\n                ll si = r.area();\n                double x = (double)min((ll)ri, si) / max((ll)ri, si);\n                current_sat += 1.0 - (1.0 - x) * (1.0 - x);\n            }\n        }\n\n        if (current_sat > best_total_sat) {\n            best_total_sat = current_sat;\n            for (int i = 0; i < N; ++i) best_ans_res[i] = current_ans[i];\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_res[i].x1 << \" \" << best_ans_res[i].y1 << \" \"\n             << best_ans_res[i].x2 << \" \" << best_ans_res[i].y2 << \"\\n\";\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> points_orig[i].x >> points_orig[i].y >> points_orig[i].r;\n        points_orig[i].id = i;\n    }\n    solve();\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The task is to find a path in a 50x50 grid maximizing the sum of square values.\n * A square can only be visited once, and a tile (size 1x1, 1x2, or 2x1) can also only be visited once.\n * This means once we step on any part of a multi-square tile, the other squares of that tile \n * are rendered inaccessible.\n * \n * Refined Algorithm:\n * We use a Randomized Diversity-based Beam Search.\n * 1. Beam Search: Maintains a fixed number of promising paths (the beam) to avoid getting stuck in local optima.\n * 2. Diversity Mechanism: Instead of just keeping the top-N paths by score, we split the beam:\n *    - A portion of the beam is taken from the best paths in each of the 4 possible move directions (U, D, L, R).\n *    - Another portion is taken from the absolute top-N paths by heuristic score.\n *    This prevents the beam from becoming saturated with very similar paths that all move in the same direction.\n * 3. Enhanced Heuristic:\n *    Heuristic = CurrentScore + W1 * (RemainingPotential) + W2 * (SumOfNeighborValues) + W3 * (ConnectivityCount)\n *    - RemainingPotential: encourages long paths.\n *    - SumOfNeighborValues: encourages moving towards high-value clusters.\n *    - ConnectivityCount: encourages staying in open areas to avoid getting trapped.\n * 4. Efficient State Management: Use a bitset (represented by uint64_t array) for fast tile-visited checks.\n */\n\nconst int N = 50;\nconst int MAX_TILES = 2505;\nconst int NUM_U64 = (MAX_TILES + 63) / 64;\n\nint si, sj;\nint T[N][N];\nint P[N][N];\n\nstruct State {\n    int r, c;\n    int score;\n    uint64_t visited_tiles[NUM_U64];\n    int prev_idx;\n    char move;\n    float heuristic;\n    int visited_count;\n};\n\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nstring global_best_path = \"\";\nint global_best_score = -1;\n\nvoid solve_beam(int w_rem, int w_nscore, int w_nconn, int beam_width, vector<State>& all_states) {\n    all_states.clear();\n    \n    // Initialize the starting state\n    State start;\n    start.r = si; start.c = sj;\n    start.score = P[si][sj];\n    memset(start.visited_tiles, 0, sizeof(start.visited_tiles));\n    int st = T[si][sj];\n    start.visited_tiles[st / 64] |= (1ULL << (st % 64));\n    start.prev_idx = -1;\n    start.move = ' ';\n    start.visited_count = 1;\n    start.heuristic = 0.0f;\n    all_states.push_back(start);\n\n    vector<int> current_beam;\n    current_beam.push_back(0);\n\n    int best_idx_in_run = 0;\n\n    // Iterate path steps (at most total tiles)\n    for (int step = 0; step < 2500; ++step) {\n        if (current_beam.empty()) break;\n\n        vector<int> candidates_by_move[4];\n        vector<int> global_candidates;\n\n        for (int idx : current_beam) {\n            const State& s = all_states[idx];\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i], nc = s.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int nt = T[nr][nc];\n                    if (!(s.visited_tiles[nt / 64] & (1ULL << (nt % 64)))) {\n                        State next_s;\n                        next_s.r = nr; next_s.c = nc;\n                        next_s.score = s.score + P[nr][nc];\n                        memcpy(next_s.visited_tiles, s.visited_tiles, sizeof(next_s.visited_tiles));\n                        next_s.visited_tiles[nt / 64] |= (1ULL << (nt % 64));\n                        next_s.prev_idx = idx;\n                        next_s.move = move_char[i];\n                        next_s.visited_count = s.visited_count + 1;\n\n                        int n_score = 0, n_conn = 0;\n                        for (int j = 0; j < 4; ++j) {\n                            int nnr = nr + dr[j], nnc = nc + dc[j];\n                            if (nnr >= 0 && nnr < N && nnc >= 0 && nnc < N) {\n                                int nnt = T[nnr][nnc];\n                                if (!(next_s.visited_tiles[nnt / 64] & (1ULL << (nnt % 64)))) {\n                                    n_score += P[nnr][nnc];\n                                    n_conn++;\n                                }\n                            }\n                        }\n                        // Heuristic calculation\n                        next_s.heuristic = (float)next_s.score + \n                                           (float)w_rem * (MAX_TILES - next_s.visited_count) + \n                                           (float)w_nscore * n_score + \n                                           (float)w_nconn * n_conn;\n\n                        int new_idx = all_states.size();\n                        all_states.push_back(next_s);\n                        candidates_by_move[i].push_back(new_idx);\n                        global_candidates.push_back(new_idx);\n\n                        if (all_states.back().score > all_states[best_idx_in_run].score) {\n                            best_idx_in_run = new_idx;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (global_candidates.empty()) break;\n\n        // Diversity-based selection for the next beam\n        current_beam.clear();\n        int per_dir = beam_width / 5;\n        if (per_dir < 1) per_dir = 1;\n        \n        for (int i = 0; i < 4; ++i) {\n            if (candidates_by_move[i].empty()) continue;\n            sort(candidates_by_move[i].begin(), candidates_by_move[i].end(), [&](int a, int b) {\n                return all_states[a].heuristic > all_states[b].heuristic;\n            });\n            int take = min((int)candidates_by_move[i].size(), per_dir);\n            for (int j = 0; j < take; ++j) current_beam.push_back(candidates_by_move[i][j]);\n        }\n\n        // Add global top candidates to ensure quality\n        sort(global_candidates.begin(), global_candidates.end(), [&](int a, int b) {\n            return all_states[a].heuristic > all_states[b].heuristic;\n        });\n        int remaining_slots = beam_width - (int)current_beam.size();\n        if (remaining_slots > 0) {\n            int take_global = min((int)global_candidates.size(), remaining_slots);\n            for (int i = 0; i < take_global; ++i) current_beam.push_back(global_candidates[i]);\n        }\n\n        // Cleanup beam: remove duplicates and ensure limit\n        sort(current_beam.begin(), current_beam.end());\n        current_beam.erase(unique(current_beam.begin(), current_beam.end()), current_beam.end());\n\n        if (current_beam.size() > (size_t)beam_width) {\n            sort(current_beam.begin(), current_beam.end(), [&](int a, int b) {\n                return all_states[a].heuristic > all_states[b].heuristic;\n            });\n            current_beam.resize(beam_width);\n        }\n    }\n\n    // Update global best path\n    if (all_states[best_idx_in_run].score > global_best_score) {\n        global_best_score = all_states[best_idx_in_run].score;\n        string path = \"\";\n        int curr = best_idx_in_run;\n        while (curr != -1 && all_states[curr].prev_idx != -1) {\n            path += all_states[curr].move;\n            curr = all_states[curr].prev_idx;\n        }\n        reverse(path.begin(), path.end());\n        global_best_path = path;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> si >> sj)) return 0;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) cin >> T[i][j];\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) cin >> P[i][j];\n\n    clock_t start_time = clock();\n    mt19937 rng(1337);\n    \n    // Randomizing parameters for different search characteristics in each trial\n    uniform_int_distribution<int> dist_w1(15, 35);   // Weight for remaining tile potential\n    uniform_int_distribution<int> dist_w2(1, 3);     // Weight for local square value\n    uniform_int_distribution<int> dist_w3(5, 15);    // Weight for connectivity\n    uniform_int_distribution<int> dist_bw(40, 70);   // Beam width\n\n    vector<State> all_states;\n    all_states.reserve(1000000);\n\n    while (true) {\n        if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 1.85) break;\n        solve_beam(dist_w1(rng), dist_w2(rng), dist_w3(rng), dist_bw(rng), all_states);\n    }\n\n    cout << global_best_path << endl;\n\n    return 0;\n}\n","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\n\n// Hierarchical model parameters\n// h[i][j] = H[i] + delta_h[i][j]\n// v[i][j] = V[j] + gamma_v[i][j]\ndouble H[N], V[N];\ndouble delta_h[N][N - 1], gamma_v[N - 1][N];\n\n// Momentum velocities\ndouble vH[N], vV[N];\ndouble vdh[N][N - 1], vdv[N - 1][N];\n\nstruct Node {\n    double d;\n    int r, c;\n    bool operator>(const Node& other) const { return d > other.d; }\n};\n\nstruct Parent {\n    int r, c;\n    char dir;\n};\n\nParent parent[N][N];\ndouble dists[N][N];\n\n// Dijkstra's algorithm to find the shortest path using current estimates\nvoid dijkstra(int sr, int sc, int tr, int tc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j] = INF;\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[sr][sc] = 0;\n    pq.push({0.0, sr, sc});\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    while (!pq.empty()) {\n        Node top = pq.top();\n        pq.pop();\n\n        int r = top.r;\n        int c = top.c;\n        double d = top.d;\n\n        if (d > dists[r][c]) continue;\n        if (r == tr && c == tc) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = 0;\n                if (dirs[i] == 'U') weight = V[c] + gamma_v[nr][c];\n                else if (dirs[i] == 'D') weight = V[c] + gamma_v[r][c];\n                else if (dirs[i] == 'L') weight = H[r] + delta_h[r][nc];\n                else if (dirs[i] == 'R') weight = H[r] + delta_h[r][c];\n\n                if (dists[nr][nc] > d + weight) {\n                    dists[nr][nc] = d + weight;\n                    parent[nr][nc] = {r, c, dirs[i]};\n                    pq.push({dists[nr][nc], nr, nc});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialization\n    for (int i = 0; i < N; ++i) {\n        H[i] = 5000.0; vH[i] = 0.0;\n        for (int j = 0; j < N - 1; ++j) { delta_h[i][j] = 0.0; vdh[i][j] = 0.0; }\n    }\n    for (int j = 0; j < N; ++j) {\n        V[j] = 5000.0; vV[j] = 0.0;\n        for (int i = 0; i < N - 1; ++i) { gamma_v[i][j] = 0.0; vdv[i][j] = 0.0; }\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        dijkstra(si, sj, ti, tj);\n\n        string path = \"\";\n        int cr = ti, cc = tj;\n        while (cr != si || cc != sj) {\n            Parent p = parent[cr][cc];\n            path += p.dir;\n            cr = p.r; cc = p.c;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << \"\\n\" << flush;\n\n        long long L_k;\n        if (!(cin >> L_k)) break;\n\n        double est_len = 0;\n        cr = si; cc = sj;\n        for (char d : path) {\n            if (d == 'U') { est_len += V[cc] + gamma_v[cr - 1][cc]; cr--; }\n            else if (d == 'D') { est_len += V[cc] + gamma_v[cr][cc]; cr++; }\n            else if (d == 'L') { est_len += H[cr] + delta_h[cr][cc - 1]; cc--; }\n            else if (d == 'R') { est_len += H[cr] + delta_h[cr][cc]; cc++; }\n        }\n\n        double diff = (double)L_k - est_len;\n        double eta_k = 2.0 * pow(0.997, k); \n        double alpha = 0.1; // Low alpha handles M=2 case by letting deviations absorb splits\n        double step = (diff / (double)path.size()) * eta_k;\n        \n        double beta_base = 0.9; // High momentum for shared base\n        double beta_dev = 0.5;  // Lower momentum for local deviations\n\n        cr = si; cc = sj;\n        for (char d : path) {\n            double g_base = step * alpha;\n            double g_dev = step * (1.0 - alpha);\n            if (d == 'U') {\n                vV[cc] = beta_base * vV[cc] + (1.0 - beta_base) * g_base;\n                V[cc] += vV[cc];\n                vdv[cr - 1][cc] = beta_dev * vdv[cr - 1][cc] + (1.0 - beta_dev) * g_dev;\n                gamma_v[cr - 1][cc] += vdv[cr - 1][cc];\n                cr--;\n            } else if (d == 'D') {\n                vV[cc] = beta_base * vV[cc] + (1.0 - beta_base) * g_base;\n                V[cc] += vV[cc];\n                vdv[cr][cc] = beta_dev * vdv[cr][cc] + (1.0 - beta_dev) * g_dev;\n                gamma_v[cr][cc] += vdv[cr][cc];\n                cr++;\n            } else if (d == 'L') {\n                vH[cr] = beta_base * vH[cr] + (1.0 - beta_base) * g_base;\n                H[cr] += vH[cr];\n                vdh[cr][cc - 1] = beta_dev * vdh[cr][cc - 1] + (1.0 - beta_dev) * g_dev;\n                delta_h[cr][cc - 1] += vdh[cr][cc - 1];\n                cc--;\n            } else if (d == 'R') {\n                vH[cr] = beta_base * vH[cr] + (1.0 - beta_base) * g_base;\n                H[cr] += vH[cr];\n                vdh[cr][cc] = beta_dev * vdh[cr][cc] + (1.0 - beta_dev) * g_dev;\n                delta_h[cr][cc] += vdh[cr][cc];\n                cc++;\n            }\n        }\n\n        // Clamping for stability\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                if (H[i] + delta_h[i][j] < 50.0) {\n                    double fix = 50.0 - (H[i] + delta_h[i][j]);\n                    H[i] += fix * 0.1; delta_h[i][j] += fix * 0.9;\n                }\n            }\n            if (i < N - 1) {\n                for (int j = 0; j < N; ++j) {\n                    if (V[j] + gamma_v[i][j] < 50.0) {\n                        double fix = 50.0 - (V[j] + gamma_v[i][j]);\n                        V[j] += fix * 0.1; gamma_v[i][j] += fix * 0.9;\n                    }\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Occ stores information about which string occurrence a cell belongs to.\nstruct Occ {\n    int m_idx;\n    int k;\n};\n\nstruct MismatchChange {\n    int m_idx;\n    int old_m;\n};\n\nstruct CountChange {\n    int k;\n    int old_counts_k;\n};\n\nint N, M;\nstring s[800];\nchar A[20][20];\nint mismatches[640000]; \nint counts[800];        \nint c_satisfied = 0;    \nvector<Occ> cell_occs[20][20][8];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) cin >> s[i];\n\n    mt19937 rng(42);\n    string chars = \"ABCDEFGH\";\n\n    // Initial random matrix\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = chars[rng() % 8];\n        }\n    }\n\n    // Pre-calculate mismatches and cell_occs\n    for (int k = 0; k < M; ++k) {\n        int len = (int)s[k].length();\n        for (int t = 0; t < 2; ++t) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    int m = 0;\n                    int m_idx = (k * 2 + t) * 400 + r * 20 + c;\n                    for (int p = 0; p < len; ++p) {\n                        int ni, nj;\n                        if (t == 0) { ni = r; nj = (c + p) % N; }\n                        else { ni = (r + p) % N; nj = c; }\n                        if (A[ni][nj] != s[k][p]) m++;\n                    }\n                    mismatches[m_idx] = m;\n                    if (m == 0) counts[k]++;\n                    \n                    for (int p = 0; p < len; ++p) {\n                        int ni, nj;\n                        if (t == 0) { ni = r; nj = (c + p) % N; }\n                        else { ni = (r + p) % N; nj = c; }\n                        int target_idx = (int)chars.find(s[k][p]);\n                        cell_occs[ni][nj][target_idx].push_back({m_idx, k});\n                    }\n                }\n            }\n        }\n    }\n\n    for (int k = 0; k < M; ++k) {\n        if (counts[k] > 0) c_satisfied++;\n    }\n\n    // Simulated Annealing phase\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 1.0;\n    double T_end = 0.001;\n\n    vector<MismatchChange> m_changes;\n    vector<CountChange> k_changes;\n    m_changes.reserve(3000);\n    k_changes.reserve(3000);\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n        if (elapsed > 2.7) break;\n\n        double T = T_start * pow(T_end / T_start, elapsed / 2.7);\n\n        int i = rng() % N;\n        int j = rng() % N;\n        char old_v = A[i][j];\n        char new_v = chars[rng() % 8];\n        if (old_v == new_v) continue;\n\n        int old_idx = (int)chars.find(old_v);\n        int new_idx = (int)chars.find(new_v);\n\n        m_changes.clear();\n        k_changes.clear();\n        int delta_c = 0;\n\n        // 1. Increase mismatches for those where target == old_v\n        for (auto& occ : cell_occs[i][j][old_idx]) {\n            m_changes.push_back({occ.m_idx, mismatches[occ.m_idx]});\n            if (mismatches[occ.m_idx] == 0) {\n                k_changes.push_back({occ.k, counts[occ.k]});\n                counts[occ.k]--;\n                if (counts[occ.k] == 0) delta_c--;\n            }\n            mismatches[occ.m_idx]++;\n        }\n        // 2. Decrease mismatches for those where target == new_v\n        for (auto& occ : cell_occs[i][j][new_idx]) {\n            m_changes.push_back({occ.m_idx, mismatches[occ.m_idx]});\n            if (mismatches[occ.m_idx] == 1) {\n                k_changes.push_back({occ.k, counts[occ.k]});\n                counts[occ.k]++;\n                if (counts[occ.k] == 1) delta_c++;\n            }\n            mismatches[occ.m_idx]--;\n        }\n\n        if (delta_c >= 0 || (T > 1e-9 && (double)rng() / rng.max() < exp((double)delta_c / T))) {\n            A[i][j] = new_v;\n            c_satisfied += delta_c;\n        } else {\n            // Rollback\n            for (int idx = (int)m_changes.size() - 1; idx >= 0; --idx) {\n                mismatches[m_changes[idx].m_idx] = m_changes[idx].old_m;\n            }\n            for (int idx = (int)k_changes.size() - 1; idx >= 0; --idx) {\n                counts[k_changes[idx].k] = k_changes[idx].old_counts_k;\n            }\n        }\n    }\n\n    // Phase 2: Maximize density (number of '.') if all strings are satisfied\n    if (c_satisfied == M) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (A[i][j] == '.') continue;\n                \n                static int hits[800];\n                static int hit_ks[800];\n                int hit_count = 0;\n                for (int k = 0; k < M; ++k) hits[k] = 0;\n\n                for (int c_idx = 0; c_idx < 8; ++c_idx) {\n                    for (auto& occ : cell_occs[i][j][c_idx]) {\n                        if (mismatches[occ.m_idx] == 0) {\n                            if (hits[occ.k] == 0) hit_ks[hit_count++] = occ.k;\n                            hits[occ.k]++;\n                        }\n                    }\n                }\n\n                bool can_be_dot = true;\n                for (int idx = 0; idx < hit_count; ++idx) {\n                    int k = hit_ks[idx];\n                    if (hits[k] == counts[k]) {\n                        can_be_dot = false;\n                        break;\n                    }\n                }\n\n                if (can_be_dot) {\n                    A[i][j] = '.';\n                    for (int idx = 0; idx < hit_count; ++idx) {\n                        int k = hit_ks[idx];\n                        counts[k] -= hits[k];\n                    }\n                    for (int c_idx = 0; c_idx < 8; ++c_idx) {\n                        for (auto& occ : cell_occs[i][j][c_idx]) {\n                            mismatches[occ.m_idx] = 100; \n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cout << A[i][j];\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to find a shortest patrol route that visits road squares such that\n * all road squares become \"visible\" at least once.\n * A square is visible if it's in the same row/column and no obstacles are between.\n * \n * Strategy:\n * 1. Represent the map and precompute visibility (which squares can see each other).\n * 2. Use a greedy strategy to pick a subset of road squares (ToVisit) that covers\n *    the most \"uncovered\" road squares with the minimum distance.\n * 3. The greedy heuristic: Pick the \"hardest-to-cover\" square (one with fewest \n *    potential visitors) and then pick the best visitor (maximizing newly covered / distance).\n * 4. Once the set of points to visit is found, solve the Traveling Salesperson Problem (TSP)\n *    on these points using a Nearest Neighbor heuristic followed by 2-opt refinement.\n * 5. Convert the TSP tour into the actual move string (U, D, L, R).\n */\n\nconst int INF = 1e9;\n\nint N, si, sj;\nint grid[70][70];\nvector<int> C[5000], S[5000];\nbool is_road[5000];\nint dists[5000];\nint parent_node[5000];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Standard Dijkstra to find shortest path distances from a source node\nvoid dijkstra(int start, int n_size) {\n    for (int i = 0; i < n_size; ++i) dists[i] = INF;\n    dists[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n\n    while (!pq.empty()) {\n        int d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n\n        if (d > dists[u]) continue;\n\n        int r = u / N, c = u % N;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != -1) {\n                int v = nr * N + nc;\n                if (dists[u] + grid[nr][nc] < dists[v]) {\n                    dists[v] = dists[u] + grid[nr][nc];\n                    parent_node[v] = u;\n                    pq.push({dists[v], v});\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> si >> sj)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            if (row[j] == '#') {\n                grid[i][j] = -1;\n                is_road[i * N + j] = false;\n            } else {\n                grid[i][j] = row[j] - '0';\n                is_road[i * N + j] = true;\n            }\n        }\n    }\n\n    // Precompute visibility\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!is_road[i * N + j]) continue;\n            int u = i * N + j;\n            C[u].push_back(u);\n            S[u].push_back(u);\n            // Horizontal\n            for (int k = j - 1; k >= 0 && grid[i][k] != -1; --k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = j + 1; k < N && grid[i][k] != -1; ++k) {\n                int v = i * N + k;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            // Vertical\n            for (int k = i - 1; k >= 0 && grid[k][j] != -1; --k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n            for (int k = i + 1; k < N && grid[k][j] != -1; ++k) {\n                int v = k * N + j;\n                C[u].push_back(v);\n                S[v].push_back(u);\n            }\n        }\n    }\n\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            sort(C[i].begin(), C[i].end());\n            C[i].erase(unique(C[i].begin(), C[i].end()), C[i].end());\n            sort(S[i].begin(), S[i].end());\n            S[i].erase(unique(S[i].begin(), S[i].end()), S[i].end());\n        }\n    }\n\n    // Set Cover Greedy\n    vector<bool> is_uncovered(N * N, false);\n    vector<int> uncovered_list;\n    for (int i = 0; i < N * N; ++i) {\n        if (is_road[i]) {\n            is_uncovered[i] = true;\n            uncovered_list.push_back(i);\n        }\n    }\n\n    vector<int> ToVisit;\n    int curr = si * N + sj;\n    while (!uncovered_list.empty()) {\n        dijkstra(curr, N * N);\n        int best_r = -1;\n        int min_S_r = 1000000;\n        for (int r : uncovered_list) {\n            if ((int)S[r].size() < min_S_r) {\n                min_S_r = S[r].size();\n                best_r = r;\n            }\n        }\n        if (best_r == -1) break;\n\n        int best_v = -1;\n        double best_gain = -1.0;\n        for (int v : S[best_r]) {\n            int gain = 0;\n            for (int road_idx : C[v]) {\n                if (is_uncovered[road_idx]) gain++;\n            }\n            double current_gain = (double)gain / (dists[v] + 1.0);\n            if (current_gain > best_gain) {\n                best_gain = current_gain;\n                best_v = v;\n            }\n        }\n        if (best_v == -1 || best_gain <= 0.0) break;\n\n        ToVisit.push_back(best_v);\n        for (int road_idx : C[best_v]) {\n            is_uncovered[road_idx] = false;\n        }\n        \n        vector<int> next_uncovered;\n        for (int r : uncovered_list) {\n            if (is_uncovered[r]) next_uncovered.push_back(r);\n        }\n        uncovered_list = next_uncovered;\n        curr = best_v;\n    }\n\n    // TSP Step: Nearest Neighbor + 2-opt\n    vector<int> P;\n    P.push_back(si * N + sj);\n    set<int> seen;\n    seen.insert(si * N + sj);\n    for (int v : ToVisit) {\n        if (seen.find(v) == seen.end()) {\n            P.push_back(v);\n            seen.insert(v);\n        }\n    }\n\n    int k_points = P.size();\n    vector<vector<int>> dist_matrix(k_points, vector<int>(k_points, INF));\n    for (int i = 0; i < k_points; ++i) {\n        dijkstra(P[i], N * N);\n        for (int j = 0; j < k_points; ++j) {\n            dist_matrix[i][j] = dists[P[j]];\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited_tsp(k_points, false);\n    int current_idx = 0;\n    tour.push_back(0);\n    visited_tsp[0] = true;\n    for (int step = 1; step < k_points; ++step) {\n        int next_idx = -1;\n        int min_d = INF;\n        for (int j = 0; j < k_points; ++j) {\n            if (!visited_tsp[j] && dist_matrix[current_idx][j] < min_d) {\n                min_d = dist_matrix[current_idx][j];\n                next_idx = j;\n            }\n        }\n        if (next_idx == -1) break;\n        tour.push_back(next_idx);\n        visited_tsp[next_idx] = true;\n        current_idx = next_idx;\n    }\n    tour.push_back(0);\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int sz = tour.size();\n        for (int i = 1; i < sz - 2; ++i) {\n            for (int j = i + 1; j < sz - 1; ++j) {\n                if (dist_matrix[tour[i - 1]][tour[i]] + dist_matrix[tour[j]][tour[j + 1]] >\n                    dist_matrix[tour[i - 1]][tour[j]] + dist_matrix[tour[i]][tour[j + 1]]) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Final Path Reconstruction\n    string final_route = \"\";\n    for (int i = 0; i < (int)tour.size() - 1; ++i) {\n        int u = P[tour[i]];\n        int v = P[tour[i+1]];\n        if (u == v) continue;\n        dijkstra(u, N * N);\n        vector<int> path_nodes;\n        int curr_node = v;\n        while (curr_node != u) {\n            path_nodes.push_back(curr_node);\n            curr_node = parent_node[curr_node];\n        }\n        reverse(path_nodes.begin(), path_nodes.end());\n        \n        int prev_r = u / N, prev_c = u % N;\n        for (int node : path_nodes) {\n            int nr = node / N, nc = node % N;\n            if (nr == prev_r + 1) final_route += 'D';\n            else if (nr == prev_r - 1) final_route += 'U';\n            else if (nc == prev_c + 1) final_route += 'R';\n            else if (nc == prev_c - 1) final_route += 'L';\n            prev_r = nr;\n            prev_c = nc;\n        }\n    }\n    cout << final_route << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis & Improvements:\n * \n * 1. Skill Estimation:\n *    - We use Stochastic Gradient Descent (SGD) to update the skill level estimates.\n *    - The expected time E[t_{i,j}] is approx max(1, w_{i,j}), where w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k}).\n *    - If the actual time T_{i,j} differs from the estimated E[t_{i,j}], we update the skill s_{j,k}\n *      for all k where d_{i,k} > s_{j,k}.\n *    - Update rule: s_{j,k} = s_{j,k} - eta * (T_{i,j} - E[t_{i,j}]) * ( (d_{i,k} - s_{j,k}) / w_{i,j} ).\n * \n * 2. Task Prioritization (Critical Path Method):\n *    - Instead of a static rank, we use a dynamic Critical Path (CP) estimate.\n *    - CP(i) = AvgT(i) + max_{v in adj(i)} CP(v), where AvgT(i) is the average expected time for task i across all members.\n *    - This CP is recalculated every day to reflect our current understanding of the members' skills.\n * \n * 3. Greedy Scheduling Strategy:\n *    - We sort the available tasks by their dynamic CP value in descending order.\n *    - For each task in the sorted list, we assign it to the currently idle member who can complete it most quickly.\n *    - This ensures that critical tasks are prioritized and assigned to the most efficient available members.\n * \n * 4. Computational Efficiency:\n *    - Calculating CP and expected times takes O(N*M*K) per day.\n *    - Sorting and greedy matching take O(N*log N + N*M*K).\n *    - Total complexity is O(Days * N * M * K), which is roughly 2000 * 1000 * 20 * 20 = 8e8 operations.\n *    - This fits within the 3.0s time limit in C++.\n */\n\nint main() {\n    // Fast I/O for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task requirement skill levels\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    // Task dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // Topological sort to calculate CP in correct order\n    vector<int> topo_order;\n    vector<int> temp_in_degree = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (temp_in_degree[i] == 0) q.push(i);\n    }\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        topo_order.push_back(u);\n        for (int v : adj[u]) {\n            if (--temp_in_degree[v] == 0) q.push(v);\n        }\n    }\n\n    // State management\n    vector<vector<double>> s(M, vector<double>(K, 0.0)); // Skill level estimates\n    vector<int> task_status(N, 0);        // 0: not started, 1: in progress, 2: completed\n    vector<int> member_current_task(M, -1); // -1 if idle, else task index\n    vector<int> task_start_day(N, 0);     // Start day of task i\n    vector<vector<double>> E_t(N, vector<double>(M)); // Expected time for task i by member j\n    vector<double> avg_t(N);              // Average expected time for task i\n    vector<double> cp(N);                 // Critical path value for task i\n\n    int current_day = 1;\n    while (current_day <= 2000) {\n        // 1. Recalculate expected times and average task time\n        for (int i = 0; i < N; ++i) {\n            double sum_e = 0;\n            for (int j = 0; j < M; ++j) {\n                double w_ij = 0;\n                for (int k = 0; k < K; ++k) {\n                    double diff = (double)d[i][k] - s[j][k];\n                    if (diff > 0) w_ij += diff;\n                }\n                E_t[i][j] = (w_ij < 1.0 ? 1.0 : w_ij);\n                sum_e += E_t[i][j];\n            }\n            avg_t[i] = sum_e / M;\n        }\n\n        // 2. Recalculate Critical Path (CP) values using topological order\n        for (int i = N - 1; i >= 0; --i) {\n            int u = topo_order[i];\n            double max_next_cp = 0;\n            for (int v : adj[u]) {\n                if (cp[v] > max_next_cp) max_next_cp = cp[v];\n            }\n            cp[u] = avg_t[u] + max_next_cp;\n        }\n\n        // 3. Identify available tasks and idle members\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] == 0 && in_degree[i] == 0) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_current_task[j] == -1) {\n                idle_members.push_back(j);\n            }\n        }\n\n        // 4. Greedy matching based on task priority (CP) and speed (E[t])\n        // Sort available tasks by Critical Path value descending\n        sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n            return cp[a] > cp[b];\n        });\n\n        struct Assignment {\n            int m, t;\n        };\n        vector<Assignment> current_day_assignments;\n        vector<bool> member_used_today(M, false);\n\n        for (int i : available_tasks) {\n            int best_j = -1;\n            double min_et = 1e18;\n\n            for (int j : idle_members) {\n                if (member_used_today[j]) continue;\n                if (E_t[i][j] < min_et) {\n                    min_et = E_t[i][j];\n                    best_j = j;\n                }\n            }\n\n            if (best_j != -1) {\n                current_day_assignments.push_back({best_j, i});\n                member_used_today[best_j] = true;\n                task_status[i] = 1;\n                member_current_task[best_j] = i;\n                task_start_day[i] = current_day;\n            }\n        }\n\n        // 5. Output the assignments\n        cout << current_day_assignments.size();\n        for (auto& assign : current_day_assignments) {\n            cout << \" \" << assign.m + 1 << \" \" << assign.t + 1;\n        }\n        cout << endl;\n\n        // 6. Read feedback on completed tasks\n        int num_completed;\n        if (!(cin >> num_completed)) break;\n        if (num_completed == -1) break;\n\n        // 7. Update skill estimates (SGD) and task dependencies\n        for (int idx = 0; idx < num_completed; ++idx) {\n            int f;\n            cin >> f;\n            --f; // 0-indexed member\n            int t_idx = member_current_task[f];\n            int actual_t = current_day - task_start_day[t_idx] + 1;\n\n            // Recalculate current w_ij estimate for error calculation\n            double w_ij_est = 0;\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) w_ij_est += diff;\n            }\n            if (w_ij_est < 1e-7) w_ij_est = 1e-7; // Prevent division by zero\n\n            double error = (double)actual_t - E_t[t_idx][f];\n            double eta = 0.2 / (1.0 + 0.005 * current_day); // Learning rate decay\n\n            // Refined SGD update for skill levels\n            for (int k = 0; k < K; ++k) {\n                double diff = (double)d[t_idx][k] - s[f][k];\n                if (diff > 0) {\n                    double contribution = diff / w_ij_est;\n                    s[f][k] -= eta * error * contribution;\n                    if (s[f][k] < 0) s[f][k] = 0;\n                }\n            }\n\n            // Mark task as completed and update dependency graph\n            task_status[t_idx] = 2;\n            member_current_task[f] = -1;\n            for (int v : adj[t_idx]) {\n                in_degree[v]--;\n            }\n        }\n        current_day++;\n    }\n\n    return 0;\n}\n","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Pickup and Delivery Problem (PDP)\n * Given 1000 orders, select 50 and find a Manhattan-distance route starting/ending at (400, 400).\n * Precedence constraint: For each selected order, pickup (a, b) must be visited before delivery (c, d).\n * \n * Strategy: Simulated Annealing (SA)\n * - Initial state: Pick 50 orders with the smallest individual round-trip distance.\n * - Moves:\n *   1. Swap: Swap two points in the current sequence.\n *   2. Reinsert: Move a point to a new position in the sequence.\n *   3. Replace: Replace one order's pickup/delivery with a new order's pickup/delivery at the same positions.\n * - Optimization:\n *   - Use fast total_dist calculation (O(N)).\n *   - Maintain posA and posC to check precedence in O(1).\n *   - Ensure all moves respect the precedence constraints.\n */\n\nstruct Order {\n    int a, b, c, d, id;\n};\n\nstruct Point {\n    int x, y, order_idx;\n    bool is_pickup;\n};\n\ninline int dist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint total_dist(const vector<Point>& P) {\n    if (P.empty()) return 0;\n    int d = 0;\n    d += dist(400, 400, P[0].x, P[0].y);\n    for (size_t i = 0; i < P.size() - 1; ++i) {\n        d += dist(P[i].x, P[i].y, P[i + 1].x, P[i + 1].y);\n    }\n    d += dist(P.back().x, P.back().y, 400, 400);\n    return d;\n}\n\nint posA[1000], posC[1000];\n\nvoid update_all_pos(const vector<Point>& P) {\n    for (int i = 0; i < 1000; ++i) posA[i] = posC[i] = -1;\n    for (int i = 0; i < (int)P.size(); ++i) {\n        if (P[i].is_pickup) posA[P[i].order_idx] = i;\n        else posC[P[i].order_idx] = i;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<Order> all_orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        if (!(cin >> all_orders[i].a >> all_orders[i].b >> all_orders[i].c >> all_orders[i].d)) break;\n        all_orders[i].id = i + 1;\n    }\n\n    // Heuristic for initial subset selection\n    vector<pair<int, int>> costs;\n    for (int i = 0; i < 1000; ++i) {\n        int d = dist(400, 400, all_orders[i].a, all_orders[i].b) +\n                dist(all_orders[i].a, all_orders[i].b, all_orders[i].c, all_orders[i].d) +\n                dist(all_orders[i].c, all_orders[i].d, 400, 400);\n        costs.push_back({d, i});\n    }\n    sort(costs.begin(), costs.end());\n\n    vector<int> S, not_S;\n    vector<bool> in_S(1000, false);\n    for (int i = 0; i < 50; ++i) {\n        S.push_back(costs[i].second);\n        in_S[costs[i].second] = true;\n    }\n    for (int i = 0; i < 1000; ++i) {\n        if (!in_S[i]) not_S.push_back(i);\n    }\n\n    // Initial sequence\n    vector<Point> P;\n    for (int idx : S) {\n        P.push_back({all_orders[idx].a, all_orders[idx].b, idx, true});\n        P.push_back({all_orders[idx].c, all_orders[idx].d, idx, false});\n    }\n    update_all_pos(P);\n\n    int current_dist = total_dist(P);\n    vector<Point> best_P = P;\n    vector<int> best_S = S;\n    int best_dist = current_dist;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 1000.0;\n    double T_end = 0.1;\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        if (iter % 2000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n            if (elapsed >= 1.0) break;\n        }\n\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1900.0;\n        double T = T_start * pow(T_end / T_start, elapsed);\n\n        int move_type = rng() % 100;\n        if (move_type < 40) { // Type 0: Swap two points\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            int ord_j = P[j].order_idx;\n            swap(P[i], P[j]);\n\n            // Check if swap satisfies precedence for involved orders\n            int pi = -1, ci = -1, pj = -1, cj = -1;\n            for(int k=0; k<(int)P.size(); ++k) {\n                if(P[k].order_idx == ord_i) {\n                    if(P[k].is_pickup) pi = k; else ci = k;\n                }\n                if(P[k].order_idx == ord_j) {\n                    if(P[k].is_pickup) pj = k; else cj = k;\n                }\n            }\n\n            if (pi != -1 && ci != -1 && pi < ci && pj != -1 && cj != -1 && pj < cj) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    update_all_pos(P);\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    swap(P[i], P[j]);\n                }\n            } else {\n                swap(P[i], P[j]);\n            }\n        } else if (move_type < 70) { // Type 1: Reinsert a point\n            int i = rng() % P.size();\n            int j = rng() % P.size();\n            if (i == j) continue;\n            int ord_i = P[i].order_idx;\n            Point p = P[i];\n            P.erase(P.begin() + i);\n            P.insert(P.begin() + j, p);\n\n            int pi = -1, ci = -1;\n            for(int k=0; k<(int)P.size(); ++k) {\n                if(P[k].order_idx == ord_i) {\n                    if(P[k].is_pickup) pi = k; else ci = k;\n                }\n            }\n            if (pi != -1 && ci != -1 && pi < ci) {\n                int new_dist = total_dist(P);\n                if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                    current_dist = new_dist;\n                    update_all_pos(P);\n                    if (current_dist < best_dist) {\n                        best_dist = current_dist;\n                        best_P = P;\n                        best_S = S;\n                    }\n                } else {\n                    P.erase(P.begin() + j);\n                    P.insert(P.begin() + i, p);\n                }\n            } else {\n                P.erase(P.begin() + j);\n                P.insert(P.begin() + i, p);\n            }\n        } else { // Type 2: Replace order points\n            int i_idx = rng() % 50;\n            int j_idx = rng() % (int)not_S.size();\n            int old_ord = S[i_idx];\n            int new_ord = not_S[j_idx];\n\n            int pa = posA[old_ord];\n            int pc = posC[old_ord];\n            if (pa == -1 || pc == -1) continue;\n\n            vector<Point> old_P_state = P;\n            int old_S_val = S[i_idx];\n            int old_not_S_val = not_S[j_idx];\n\n            P[pa] = {all_orders[new_ord].a, all_orders[new_ord].b, new_ord, true};\n            P[pc] = {all_orders[new_ord].c, all_orders[new_ord].d, new_ord, false};\n            S[i_idx] = new_ord;\n            not_S[j_idx] = old_ord;\n\n            int new_dist = total_dist(P);\n            if (new_dist < current_dist || exp((double)(current_dist - new_dist) / T) > (double)rng() / mt19937::max()) {\n                current_dist = new_dist;\n                update_all_pos(P);\n                if (current_dist < best_dist) {\n                    best_dist = current_dist;\n                    best_P = P;\n                    best_S = S;\n                }\n            } else {\n                P = old_P_state;\n                S[i_idx] = old_S_val;\n                not_S[j_idx] = old_not_S_val;\n            }\n        }\n    }\n\n    cout << 50;\n    for (int idx : best_S) cout << \" \" << all_orders[idx].id;\n    cout << endl;\n    cout << best_P.size() + 2;\n    cout << \" 400 400\";\n    for (const auto& p : best_P) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \" 400 400\" << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem: Online Minimum Spanning Tree with uncertain future edge weights.\n * Strategy: Monte Carlo simulation to estimate the bottleneck weight of alternative paths.\n * Complexity: O(M * K * M log M), where M is the number of edges and K is the number of samples.\n * With M=2000 and K=10, total operations are approximately 4e8, fitting in 2s.\n */\n\n// Fast Disjoint Set Union (DSU) for bottleneck calculations\nstruct FastDSU {\n    int parent[405];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    int find(int i) {\n        int root = i;\n        while (parent[root] != root) root = parent[root];\n        while (parent[i] != root) {\n            int next = parent[i];\n            parent[i] = root;\n            i = next;\n        }\n        return root;\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v, d, l, id;\n};\n\nstruct SimEdge {\n    int u, v, w;\n    bool operator<(const SimEdge& other) const {\n        return w < other.w;\n    }\n};\n\n// Global buffers to avoid repeated allocations in the loop\nSimEdge sim_edges[2500];\nFastDSU dsu;\nFastDSU dsu_S;\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    const int N = 400;\n    const int M = 1995;\n    const int K = 10; // Number of Monte Carlo samples\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> coords[i].first >> coords[i].second)) break;\n    }\n\n    vector<Edge> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) break;\n        all_edges[i].u = u;\n        all_edges[i].v = v;\n        all_edges[i].id = i;\n        double dx = (double)coords[u].first - coords[v].first;\n        double dy = (double)coords[u].second - coords[v].second;\n        all_edges[i].d = (int)round(hypot(dx, dy));\n    }\n\n    vector<int> S;\n    S.reserve(N);\n    dsu_S.init(N);\n\n    // Random number generator for sampling future weights\n    mt19937 rng(42);\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n        all_edges[i].l = l_i;\n\n        int u_i = all_edges[i].u;\n        int v_i = all_edges[i].v;\n\n        // If u and v are already connected, adding this edge only adds cost.\n        if (dsu_S.find(u_i) == dsu_S.find(v_i)) {\n            cout << \"0\" << endl; // endl performs flush\n        } else {\n            int Ws[K];\n            for (int k = 0; k < K; ++k) {\n                int edge_count = 0;\n                // 1. Include edges already adopted in our MST\n                for (int idx : S) {\n                    sim_edges[edge_count++] = {all_edges[idx].u, all_edges[idx].v, all_edges[idx].l};\n                }\n                // 2. Include future edges with sampled weights\n                for (int j = i + 1; j < M; ++j) {\n                    int d_j = all_edges[j].d;\n                    // Sample weight uniformly from [d_j, 3*d_j]\n                    int weight = d_j + (rng() % (2 * d_j + 1));\n                    sim_edges[edge_count++] = {all_edges[j].u, all_edges[j].v, weight};\n                }\n\n                // 3. Sort edges to find the bottleneck weight using Kruskal's logic\n                sort(sim_edges, sim_edges + edge_count);\n\n                dsu.init(N);\n                int W_k = 2000000000; // Infinity placeholder\n                for (int e = 0; e < edge_count; ++e) {\n                    dsu.unite(sim_edges[e].u, sim_edges[e].v);\n                    if (dsu.find(u_i) == dsu.find(v_i)) {\n                        W_k = sim_edges[e].w;\n                        break;\n                    }\n                }\n                Ws[k] = W_k;\n            }\n\n            // 4. Use the median of simulated bottlenecks as the decision threshold\n            sort(Ws, Ws + K);\n            int W_median = Ws[K / 2];\n\n            if (l_i < W_median) {\n                cout << \"1\" << endl;\n                S.push_back(i);\n                dsu_S.unite(u_i, v_i);\n            } else {\n                cout << \"0\" << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * Goal: Maximize human satisfaction score.\n * Scoring: s_i = (|R_i| / 900) * 2^(-n_i), where |R_i| is the reachable area for human i \n * and n_i is the number of pets in that area.\n * Key Strategy:\n * 1. Maintain n_i = 0 by enclosing the human in a wall.\n * 2. The \"impassable\" action is powerful but restricted by the \"no pet or adjacent square has a pet\" rule.\n * 3. Use each human to target and build a boundary of a large rectangle containing them and no pets.\n * 4. Manage simultaneous actions and conflicts (two people building the same square, or moving into a square being blocked).\n */\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& other) const { return x == other.x && y == other.y; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nstruct Pet {\n    Pos p;\n    int type;\n};\n\nstruct Human {\n    Pos p;\n    int id;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool impassable[31][31];\n\nbool is_valid(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\n// Checks if a square is safe to make impassable\nbool is_safe(int x, int y, const vector<Pet>& cur_pets, const vector<Human>& cur_humans) {\n    if (!is_valid(x, y) || impassable[x][y]) return false;\n    for (const auto& p : cur_pets) {\n        if (p.p.x == x && p.p.y == y) return false;\n        // The square or any adjacent square cannot contain a pet.\n        if (abs(p.p.x - x) + abs(p.p.y - y) <= 1) return false;\n    }\n    for (const auto& h : cur_humans) {\n        if (h.p.x == x && h.p.y == y) return false;\n    }\n    return true;\n}\n\n// BFS to find a path of passable squares\nvector<Pos> get_path(Pos start, Pos end) {\n    if (start == end) return {};\n    queue<Pos> q;\n    q.push(start);\n    vector<vector<Pos>> parent(31, vector<Pos>(31, {0, 0}));\n    vector<vector<bool>> visited(31, vector<bool>(31, false));\n    visited[start.x][start.y] = true;\n    bool found = false;\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n        if (curr == end) {\n            found = true;\n            break;\n        }\n        int dx[] = {-1, 1, 0, 0};\n        int dy[] = {0, 0, -1, 1};\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.x + dx[i], ny = curr.y + dy[i];\n            if (is_valid(nx, ny) && !visited[nx][ny] && !impassable[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n    if (!found) return {};\n    vector<Pos> path;\n    Pos curr = end;\n    while (curr != start) {\n        path.push_back(curr);\n        curr = parent[curr.x][curr.y];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    pets.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pets[i].p.x >> pets[i].p.y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humans[i].p.x >> humans[i].p.y;\n        humans[i].id = i;\n    }\n\n    for (int i = 1; i <= 30; ++i)\n        for (int j = 1; j <= 30; ++j)\n            impassable[i][j] = false;\n\n    // Pre-calculate potential boundaries (rectangles with no pets containing the human)\n    vector<vector<Pos>> human_boundaries(M);\n    for (int i = 0; i < M; ++i) {\n        int max_area = 0;\n        Rect best_rect = {humans[i].p.x, humans[i].p.y, humans[i].p.x, humans[i].p.y};\n        for (int x1 = 1; x1 <= humans[i].p.x; ++x1) {\n            for (int x2 = humans[i].p.x; x2 <= 30; ++x2) {\n                for (int y1 = 1; y1 <= humans[i].p.y; ++y1) {\n                    for (int y2 = humans[i].p.y; y2 <= 30; ++y2) {\n                        bool has_pet = false;\n                        for (const auto& pet : pets) {\n                            if (pet.p.x >= x1 && pet.p.x <= x2 && pet.p.y >= y1 && pet.p.y <= y2) {\n                                has_pet = true; break;\n                            }\n                        }\n                        if (!has_pet) {\n                            int area = (x2 - x1 + 1) * (y2 - y1 + 1);\n                            if (area > max_area) {\n                                max_area = area;\n                                best_rect = {x1, y1, x2, y2};\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for (int x = best_rect.x1; x <= best_rect.x2; ++x) {\n            human_boundaries[i].push_back({x, best_rect.y1});\n            human_boundaries[i].push_back({x, best_rect.y2});\n        }\n        for (int y = best_rect.y1 + 1; y < best_rect.y2; ++y) {\n            human_boundaries[i].push_back({best_rect.x1, y});\n            human_boundaries[i].push_back({best_rect.x2, y});\n        }\n        sort(human_boundaries[i].begin(), human_boundaries[i].end(), [](Pos a, Pos b) {\n            return a.x < b.x || (a.x == b.x && a.y < b.y);\n        });\n        human_boundaries[i].erase(unique(human_boundaries[i].begin(), human_boundaries[i].end()), human_boundaries[i].end());\n    }\n\n    for (int turn = 0; turn < 300; ++turn) {\n        struct IntendedAction {\n            char type; // 'B' build, 'M' move, '.' nothing\n            Pos target_impassable;\n            Pos move_to;\n        };\n        vector<IntendedAction> intended(M, {'.', {0, 0}, {0, 0}});\n\n        for (int i = 0; i < M; ++i) {\n            Pos best_T = {0, 0};\n            int min_dist = 1000;\n            for (const auto& T : human_boundaries[i]) {\n                if (is_safe(T.x, T.y, pets, humans)) {\n                    int d = abs(humans[i].p.x - T.x) + abs(humans[i].p.y - T.y);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_T = T;\n                    }\n                }\n            }\n\n            if (best_T.x != 0) {\n                if (min_dist == 1) {\n                    intended[i].type = 'B';\n                    intended[i].target_impassable = best_T;\n                } else {\n                    intended[i].type = 'M';\n                    intended[i].target_impassable = best_T;\n                    vector<Pos> path = get_path(humans[i].p, best_T);\n                    if (!path.empty()) {\n                        intended[i].move_to = path[0];\n                    } else {\n                        intended[i].type = '.';\n                    }\n                }\n            }\n        }\n\n        vector<char> final_actions(M, '.');\n        vector<Pos> actual_build_targets(M, {0, 0});\n\n        // Resolve build conflicts\n        vector<bool> build_taken(31 * 31, false);\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'B') {\n                int idx = intended[i].target_impassable.x * 31 + intended[i].target_impassable.y;\n                if (!build_taken[idx]) {\n                    build_taken[idx] = true;\n                    Pos h = humans[i].p;\n                    Pos t = intended[i].target_impassable;\n                    if (t.x == h.x - 1 && t.y == h.y) final_actions[i] = 'u';\n                    else if (t.x == h.x + 1 && t.y == h.y) final_actions[i] = 'd';\n                    else if (t.x == h.x && t.y == h.y - 1) final_actions[i] = 'l';\n                    else if (t.x == h.x && t.y == h.y + 1) final_actions[i] = 'r';\n                    actual_build_targets[i] = t;\n                } else {\n                    intended[i].type = '.';\n                }\n            }\n        }\n\n        // Resolve move conflicts\n        for (int i = 0; i < M; ++i) {\n            if (intended[i].type == 'M') {\n                Pos next_pos = intended[i].move_to;\n                bool blocked = false;\n                for (int j = 0; j < M; ++j) {\n                    if (intended[j].type == 'B' && intended[j].target_impassable == next_pos) {\n                        blocked = true; break;\n                    }\n                }\n                if (blocked) {\n                    final_actions[i] = '.';\n                } else {\n                    Pos h = humans[i].p;\n                    if (next_pos.x == h.x - 1 && next_pos.y == h.y) final_actions[i] = 'U';\n                    else if (next_pos.x == h.x + 1 && next_pos.y == h.y) final_actions[i] = 'D';\n                    else if (next_pos.x == h.x && next_pos.y == h.y - 1) final_actions[i] = 'L';\n                    else if (next_pos.x == h.x && next_pos.y == h.y + 1) final_actions[i] = 'R';\n                }\n            }\n        }\n\n        string out = \"\";\n        for (int i = 0; i < M; ++i) out += final_actions[i];\n        cout << out << endl;\n\n        for (int i = 0; i < M; ++i) {\n            if (final_actions[i] == 'U') humans[i].p.x--;\n            else if (final_actions[i] == 'D') humans[i].p.x++;\n            else if (final_actions[i] == 'L') humans[i].p.y--;\n            else if (final_actions[i] == 'R') humans[i].p.y++;\n            \n            if (final_actions[i] == 'u' || final_actions[i] == 'd' || final_actions[i] == 'l' || final_actions[i] == 'r') {\n                if (actual_build_targets[i].x != 0) {\n                    impassable[actual_build_targets[i].x][actual_build_targets[i].y] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; ++i) {\n            string move;\n            cin >> move;\n            for (char c : move) {\n                if (c == 'U') pets[i].p.x--;\n                else if (c == 'D') pets[i].p.x++;\n                else if (c == 'L') pets[i].p.y--;\n                else if (c == 'R') pets[i].p.y++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\n// Global variables for map and problem constraints\nint si, sj, ti, tj;\ndouble p_forget;\nbool wall_h[20][20], wall_v[20][20];\nint trans[400][4];\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\n// DP state arrays for efficient calculation\ndouble dp[400], next_dp[400];\nint active[400], next_active[400], active_cnt, next_cnt;\nbool in_next[400];\n\n// Precompute all possible movements for every square and direction\nvoid precompute_trans() {\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int u = r * 20 + c;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                bool blocked = false;\n                if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) blocked = true;\n                else if (dr[d] == 0) {\n                    if (wall_h[r][min(c, nc)]) blocked = true;\n                } else {\n                    if (wall_v[min(r, nr)][c]) blocked = true;\n                }\n                trans[u][d] = blocked ? u : (nr * 20 + nc);\n            }\n        }\n    }\n}\n\n// BFS to find the shortest path as a baseline\nstring get_shortest_path() {\n    queue<pair<pair<int, int>, string>> q;\n    q.push({{si, sj}, \"\"});\n    bool visited[20][20] = {false};\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto curr = q.front(); q.pop();\n        int r = curr.first.first, c = curr.first.second;\n        string path = curr.second;\n        if (r == ti && c == tj) return path;\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < 20 && nc >= 0 && nc < 20 && !visited[nr][nc]) {\n                bool blocked = false;\n                if (dr[i] == 0) { if (wall_h[r][min(c, nc)]) blocked = true; }\n                else { if (wall_v[min(r, nr)][c]) blocked = true; }\n                if (!blocked) {\n                    visited[nr][nc] = true;\n                    q.push({{nr, nc}, path + dir_char[i]});\n                }\n            }\n        }\n    }\n    return \"\";\n}\n\n// Optimized DP to compute the expected value E[401 - t]\ndouble calculate_expected_value(const string& S) {\n    if (S.length() > 200) return 0;\n    int office_idx = ti * 20 + tj, start_idx = si * 20 + sj;\n    for (int i = 0; i < 400; ++i) dp[i] = 0;\n    dp[start_idx] = 1.0;\n    active_cnt = 1; active[0] = start_idx;\n    double expected_val = 0;\n\n    for (int t = 0; t < (int)S.length(); ++t) {\n        next_cnt = 0;\n        int d = (S[t] == 'U' ? 0 : (S[t] == 'D' ? 1 : (S[t] == 'L' ? 2 : 3)));\n        memset(next_dp, 0, sizeof(next_dp));\n        memset(in_next, 0, sizeof(in_next));\n\n        for (int i = 0; i < active_cnt; ++i) {\n            int u = active[i];\n            if (u == office_idx) continue;\n            double p_u = dp[u];\n            int v = trans[u][d];\n            if (v == u) { // Blocked\n                if (!in_next[u]) { in_next[u] = true; next_active[next_cnt++] = u; }\n                next_dp[u] += p_u;\n            } else { // Not blocked\n                if (!in_next[u]) { in_next[u] = true; next_active[next_cnt++] = u; }\n                next_dp[u] += p_u * p_forget;\n                if (v == office_idx) expected_val += p_u * (1.0 - p_forget) * (401 - (t + 1));\n                else {\n                    if (!in_next[v]) { in_next[v] = true; next_active[next_cnt++] = v; }\n                    next_dp[v] += p_u * (1.0 - p_forget);\n                }\n            }\n        }\n        for (int i = 0; i < active_cnt; ++i) dp[active[i]] = 0;\n        active_cnt = next_cnt;\n        for (int i = 0; i < active_cnt; ++i) {\n            int v = next_active[i];\n            dp[v] = next_dp[v];\n            active[i] = v;\n        }\n        if (active_cnt == 0) break;\n    }\n    return expected_val;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    for (int i = 0; i < 20; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < 19; ++j) wall_h[i][j] = (row[j] == '1');\n    }\n    for (int i = 0; i < 19; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < 20; ++j) wall_v[i][j] = (row[j] == '1');\n    }\n\n    precompute_trans();\n    string base_path = get_shortest_path();\n    string best_S = base_path;\n    double best_E = calculate_expected_value(best_S);\n\n    for (int k = 2; k <= 4; ++k) {\n        string enriched = \"\";\n        for (char c : base_path) for (int count = 0; count < k; ++count) enriched += c;\n        if (enriched.length() <= 200) {\n            double e = calculate_expected_value(enriched);\n            if (e > best_E) { best_E = e; best_S = enriched; }\n        }\n    }\n\n    string current_S = best_S;\n    double current_E = best_E;\n    mt19937 rng(1337);\n    clock_t start_time = clock();\n    const double max_time = 1.9;\n\n    while (true) {\n        double elapsed = (double)(clock() - start_time) / CLOCKS_PER_SEC;\n        if (elapsed > max_time) break;\n        double T = 2.0 * (1.0 - elapsed / max_time);\n\n        string next_S = current_S;\n        int type = uniform_int_distribution<int>(0, 7)(rng);\n\n        if (type == 0) { // Add\n            if (next_S.length() < 200) {\n                int pos = uniform_int_distribution<int>(0, next_S.length())(rng);\n                next_S.insert(pos, 1, dir_char[uniform_int_distribution<int>(0, 3)(rng)]);\n            } else type = 1;\n        } else if (type == 1) { // Delete\n            if (next_S.length() > 1) next_S.erase(uniform_int_distribution<int>(0, next_S.length() - 1)(rng), 1);\n            else type = 0;\n        } else if (type == 2) { // Change\n            int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            next_S[pos] = dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n        } else if (type == 3) { // Swap\n            int i = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            int j = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n            swap(next_S[i], next_S[j]);\n        } else if (type == 4) { // Duplicate\n            if (next_S.length() < 200) {\n                int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                next_S.insert(pos, 1, next_S[pos]);\n            } else type = 5;\n        } else if (type == 5) { // Remove duplicate\n            if (next_S.length() > 1) {\n                int pos = uniform_int_distribution<int>(0, next_S.length() - 1)(rng);\n                if (pos < (int)next_S.length() - 1 && next_S[pos] == next_S[pos + 1]) next_S.erase(pos, 1);\n                else if (pos > 0 && next_S[pos] == next_S[pos - 1]) next_S.erase(pos, 1);\n                else type = 4;\n            } else type = 4;\n        } else if (type == 6) { // Replace segment\n            if (next_S.length() >= 2) {\n                int len = uniform_int_distribution<int>(2, 4)(rng);\n                int pos = uniform_int_distribution<int>(0, max(0, (int)next_S.length() - len))(rng);\n                string segment = \"\";\n                for (int k = 0; k < len; ++k) segment += dir_char[uniform_int_distribution<int>(0, 3)(rng)];\n                next_S.replace(pos, min(len, (int)next_S.length() - pos), segment);\n                if (next_S.length() > 200) next_S.erase(200);\n            } else type = 5;\n        } else { // Repeat block\n            if (next_S.length() >= 2 && next_S.length() < 150) {\n                int len = uniform_int_distribution<int>(2, 5)(rng);\n                int pos = uniform_int_distribution<int>(0, (int)next_S.length() - len)(rng);\n                next_S.insert(pos, next_S.substr(pos, len));\n                if (next_S.length() > 200) next_S.erase(200);\n            } else type = 6;\n        }\n\n        double next_E = calculate_expected_value(next_S);\n        if (next_E > current_E || (T > 1e-9 && exp((next_E - current_E) / T) > uniform_real_distribution<double>(0, 1)(rng))) {\n            current_S = next_S; current_E = next_E;\n            if (current_E > best_E) { best_E = current_E; best_S = current_S; }\n        }\n    }\n    cout << best_S << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// base_to[type][direction] = exit_direction\nint base_to[8][4] = {\n    {1, 0, -1, -1}, // 0: one curve (Left, Up)\n    {3, -1, -1, 0}, // 1: one curve (Up, Down)\n    {-1, -1, 3, 2}, // 2: one curve (Right, Down)\n    {-1, 2, 1, -1}, // 3: one curve (Down, Left)\n    {1, 0, 3, 2},    // 4: two curves (Left-Up, Right-Down)\n    {3, 2, 1, 0},    // 5: two curves (Up-Down, Left-Right)\n    {2, -1, 0, -1}, // 6: one straight (Left, Right)\n    {-1, 3, -1, 1}, // 7: one straight (Up, Down)\n};\n\nint rot_to[8][4][4];\n\nvoid precompute() {\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            for (int d = 0; d < 4; ++d) rot_to[t][r][d] = -1;\n            for (int d = 0; d < 4; ++d) {\n                int partner = base_to[t][d];\n                if (partner != -1) {\n                    int d_rot = (d + 3 * r) % 4;\n                    int p_rot = (partner + 3 * r) % 4;\n                    rot_to[t][r][d_rot] = p_rot;\n                }\n            }\n        }\n    }\n}\n\nint current_to[N][N][4];\nint initial_type[N][N];\nint current_rot[N][N];\nint visited[N][N][4];\nint timer = 0;\n\nlong long get_guided_score(int& L1, int& L2) {\n    vector<int> lengths;\n    timer++;\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] != timer) {\n                    int ci = i, cj = j, cd = d;\n                    int len = 0;\n                    bool broken = false;\n                    while (visited[ci][cj][cd] != timer) {\n                        visited[ci][cj][cd] = timer;\n                        int cd2 = current_to[ci][cj][cd];\n                        if (cd2 == -1) {\n                            broken = true;\n                            break;\n                        }\n                        int ni = ci + di[cd2];\n                        int nj = cj + dj[cd2];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                            broken = true;\n                            break;\n                        }\n                        len++;\n                        ci = ni; cj = nj;\n                        cd = (cd2 + 2) % 4;\n                    }\n                    if (!broken && len > 0) {\n                        lengths.push_back(len);\n                    }\n                }\n            }\n        }\n    }\n    if (lengths.empty()) {\n        L1 = 0; L2 = 0;\n        return 0;\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    L1 = lengths[0];\n    L2 = (lengths.size() > 1) ? lengths[1] : 0;\n    \n    // Guided score: prioritizes finding two loops, then maximizing their product\n    if (L2 > 0) return (long long)L1 * L2 + L1 + L2;\n    else return (long long)L1;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precompute();\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        if (!(cin >> s)) return 0;\n        for (int j = 0; j < N; ++j) {\n            initial_type[i][j] = s[j] - '0';\n            current_rot[i][j] = 0;\n            for (int d = 0; d < 4; ++d) {\n                current_to[i][j][d] = rot_to[initial_type[i][j]][0][d];\n            }\n        }\n    }\n\n    int L1, L2;\n    long long current_score = get_guided_score(L1, L2);\n\n    int best_rot[N][N];\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) best_rot[i][j] = current_rot[i][j];\n    long long best_score = current_score;\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    double T_start = 1000.0;\n    double T_end = 0.1;\n    int max_iters = 600000; \n\n    for (int iter = 0; iter < max_iters; ++iter) {\n        if ((iter & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1880) break;\n        }\n\n        int ri = rng() % N;\n        int rj = rng() % N;\n        int old_r = current_rot[ri][rj];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        int backup_to[4];\n        for (int d = 0; d < 4; ++d) backup_to[d] = current_to[ri][rj][d];\n\n        current_rot[ri][rj] = new_r;\n        for (int d = 0; d < 4; ++d) {\n            current_to[ri][rj][d] = rot_to[initial_type[ri][rj]][new_r][d];\n        }\n\n        int next_L1, next_L2;\n        long long next_score = get_guided_score(next_L1, next_L2);\n\n        double T = T_start * pow(T_end / T_start, (double)iter / max_iters);\n\n        if (next_score >= current_score || \n            (next_score > 0 && exp((double)(next_score - current_score) / T) > (double)rng() / mt19937::max())) {\n            current_score = next_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        best_rot[i][j] = current_rot[i][j];\n            }\n        } else {\n            current_rot[ri][rj] = old_r;\n            for (int d = 0; d < 4; ++d) current_to[ri][rj][d] = backup_to[d];\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << best_rot[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint N, T_limit;\nint board[10][10];\nint target_board[10][10];\nbool fixed_cell[10][10];\nstruct Pos { int r, c; bool operator==(const Pos& o) const { return r == o.r && c == o.c; } bool operator!=(const Pos& o) const { return !(*this == o); } };\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; // U, D, L, R\nchar dchar[] = {'U', 'D', 'L', 'R'};\n\nbool check_match(int t1, int t2, int dir) {\n    if (dir == 0) return (t1 & 8) && (t2 & 2); // U: t1 is (r,c), t2 is (r-1,c). t1 has U(2), t2 has D(8)\n    if (dir == 1) return (t1 & 2) && (t2 & 8); // D: t1 is (r,c), t2 is (r+1,c). t1 has D(8), t2 has U(2)\n    if (dir == 2) return (t1 & 1) && (t2 & 4); // L: t1 is (r,c), t2 is (r,c-1). t1 has L(1), t2 has R(4)\n    if (dir == 3) return (t1 & 4) && (t2 & 1); // R: t1 is (r,c), t2 is (r,c+1). t1 has R(4), t2 has L(1)\n    return false;\n}\n\n// The dir above is based on: if we move the tile from (r+dr, c+dc) to (r, c).\n// If dir=0 (Up), the tile at (r+1, c) moves to (r, c).\n// Let's just use the directions as: U means tile at (r+1, c) moves to (r, c).\n// D means tile at (r-1, c) moves to (r, c).\n// L means tile at (r, c+1) moves to (r, c).\n// R means tile at (r, c-1) moves to (r, c).\n\nint get_tile_dir(Pos from, Pos to) {\n    if (from.r == to.r + 1 && from.c == to.c) return 0; // Tile moves Up\n    if (from.r == to.r - 1 && from.c == to.c) return 1; // Tile moves Down\n    if (from.c == to.c + 1 && from.r == to.r) return 2; // Tile moves Left\n    if (from.c == to.c - 1 && from.r == to.r) return 3; // Tile moves Right\n    return -1;\n}\n\nint main() {\n    if (!(cin >> N >> T_limit)) return 0;\n    Pos empty_pos;\n    vector<int> all_tiles;\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) {\n            int val = stoi(s, nullptr, 16);\n            if (val == 0) empty_pos = {i, j};\n            else all_tiles.push_back(val);\n            board[i][j] = (val == 0 ? 0 : val);\n            target_board[i][j] = -1;\n        }\n    }\n\n    mt19937 rng(time(0));\n    vector<pair<Pos, Pos>> tree_edges;\n    vector<Pos> bfs_order;\n    while (true) {\n        tree_edges.clear(); bfs_order.clear();\n        vector<pair<Pos, Pos>> all_possible_edges;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (i == N - 1 && j == N - 1) continue;\n            if (i + 1 < N && !(i + 1 == N - 1 && j == N - 1)) all_possible_edges.push_back({{i, j}, {i + 1, j}});\n            if (j + 1 < N && !(i == N - 1 && j + 1 == N - 1)) all_possible_edges.push_back({{i, j}, {i, j + 1}});\n        }\n        shuffle(all_possible_edges.begin(), all_possible_edges.end(), rng);\n        vector<int> parent(N * N); for (int i = 0; i < N * N; ++i) parent[i] = i;\n        auto find = [&](auto self, int i) -> int { return parent[i] == i ? i : parent[i] = self(self, parent[i]); };\n        for (auto& e : all_possible_edges) {\n            int r1 = find(find, e.first.r * N + e.first.c), r2 = find(find, e.second.r * N + e.second.c);\n            if (r1 != r2) { parent[r1] = r2; tree_edges.push_back(e); }\n        }\n        bfs_order.push_back({0, 0});\n        vector<bool> visited(N * N, false); visited[0] = true;\n        queue<Pos> q; q.push({0, 0});\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = u.r + dr[i], nc = u.c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !(nr == N - 1 && nc == N - 1) && !visited[nr * N + nc]) {\n                    visited[nr * N + nc] = true; bfs_order.push_back({nr, nc}); q.push({nr, nc});\n                }\n            }\n        }\n        auto backtrack = [&](auto self, int idx, vector<int>& used) -> bool {\n            if (idx == N * N - 1) return true;\n            Pos u = bfs_order[idx];\n            for (int i = 0; i < (int)all_tiles.size(); ++i) {\n                if (used[i]) continue;\n                int tile = all_tiles[i];\n                bool ok = true;\n                for (auto& edge : tree_edges) {\n                    if ((edge.first == u || edge.second == u)) {\n                        Pos other = (edge.first == u) ? edge.second : edge.first;\n                        if (target_board[other.r][other.c] != -1) {\n                            if (!check_match(tile, target_board[other.r][other.c], get_tile_dir(u, other))) { ok = false; break; }\n                        }\n                    }\n                }\n                if (ok) {\n                    target_board[u.r][u.c] = tile; used[i] = 1;\n                    if (self(self, idx + 1, used)) return true;\n                    used[i] = 0; target_board[u.r][u.c] = -1;\n                }\n            }\n            return false;\n        };\n        vector<int> used(all_tiles.size(), 0);\n        if (backtrack(backtrack, 0, used)) break;\n    }\n\n    vector<Pos> order;\n    for (int i = 0; i < N - 1; ++i) for (int j = 0; j < N; ++j) order.push_back({i, j});\n    for (int j = 0; j < N - 1; ++j) order.push_back({N - 1, j});\n\n    string res = \"\";\n    Pos cur_e = empty_pos;\n    for (auto p : order) {\n        int tr = -1, tc = -1;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (board[i][j] == target_board[p.r][p.c] && !fixed_cell[i][j]) { tr = i; tc = j; break; }\n        }\n        if (tr == p.r && tc == p.c) { fixed_cell[p.r][p.c] = true; continue; }\n\n        auto bfs_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) if (fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            while (!q.empty()) {\n                auto [curr, path] = q.front(); q.pop();\n                if (curr == target) {\n                    res += path; cur_e = target;\n                    for (char c : path) {\n                        // To keep board in sync, we simulate. But easier to just swap.\n                    }\n                    return;\n                }\n                for (int i = 0; i < 4; ++i) {\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !v[nr][nc]) {\n                        v[nr][nc] = true;\n                        // If empty moves from (nr,nc) to (curr.r, curr.c), tile moves from (curr.r, curr.c) to (nr,nc)\n                        // The direction is the direction the TILE moves.\n                        // If empty moves (nr,nc) -> (curr.r, curr.c), tile moves (curr.r, curr.c) -> (nr,nc).\n                        // If nr = curr.r-1, tile moves Down. If nr = curr.r+1, tile moves Up.\n                        // If nc = curr.c-1, tile moves Right. If nc = curr.c+1, tile moves Left.\n                        char move_char;\n                        if (nr == curr.r - 1) move_char = 'D';\n                        else if (nr == curr.r + 1) move_char = 'U';\n                        else if (nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n        \n        // Correcting move: BFS to move empty to (tr, tc)\n        // But we must not move through the tile we are trying to move!\n        // No, we move the empty to (tr,tc) then to (p.r, p.c)? \n        // Let's do: 1. Move empty to (tr, tc) 2. Move empty to (p.r, p.c)\n        // Actually, to move tile from (tr,tc) to (p.r,p.c):\n        // Step 1: Move empty square to (p.r, p.c). Step 2: Move empty square to (tr, tc).\n        // Then the tile at (tr,tc) will be at (p.r, p.c).\n        \n        // Let's re-implement the BFS more simply.\n        auto move_empty = [&](Pos target) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            // To move a tile to (p.r, p.c), we shouldn't let the empty square pass through (p.r, p.c)\n            // EXCEPT when it's the final step. But it's easier to say:\n            // During BFS, the empty square cannot pass through ANY fixed cell.\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply the moves to the board\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int nr = temp_e.r, nc = temp_e.c;\n                        int tr_idx = -1;\n                        if(c == 'U') tr_idx = 1; else if(c == 'D') tr_idx = 0;\n                        else if(c == 'L') tr_idx = 3; else tr_idx = 2;\n                        // Wait, the directions are for the TILE.\n                        // If tile moves Up, empty moves Down.\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char move_char;\n                        if(nr == curr.r - 1) move_char = 'D';\n                        else if(nr == curr.r + 1) move_char = 'U';\n                        else if(nc == curr.c - 1) move_char = 'R';\n                        else move_char = 'L';\n                        q.push({{nr, nc}, path + move_char});\n                    }\n                }\n            }\n        };\n\n        // 1. Move empty to (p.r, p.c)\n        // But we must avoid (tr, tc) during this, because it's the tile we want.\n        // Wait, the empty square can move through (tr, tc) if it's not fixed!\n        // Let's just move empty to (p.r, p.c) then to (tr, tc).\n        // Wait, the order is:\n        // 1. Move empty square to (p.r, p.c)\n        // 2. Move empty square to (tr, tc)\n        // Now the tile that was at (tr, tc) is at (p.r, p.c).\n        \n        // We'll use a slightly different approach: move empty to (tr, tc) and then to (p.r, p.c).\n        // Actually, the simplest: move empty to (p.r, p.c), then to (tr, tc).\n        // Let's use a modified BFS that avoids (tr, tc) if we are moving to (p.r, p.c).\n        // Wait, the current tile is at (tr, tc). The empty square should move to (p.r, p.c) \n        // without using (tr, tc) as an intermediate.\n        \n        // BFS to move empty to (p.r, p.c), avoiding (tr, tc) and all fixed cells.\n        auto bfs_with_avoid = [&](Pos target, Pos avoid) {\n            queue<pair<Pos, string>> q; q.push({cur_e, \"\"});\n            vector<vector<bool>> v(N, vector<bool>(N, false));\n            for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) if(fixed_cell[i][j]) v[i][j] = true;\n            v[cur_e.r][cur_e.c] = true;\n            if(avoid.r != -1) v[avoid.r][avoid.c] = true;\n            while(!q.empty()){\n                auto [curr, path] = q.front(); q.pop();\n                if(curr == target){\n                    // Apply moves\n                    Pos temp_e = cur_e;\n                    for(char c : path){\n                        int er = temp_e.r, ec = temp_e.c;\n                        int nr_e, nc_e;\n                        if(c == 'U') { nr_e = er + 1; nc_e = ec; }\n                        else if(c == 'D') { nr_e = er - 1; nc_e = ec; }\n                        else if(c == 'L') { nr_e = er; nc_e = ec + 1; }\n                        else { nr_e = er; nc_e = ec - 1; }\n                        swap(board[er][ec], board[nr_e][nc_e]);\n                        temp_e = {nr_e, nc_e};\n                    }\n                    res += path; cur_e = target;\n                    return;\n                }\n                for(int i=0; i<4; ++i){\n                    int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                    if(nr>=0 && nr<N && nc>=0 && nc<N && !v[nr][nc]){\n                        v[nr][nc] = true;\n                        char m;\n                        if(nr == curr.r - 1) m = 'D'; else if(nr == curr.r + 1) m = 'U';\n                        else if(nc == curr.c - 1) m = 'R'; else m = 'L';\n                        q.push({{nr, nc}, path + m});\n                    }\n                }\n            }\n        };\n\n        bfs_with_avoid(p, {tr, tc});\n        bfs_with_avoid({tr, tc}, {-1, -1});\n        fixed_cell[p.r][p.c] = true;\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Refined Approach:\n * - Simulated Annealing with multiple restarts (reheating) to escape local optima.\n * - Improved move sets:\n *    1. Random line.\n *    2. Perpendicular bisector (splitting two strawberries).\n *    3. Random line through one strawberry with a tiny offset (to avoid cutting through center).\n *    4. Jittering an existing line.\n * - Optimized signature calculation using unsigned __int128.\n */\n\ntypedef __int128_t int128;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct RobustLine {\n    long long a, b, c;\n    long long px, py, qx, qy;\n};\n\nstruct SigBitset {\n    unsigned __int128 bits;\n};\n\nRobustLine make_line_from_points(long long px, long long py, long long qx, long long qy) {\n    RobustLine l;\n    l.px = px; l.py = py; l.qx = qx; l.qy = qy;\n    l.a = qy - py;\n    l.b = px - qx;\n    int128 c_val = (int128)l.a * px + (int128)l.b * py;\n    l.c = (long long)(-c_val);\n    return l;\n}\n\nint N, K;\nint a_years[11];\nPoint strawberries[5505];\nRobustLine robust_lines[105];\nSigBitset sigs[5505];\nint on_count[5505];\nunsigned __int128 active_sigs[5505];\n\nint calculate_score() {\n    int count = 0;\n    for (int i = 0; i < N; ++i) {\n        if (on_count[i] == 0) {\n            active_sigs[count++] = sigs[i].bits;\n        }\n    }\n    if (count == 0) return 0;\n    sort(active_sigs, active_sigs + count);\n\n    int b_counts[11] = {0};\n    int current_run = 1;\n    for (int i = 1; i < count; ++i) {\n        if (active_sigs[i] == active_sigs[i - 1]) {\n            current_run++;\n        } else {\n            if (current_run <= 10) b_counts[current_run]++;\n            current_run = 1;\n        }\n    }\n    if (current_run <= 10) b_counts[current_run]++;\n\n    int total = 0;\n    for (int d = 1; d <= 10; ++d) {\n        total += min(a_years[d], b_counts[d]);\n    }\n    return total;\n}\n\nvoid update_line(int idx, const RobustLine& new_line) {\n    long long a1 = robust_lines[idx].a, b1 = robust_lines[idx].b, c1 = robust_lines[idx].c;\n    long long a2 = new_line.a, b2 = new_line.b, c2 = new_line.c;\n\n    for (int i = 0; i < N; ++i) {\n        int128 val_old = (int128)a1 * strawberries[i].x + (int128)b1 * strawberries[i].y + c1;\n        if (val_old == 0) on_count[i]--;\n\n        int128 val_new = (int128)a2 * strawberries[i].x + (int128)b2 * strawberries[i].y + c2;\n        if (val_new == 0) {\n            on_count[i]++;\n        } else {\n            if (val_new > 0) sigs[i].bits |= ((unsigned __int128)1 << idx);\n            else sigs[i].bits &= ~((unsigned __int128)1 << idx);\n        }\n    }\n    robust_lines[idx] = new_line;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> K)) return 0;\n    for (int i = 1; i <= 10; ++i) cin >> a_years[i];\n    for (int i = 0; i < N; ++i) cin >> strawberries[i].x >> strawberries[i].y;\n\n    mt19937_64 rng(1337);\n    uniform_int_distribution<long long> dist_coord(-1000000, 1000000);\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    uniform_int_distribution<int> dist_K(0, K - 1);\n\n    for (int i = 0; i < N; ++i) {\n        on_count[i] = 0;\n        sigs[i].bits = 0;\n    }\n    for (int i = 0; i < K; ++i) {\n        robust_lines[i] = make_line_from_points(0, -20000 - i, 1, -20000 - i);\n        for (int j = 0; j < N; ++j) {\n            int128 val = (int128)robust_lines[i].a * strawberries[j].x + (int128)robust_lines[i].b * strawberries[j].y + robust_lines[i].c;\n            if (val == 0) on_count[j]++;\n            else if (val > 0) sigs[j].bits |= ((unsigned __int128)1 << i);\n        }\n    }\n\n    int current_score = calculate_score();\n    int best_score = current_score;\n    vector<RobustLine> best_lines(robust_lines, robust_lines + K);\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // SA Parameters\n    double T_initial = 10.0;\n    double factor = 0.999995;\n    double T = T_initial;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n            \n            // Reheating logic: if we've spent some time and not found an improvement, jump T back up\n            if (iter > 10000 && iter % 20000 == 0) {\n                T = T_initial * (0.5 + (double)rng() / mt19937_64::max());\n            }\n        }\n        iter++;\n\n        int idx = dist_K(rng);\n        RobustLine old_line = robust_lines[idx];\n        RobustLine new_line;\n        \n        int move_type = rng() % 100;\n        if (move_type < 15) { \n            new_line = make_line_from_points(dist_coord(rng), dist_coord(rng), dist_coord(rng), dist_coord(rng));\n        } else if (move_type < 55) { \n            int s1 = dist_idx(rng);\n            int s2 = dist_idx(rng);\n            if (s1 == s2) {\n                new_line = make_line_from_points(strawberries[s1].x, strawberries[s1].y, strawberries[s1].x + 1, strawberries[s1].y + 1);\n            } else {\n                long long dx = strawberries[s2].x - strawberries[s1].x;\n                long long dy = strawberries[s2].y - strawberries[s1].y;\n                long long mx2 = strawberries[s1].x + strawberries[s2].x;\n                long long my2 = strawberries[s1].y + strawberries[s2].y;\n                long long scale = 1000; \n                new_line = make_line_from_points(mx2 - 2 * dy * scale, my2 + 2 * dx * scale, mx2 + 2 * dy * scale, my2 - 2 * dx * scale);\n                if (rng() % 100 < 40) { // Jittered bisector\n                    new_line.px += (rng() % 201 - 100); new_line.py += (rng() % 201 - 100);\n                    new_line.qx += (rng() % 201 - 100); new_line.qy += (rng() % 201 - 100);\n                    new_line = make_line_from_points(new_line.px, new_line.py, new_line.qx, new_line.qy);\n                }\n            }\n        } else if (move_type < 85) { \n            int s1 = dist_idx(rng);\n            // Line through strawberry but offset slightly to avoid cutting through center\n            long long ox = (rng() % 100 - 50);\n            long long oy = (rng() % 100 - 50);\n            if (ox == 0 && oy == 0) ox = 1;\n            new_line = make_line_from_points(strawberries[s1].x + ox, strawberries[s1].y + oy, dist_coord(rng), dist_coord(rng));\n        } else { \n            new_line = old_line;\n            new_line.px += (rng() % 11) - 5; new_line.py += (rng() % 11) - 5;\n            new_line.qx += (rng() % 11) - 5; new_line.qy += (rng() % 11) - 5;\n            if (new_line.px == new_line.qx && new_line.py == new_line.qy) new_line.qx++;\n            new_line = make_line_from_points(new_line.px, new_line.py, new_line.qx, new_line.qy);\n        }\n\n        if (new_line.a == 0 && new_line.b == 0) continue;\n\n        update_line(idx, new_line);\n        int new_score = calculate_score();\n\n        if (new_score >= current_score || (exp((new_score - current_score) / T) > (double)rng() / mt19937_64::max())) {\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int i = 0; i < K; ++i) best_lines[i] = robust_lines[i];\n            }\n        } else {\n            update_line(idx, old_line);\n        }\n        T *= factor;\n    }\n\n    cout << K << \"\\n\";\n    for (int i = 0; i < K; ++i) {\n        cout << best_lines[i].px << \" \" << best_lines[i].py << \" \" << best_lines[i].qx << \" \" << best_lines[i].qy << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The goal is to maximize the sum of weights of dots on an N x N grid.\n * Weight of (x, y) is (x-c)^2 + (y-c)^2 + 1, favoring points far from the center.\n * Rectangles can be axis-aligned or 45-degree inclined.\n * \n * REFINED STRATEGY:\n * Use a priority queue to store potential rectangles. Initially, find all possible\n * rectangles using an O(N^4) search. In each step, pop the best rectangle, check if \n * it's still valid (its new corner p1 is not a dot, its other corners are dots, \n * and its perimeter is valid), then add the new dot and its segments. \n * When a new dot is added, find new valid rectangles that use this new dot \n * as one of its existing-dot corners (p2, p3, or p4).\n * \n * Complexity: \n * Initial search: O(N^4)\n * Per step: O(N^2) new rectangles found, and O(N) to validate.\n * This fits well within the 5s time limit.\n */\n\nstruct Point {\n    int x, 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\nstruct RectCandidate {\n    Point p[4]; // p[0] is the new dot p1\n    double weight;\n    bool operator<(const RectCandidate& other) const { return weight < other.weight; }\n};\n\nint N, M;\nbool is_dot[65][65];\nbool used_h[65][65], used_v[65][65], used_d1[65][65], used_d2[65][65];\nvector<Point> dots;\nvector<int> dots_in_row[65], dots_in_col[65];\n\ndouble get_weight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1.0;\n}\n\nbool is_in_grid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool check_segments(const vector<Point>& rect, bool mark) {\n    for (int i = 0; i < 4; ++i) {\n        Point s = rect[i], e = rect[(i + 1) % 4];\n        int dx = (e.x > s.x ? 1 : (e.x < s.x ? -1 : 0));\n        int dy = (e.y > s.y ? 1 : (e.y < s.y ? -1 : 0));\n        int cx = s.x, cy = s.y;\n        while (cx != e.x || cy != e.y) {\n            int nx = cx + dx, ny = cy + dy;\n            if (dx != 0 && dy == 0) {\n                int mx = min(cx, nx);\n                if (used_h[mx][cy]) return false;\n                if (mark) used_h[mx][cy] = true;\n            } else if (dx == 0 && dy != 0) {\n                int my = min(cy, ny);\n                if (used_v[cx][my]) return false;\n                if (mark) used_v[cx][my] = true;\n            } else if (dx == 1 && dy == 1) {\n                if (used_d1[cx][cy]) return false;\n                if (mark) used_d1[cx][cy] = true;\n            } else if (dx == -1 && dy == -1) {\n                if (used_d1[cx - 1][cy - 1]) return false;\n                if (mark) used_d1[cx - 1][cy - 1] = true;\n            } else if (dx == -1 && dy == 1) {\n                if (used_d2[cx - 1][cy]) return false;\n                if (mark) used_d2[cx - 1][cy] = true;\n            } else if (dx == 1 && dy == -1) {\n                if (used_d2[cx][cy - 1]) return false;\n                if (mark) used_d2[cx][cy - 1] = true;\n            }\n            cx = nx; cy = ny;\n        }\n    }\n    return true;\n}\n\nbool check_no_other_dots(const vector<Point>& rect) {\n    for (int i = 0; i < 4; ++i) {\n        Point s = rect[i], e = rect[(i + 1) % 4];\n        int dx = (e.x > s.x ? 1 : (e.x < s.x ? -1 : 0));\n        int dy = (e.y > s.y ? 1 : (e.y < s.y ? -1 : 0));\n        int cx = s.x + dx, cy = s.y + dy;\n        while (cx != e.x || cy != e.y) {\n            if (is_dot[cx][cy]) {\n                bool is_corner = false;\n                for (int j = 1; j < 4; ++j) if (cx == rect[j].x && cy == rect[j].y) is_corner = true;\n                if (!is_corner) return false;\n            }\n            cx += dx; cy += dy;\n        }\n    }\n    return true;\n}\n\npriority_queue<RectCandidate> pq;\n\nvoid add_rect_to_pq(const vector<Point>& r) {\n    if (!is_in_grid(r[0].x, r[0].y)) return;\n    if (is_dot[r[0].x][r[0].y]) return;\n    for (int i = 1; i < 4; ++i) if (!is_dot[r[i].x][r[i].y]) return;\n    // We don't check no_other_dots or segments here because they can change.\n    // We'll check them when we pop from the pq.\n    pq.push({ {r[0], r[1], r[2], r[3]}, get_weight(r[0].x, r[0].y) });\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        is_dot[x][y] = true;\n        dots.push_back({x, y});\n        dots_in_row[y].push_back(x);\n        dots_in_col[x].push_back(y);\n    }\n\n    // Initial Search: Axis-aligned\n    for (int x1 = 0; x1 < N; ++x1) {\n        for (int x2 = x1 + 1; x2 < N; ++x2) {\n            for (int y1 = 0; y1 < N; ++y1) {\n                for (int y2 = y1 + 1; y2 < N; ++y2) {\n                    int x[] = {x1, x2, x2, x1};\n                    int y[] = {y1, y1, y2, y2};\n                    int dot_count = 0;\n                    int new_dot_idx = -1;\n                    for (int k = 0; k < 4; ++k) {\n                        if (is_dot[x[k]][y[k]]) dot_count++;\n                        else new_dot_idx = k;\n                    }\n                    if (dot_count == 3 && new_dot_idx != -1) {\n                        vector<Point> r(4);\n                        for (int k = 0; k < 4; ++k) r[k] = {x[k], y[k]};\n                        // Reorder so r[0] is the new dot\n                        vector<Point> ordered_r = {r[new_dot_idx], r[(new_dot_idx + 1) % 4], r[(new_dot_idx + 2) % 4], r[(new_dot_idx + 3) % 4]};\n                        add_rect_to_pq(ordered_r);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initial Search: 45-degree\n    for (int u1 = 0; u1 <= 2 * N - 2; ++u1) {\n        for (int u2 = u1 + 2; u2 <= 2 * N - 2; ++u2) {\n            for (int v1 = -(N - 1); v1 <= N - 1; ++v1) {\n                if ((u1 % 2 + 2) % 2 != (v1 % 2 + 2) % 2) continue;\n                for (int v2 = v1 + 2; v2 <= N - 1; v2 += 2) {\n                    int u[] = {u1, u2, u2, u1};\n                    int v[] = {v1, v1, v2, v2};\n                    int x[4], y[4];\n                    int dot_count = 0, new_dot_idx = -1;\n                    for (int k = 0; k < 4; ++k) {\n                        x[k] = (u[k] + v[k]) / 2;\n                        y[k] = (u[k] - v[k]) / 2;\n                        if (is_dot[x[k]][y[k]]) dot_count++;\n                        else new_dot_idx = k;\n                    }\n                    if (dot_count == 3 && new_dot_idx != -1) {\n                        vector<Point> r(4);\n                        for (int k = 0; k < 4; ++k) r[k] = {x[k], y[k]};\n                        vector<Point> ordered_r = {r[new_dot_idx], r[(new_dot_idx + 1) % 4], r[(new_dot_idx + 2) % 4], r[(new_dot_idx + 3) % 4]};\n                        add_rect_to_pq(ordered_r);\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<Point>> ops;\n    while (!pq.empty()) {\n        RectCandidate best = pq.top(); pq.pop();\n        vector<Point> r = {best.p[0], best.p[1], best.p[2], best.p[3]};\n        if (is_dot[r[0].x][r[0].y]) continue;\n        bool p_dots = true;\n        for (int i = 1; i < 4; ++i) if (!is_dot[r[i].x][r[i].y]) { p_dots = false; break; }\n        if (!p_dots) continue;\n        if (!check_no_other_dots(r) || !check_segments(r, false)) continue;\n\n        // Valid rectangle found\n        is_dot[r[0].x][r[0].y] = true;\n        dots.push_back(r[0]);\n        dots_in_row[r[0].y].push_back(r[0].x);\n        dots_in_col[r[0].x].push_back(r[0].y);\n        check_segments(r, true);\n        ops.push_back(r);\n\n        // Find new rectangles using the new dot as p2, p3, or p4\n        Point p_new = r[0];\n        // Case 1: p_new is p3 (the corner between p2 and p4)\n        for (int py : dots_in_col[p_new.x]) {\n            for (int px : dots_in_row[p_new.y]) {\n                Point p2 = {p_new.x, py}, p4 = {px, p_new.y}, p1 = {px, py};\n                if (p1 != p_new && p1 != p2 && p1 != p4) {\n                    add_rect_to_pq({p1, p2, p_new, p4});\n                }\n            }\n        }\n        // Case 2: p_new is p2 or p4 (p_new's neighbor is p3)\n        for (int py : dots_in_col[p_new.x]) {\n            Point p3 = {p_new.x, py};\n            for (int px : dots_in_row[p3.y]) {\n                Point p4 = {px, p3.y}, p1 = {px, p_new.y};\n                if (p1 != p_new && p1 != p3 && p1 != p4) {\n                    add_rect_to_pq({p1, p_new, p3, p4});\n                }\n            }\n        }\n        for (int px : dots_in_row[p_new.y]) {\n            Point p3 = {px, p_new.y};\n            for (int py : dots_in_col[p3.x]) {\n                Point p4 = {p3.x, py}, p1 = {p_new.x, py};\n                if (p1 != p_new && p1 != p3 && p1 != p4) {\n                    add_rect_to_pq({p1, p_new, p3, p4});\n                }\n            }\n        }\n        // Case 3: 45-degree rectangles with p_new as p3\n        for (auto& p_other : dots) {\n            int dx = p_other.x - p_new.x, dy = p_other.y - p_new.y;\n            if (abs(dx) == abs(dy) && dx != 0) {\n                // p_other could be p2 or p4. Let's say p2. \n                // Then p4 = p_new + rotate(p_new-p_other, 90) or rotate(p_new-p_other, -90)\n                int dirs[2][2] = {{-dy, dx}, {dy, -dx}};\n                for (int d = 0; d < 2; ++d) {\n                    Point p4 = {p_new.x + dirs[d][0], p_new.y + dirs[d][1]};\n                    if (is_in_grid(p4.x, p4.y) && is_dot[p4.x][p4.y]) {\n                        Point p1 = {p_other.x + p4.x - p_new.x, p_other.y + p4.y - p_new.y};\n                        if (is_in_grid(p1.x, p1.y)) {\n                            add_rect_to_pq({p1, p_other, p_new, p4});\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (const auto& o : ops) {\n        cout << o[0].x << \" \" << o[0].y << \" \" << o[1].x << \" \" << o[1].y << \" \"\n             << o[2].x << \" \" << o[2].y << \" \" << o[3].x << \" \" << o[3].y << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: AtCoder Halloween (AHC015)\n * Goal: Maximize the sum of squares of the sizes of connected components of same-flavor candies.\n * \n * Strategy Refinement:\n * - We know the flavors of all 100 candies in advance.\n * - To maximize the sum of squares of component sizes, we want each flavor to form a single, large, contiguous component.\n * - The most natural way to achieve this is to organize the grid into \"stripes\" (horizontal or vertical bands).\n * - We pre-calculate 12 stripe configurations based on the 6 permutations of the 3 flavors and 2 orientations (H/V).\n * - We refine the boundary calculation for these stripes using the total expected count of each flavor.\n * - For each incoming candy, we perform a greedy decision: choose the tilt direction that maximizes a weighted sum:\n *   Score = Current_Connectivity_Score + alpha * Max_Alignment_Score\n *   Where Current_Connectivity_Score is the sum of n_i^2 and Max_Alignment_Score is the highest proximity \n *   to any of our 12 ideal stripe configurations.\n * - alpha is tuned to balance the immediate benefit of connectivity with the long-term benefit of staying \n *   aligned with the stripe-based structure.\n */\n\n// Global grid and flavor information\nint grid[10][10];\nint flavors[100];\nint counts[4]; // counts[1], counts[2], counts[3] for flavors 1, 2, and 3\n\nstruct Point {\n    int r, c;\n};\n\n// Directions for connectivity BFS\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Represents a target configuration of stripes\nstruct Config {\n    int type; // 0 for Horizontal, 1 for Vertical\n    int p[3]; // Permutation of flavor indices (1, 2, 3)\n    int boundaries[4]; // Segment boundaries for the three flavor bands\n};\n\nvector<Config> configs;\n\n/**\n * Generates 12 stripe configurations (6 permutations * 2 orientations).\n * Boundaries are calculated based on the total count of each flavor.\n */\nvoid generate_configs() {\n    int perms[6][3] = {\n        {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}\n    };\n\n    for (int i = 0; i < 6; ++i) {\n        int p[3] = {perms[i][0], perms[i][1], perms[i][2]};\n\n        // Horizontal stripe configuration\n        Config hc;\n        hc.type = 0;\n        hc.p[0] = p[0]; hc.p[1] = p[1]; hc.p[2] = p[2];\n        // Estimate row boundaries based on total counts\n        int b1 = (int)round(counts[p[0]] / 10.0);\n        int b2 = (int)round((counts[p[0]] + counts[p[1]]) / 10.0);\n        // Ensure valid and strictly increasing boundaries [0, 10]\n        if (b1 < 1) b1 = 1; if (b1 > 9) b1 = 9;\n        if (b2 <= b1) b2 = b1 + 1; if (b2 > 9) b2 = 9;\n        hc.boundaries[0] = 0; hc.boundaries[1] = b1;\n        hc.boundaries[2] = b2; hc.boundaries[3] = 10;\n        configs.push_back(hc);\n\n        // Vertical stripe configuration\n        Config vc;\n        vc.type = 1;\n        vc.p[0] = p[0]; vc.p[1] = p[1]; vc.p[2] = p[2];\n        // Boundaries for columns follow the same logic\n        vc.boundaries[0] = 0; vc.boundaries[1] = b1;\n        vc.boundaries[2] = b2; vc.boundaries[3] = 10;\n        configs.push_back(vc);\n    }\n}\n\n/**\n * Calculates the proximity of a candy at (r, c) to its ideal zone in a configuration.\n * Returns a value (up to 10.0) representing how close the candy is to its stripe.\n */\ninline double get_proximity(int r, int c, int flavor, const Config& conf) {\n    int pos = (conf.type == 0) ? r : c;\n    int idx = (conf.p[0] == flavor) ? 0 : ((conf.p[1] == flavor) ? 1 : 2);\n    int b_start = conf.boundaries[idx];\n    int b_end = conf.boundaries[idx+1];\n    \n    if (pos >= b_start && pos < b_end) return 10.0;\n    \n    int dist = 10;\n    if (pos < b_start) dist = b_start - pos;\n    else if (pos >= b_end) dist = pos - (b_end - 1);\n    \n    return 10.0 - (double)dist;\n}\n\n/**\n * Calculates the current connectivity score: Sum of the squares of component sizes.\n */\nint calculate_connectivity_score(int current_grid[10][10]) {\n    static bool visited[10][10];\n    for(int i=0; i<10; ++i) for(int j=0; j<10; ++j) visited[i][j] = false;\n    \n    int total_score = 0;\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (current_grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = current_grid[r][c];\n                int size = 0;\n                static Point q[100];\n                int head = 0, tail = 0;\n                q[tail++] = {r, c};\n                visited[r][c] = true;\n                while (head < tail) {\n                    Point curr = q[head++];\n                    size++;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = curr.r + dr[i];\n                        int nc = curr.c + dc[i];\n                        if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 &&\n                            !visited[nr][nc] && current_grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true;\n                            q[tail++] = {nr, nc};\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n/**\n * Simulates the result of tilting the grid in one of the four directions.\n */\nvoid simulate_tilt(int current_grid[10][10], char dir, int next_grid[10][10]) {\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            next_grid[i][j] = 0;\n\n    if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 0; r < 10; ++r)\n                if (current_grid[r][c] != 0) next_grid[count++][c] = current_grid[r][c];\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            int count = 0;\n            for (int r = 9; r >= 0; --r)\n                if (current_grid[r][c] != 0) next_grid[9 - count++][c] = current_grid[r][c];\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 0; c < 10; ++c)\n                if (current_grid[r][c] != 0) next_grid[r][count++] = current_grid[r][c];\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            int count = 0;\n            for (int c = 9; c >= 0; --c)\n                if (current_grid[r][c] != 0) next_grid[r][9 - count++] = current_grid[r][c];\n        }\n    }\n}\n\n/**\n * Updates the actual grid by applying a tilt.\n */\nvoid apply_tilt(int current_grid[10][10], char dir) {\n    int next_grid[10][10];\n    simulate_tilt(current_grid, dir, next_grid);\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            current_grid[i][j] = next_grid[i][j];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read the flavors of the 100 candies\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) return 0;\n        counts[flavors[i]]++;\n    }\n\n    generate_configs();\n\n    // Initialize empty grid\n    for (int i = 0; i < 10; ++i)\n        for (int j = 0; j < 10; ++j)\n            grid[i][j] = 0;\n\n    char directions[] = {'F', 'B', 'L', 'R'};\n    const double alpha = 5.0; // Tuning parameter for the alignment weight\n\n    // 100 steps for 100 candies\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        if (!(cin >> p_t)) break;\n\n        // Identify empty cells to find the p_t-th cell\n        vector<Point> empty_cells;\n        for (int r = 0; r < 10; ++r)\n            for (int c = 0; c < 10; ++c)\n                if (grid[r][c] == 0) empty_cells.push_back({r, c});\n        \n        Point pos = empty_cells[p_t - 1];\n        grid[pos.r][pos.c] = flavors[t - 1];\n\n        double best_val = -1e18;\n        char best_dir = 'F';\n\n        // Greedy check for each direction\n        for (char d : directions) {\n            int next_grid[10][10];\n            simulate_tilt(grid, d, next_grid);\n            \n            // Current Connectivity Score (S)\n            int S = calculate_connectivity_score(next_grid);\n            \n            // Maximize alignment with stripe configurations (A)\n            double max_A = -1e18;\n            for (const auto& conf : configs) {\n                double cur_A = 0;\n                for (int r = 0; r < 10; ++r) {\n                    for (int c = 0; c < 10; ++c) {\n                        int f = next_grid[r][c];\n                        if (f != 0) {\n                            cur_A += get_proximity(r, c, f, conf);\n                        }\n                    }\n                }\n                if (cur_A > max_A) max_A = cur_A;\n            }\n\n            double total_val = (double)S + alpha * max_A;\n            if (total_val > best_val) {\n                best_val = total_val;\n                best_dir = d;\n            }\n        }\n\n        // Output decision and update grid\n        cout << best_dir << endl;\n        apply_tilt(grid, best_dir);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem Analysis & Strategy:\n * \n * 1. Encoding Strategy:\n *    Clique-based encoding remains the strongest. For each label i (0 to M-1), \n *    we create a clique of size k = i + 1.\n *    - The number of edges in G_i is k(k-1)/2.\n *    - The degree distribution is very distinct: k vertices have degree k-1, \n *      and (N-k) vertices have degree 0.\n *    - This ensures high separability even with noise (epsilon up to 0.4).\n * \n * 2. Decoding Strategy (Multi-stage search):\n *    - Step A: Candidate Selection.\n *      The number of edges in the received graph H is our best first signal.\n *      We select the top 50 candidates based on the expected edge count \n *      E[e(H) | G_i] = e(G_i)*(1-2*epsilon) + (N*(N-1)/2)*epsilon.\n *    - Step B: Efficient Initialization.\n *      We sort vertices of H and G_i by degree to create an initial permutation P.\n *    - Step C: Two-Stage Optimization.\n *      Stage 1 (Hill Climbing): Perform 600 iterations of fast greedy Hill Climbing \n *      for all 50 candidates. This reduces the search space significantly.\n *      Stage 2 (Simulated Annealing): For the top 5 candidates from Stage 1, \n *      perform a very intensive Simulated Annealing (4500 iterations) to \n *      escape local minima and find the absolute best mapping.\n * \n * 3. Performance Optimization:\n *    - Precomputing degree sequences and adjacency matrices for all G_i.\n *    - The delta calculation in the permutation swap is O(N).\n *    - Time-limited loop to stay within the 5.0s limit.\n * \n * Complexity: O(Queries * (Num_Candidates_S1 * Iters_S1 + Num_Candidates_S2 * Iters_S2) * N)\n * Roughly: 100 * (50 * 600 + 5 * 4500) * 100 \u2248 5.25e8 operations.\n */\n\n// Using global static arrays for cache efficiency and to avoid stack overflow\nunsigned char G_adj[100][100][100];\nbool H_adj[100][100];\nint Gi_edges[100];\nint Gi_deg[100][100];\n\nint main() {\n    // Optimization for competitive programming performance\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double epsilon;\n    if (!(cin >> M >> epsilon)) return 0;\n\n    const int N = 100;\n    const int L = N * (N - 1) / 2;\n\n    // Precompute encoded graphs G_i\n    for (int i = 0; i < M; ++i) {\n        int k = i + 1;\n        Gi_edges[i] = k * (k - 1) / 2;\n        for (int u = 0; u < N; ++u) {\n            int d = 0;\n            for (int v = 0; v < N; ++v) {\n                if (u < k && v < k && u != v) {\n                    G_adj[i][u][v] = 1;\n                    d++;\n                } else {\n                    G_adj[i][u][v] = 0;\n                }\n            }\n            Gi_deg[i][u] = d;\n        }\n    }\n\n    // Output encoded graphs\n    cout << N << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        string s = \"\";\n        s.reserve(L);\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                s += (G_adj[i][u][v] ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    // Handle 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H_str;\n        if (!(cin >> H_str)) break;\n\n        // Parse the noisy graph H\n        int h_edges = 0;\n        vector<int> H_deg(N, 0);\n        for (int u = 0; u < N; ++u) {\n            for (int v = 0; v < N; ++v) H_adj[u][v] = false;\n        }\n        int idx = 0;\n        for (int u = 0; u < N; ++u) {\n            for (int v = u + 1; v < N; ++v) {\n                if (H_str[idx++] == '1') {\n                    H_adj[u][v] = H_adj[v][u] = true;\n                    H_deg[u]++;\n                    H_deg[v]++;\n                    h_edges++;\n                }\n            }\n        }\n\n        // Candidate Selection using expected edge count\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < M; ++i) {\n            double expected = (double)Gi_edges[i] * (1.0 - 2.0 * epsilon) + (double)L * epsilon;\n            candidates.push_back({abs((double)h_edges - expected), i});\n        }\n        sort(candidates.begin(), candidates.end());\n\n        int best_i = 0;\n        int min_mismatches = 2e9;\n\n        // Structure to keep track of candidate scores from Stage 1\n        struct Stage1Result {\n            int index;\n            int mismatches;\n            vector<int> P;\n        };\n        vector<Stage1Result> s1_results;\n\n        // Stage 1: Fast Hill Climbing for top candidates\n        int num_cand_s1 = min(M, 50);\n        for (int c = 0; c < num_cand_s1; ++c) {\n            int i = candidates[c].second;\n\n            // Initial degree-based mapping\n            vector<int> H_idx(N), G_idx(N);\n            for (int j = 0; j < N; ++j) { H_idx[j] = j; G_idx[j] = j; }\n            sort(H_idx.begin(), H_idx.end(), [&](int a, int b) { return H_deg[a] < H_deg[b]; });\n            sort(G_idx.begin(), G_idx.end(), [&](int a, int b) { return Gi_deg[i][a] < Gi_deg[i][b]; });\n\n            vector<int> P(N);\n            for (int j = 0; j < N; ++j) P[H_idx[j]] = G_idx[j];\n\n            int cur_m = 0;\n            for (int u = 0; u < N; ++u) {\n                for (int v = u + 1; v < N; ++v) {\n                    if (G_adj[i][P[u]][P[v]] != H_adj[u][v]) cur_m++;\n                }\n            }\n\n            // Hill Climbing\n            for (int it = 0; it < 600; ++it) {\n                int u = rng() % N, v = rng() % N;\n                if (u == v) continue;\n                int delta = 0;\n                int pu = P[u], pv = P[v];\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    int pk = P[k];\n                    // Diff between (current mismatch for u,v edges) and (mismatch after swap)\n                    int old_val = (G_adj[i][pu][pk] != H_adj[u][k]) + (G_adj[i][pv][pk] != H_adj[v][k]);\n                    int new_val = (G_adj[i][pv][pk] != H_adj[u][k]) + (G_adj[i][pu][pk] != H_adj[v][k]);\n                    delta += (new_val - old_val);\n                }\n                if (delta <= 0) {\n                    cur_m += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n            s1_results.push_back({i, cur_m, P});\n            if (cur_m < min_mismatches) {\n                min_mismatches = cur_m;\n                best_i = i;\n            }\n        }\n\n        // Stage 2: Intensive Simulated Annealing for the top 5 candidates\n        sort(s1_results.begin(), s1_results.end(), [](const Stage1Result& a, const Stage1Result& b) {\n            return a.mismatches < b.mismatches;\n        });\n\n        int num_cand_s2 = min((int)s1_results.size(), 5);\n        for (int s = 0; s < num_cand_s2; ++s) {\n            int i = s1_results[s].index;\n            vector<int> P = s1_results[s].P;\n            int cur_m = s1_results[s].mismatches;\n\n            // Simulated Annealing\n            const int sa_iters = 4500;\n            const double T0 = 1.0, Tend = 0.005;\n            for (int it = 0; it < sa_iters; ++it) {\n                int u = rng() % N, v = rng() % N;\n                if (u == v) continue;\n                int delta = 0;\n                int pu = P[u], pv = P[v];\n                for (int k = 0; k < N; ++k) {\n                    if (k == u || k == v) continue;\n                    int pk = P[k];\n                    int old_val = (G_adj[i][pu][pk] != H_adj[u][k]) + (G_adj[i][pv][pk] != H_adj[v][k]);\n                    int new_val = (G_adj[i][pv][pk] != H_adj[u][k]) + (G_adj[i][pu][pk] != H_adj[v][k]);\n                    delta += (new_val - old_val);\n                }\n\n                double T = T0 * pow(Tend / T0, (double)it / sa_iters);\n                if (delta <= 0 || (T > 1e-9 && exp(-delta / T) > (double)rng() / rng.max())) {\n                    cur_m += delta;\n                    swap(P[u], P[v]);\n                }\n            }\n            if (cur_m < min_mismatches) {\n                min_mismatches = cur_m;\n                best_i = i;\n            }\n        }\n\n        // Output prediction\n        cout << best_i << \"\\n\";\n        cout.flush();\n\n        // Time safety check\n        if (q % 10 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 4700) break;\n        }\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n// Use a large INF for Dijkstra to avoid overflow while still being larger than any possible path\nconst long long INF = 1e15;\n// The problem defines unreachable distance as 10^9\nconst long long DIST_INF = 1000000000LL;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct AdjEdge {\n    int to, w, id;\n};\n\nint main() {\n    // Optimize I/O performance\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w, i});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w, i});\n    }\n\n    // Skip vertex coordinates as they are not required for the improved heuristic\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // edge_count[i] stores the number of pairs (start, target) such that edge i is on the shortest path in the Dijkstra forest\n    vector<long long> edge_count(M, 0);\n\n    // Phase 1: Calculate how many shortest paths pass through each edge\n    for (int start = 1; start <= N; ++start) {\n        vector<long long> dist(N + 1, INF);\n        vector<int> parent_node(N + 1, -1);\n        vector<int> parent_edge(N + 1, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n\n        dist[start] = 0;\n        pq.push({0, start});\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& e : adj[u]) {\n                if (dist[e.to] > dist[u] + e.w) {\n                    dist[e.to] = dist[u] + e.w;\n                    parent_node[e.to] = u;\n                    parent_edge[e.to] = e.id;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n\n        // Sort nodes by distance in descending order to propagate counts up the Dijkstra tree\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 1);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n\n        vector<long long> node_count(N + 1, 1);\n        for (int u : nodes) {\n            if (u != start && parent_edge[u] != -1) {\n                int p = parent_node[u];\n                int id = parent_edge[u];\n                edge_count[id] += node_count[u];\n                node_count[p] += node_count[u];\n            }\n        }\n    }\n\n    // Phase 2: Calculate the \"detour\" weight for each edge to refine the impact metric\n    vector<long long> I(M);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int w = edges[i].w;\n\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;\n        vector<long long> dist_u(N + 1, INF);\n        dist_u[u] = 0;\n        pq.push({0, u});\n\n        while (!pq.empty()) {\n            auto [d, curr] = pq.top();\n            pq.pop();\n            if (d > dist_u[curr]) continue;\n            if (curr == v) break; // Optimization: stop once we reach the other endpoint\n            for (auto& e_adj : adj[curr]) {\n                if (e_adj.id == i) continue; // Ignore the edge being analyzed\n                if (dist_u[e_adj.to] > d + e_adj.w) {\n                    dist_u[e_adj.to] = d + e_adj.w;\n                    pq.push({dist_u[e_adj.to], e_adj.to});\n                }\n            }\n        }\n\n        long long w_prime = dist_u[v];\n        if (w_prime >= INF) w_prime = DIST_INF; // If unreachable, use the penalty value\n        \n        // Refined Impact: (number of shortest paths) * (increase in path length)\n        I[i] = edge_count[i] * (w_prime - w);\n    }\n\n    // Phase 3: Sort edges by impact and assign to days greedily to balance the total frustration\n    vector<int> edge_indices(M);\n    iota(edge_indices.begin(), edge_indices.end(), 0);\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return I[a] > I[b];\n    });\n\n    vector<int> assignment(M);\n    vector<int> day_count(D, 0);\n    vector<long long> day_sum_I(D, 0);\n    for (int idx : edge_indices) {\n        int best_day = -1;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K) {\n                if (best_day == -1 || day_sum_I[d] < day_sum_I[best_day]) {\n                    best_day = d;\n                }\n            }\n        }\n        assignment[idx] = best_day + 1;\n        day_count[best_day]++;\n        day_sum_I[best_day] += I[idx];\n    }\n\n    // Final Output\n    for (int i = 0; i < M; ++i) {\n        cout << assignment[i] << (i == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem: AHC019 - Silhouette\n * \n * Goal: Minimize 10^9 * (r1 + r2 + sum_{i in S} 1/vi)\n * This is equivalent to minimizing (V_only1 + V_only2 + sum_{i in Both} 1/vi).\n * \n * Strategy:\n * 1. In each z-layer, use a minimal \"cross\" shape to satisfy the silhouette.\n *    A cross centered at (x0, y0) for silhouette (X, Y) is {(x, y0) | x in X} U {(x0, y) | y in Y}.\n *    To minimize the number of cells (and thus the volume), x0 must be in X and y0 must be in Y.\n * 2. To minimize sum_{i in Both} 1/vi, we need to maximize the volumes of common blocks.\n *    We do this by maximizing the intersection of the two crosses in each layer and\n *    encouraging the common cells to be connected across z-layers.\n * 3. For each layer z, we brute-force all possible (x1, y1, x2, y2) such that:\n *    x1 in X1, y1 in Y1, x2 in X2, y2 in Y2.\n *    We maximize: Score(z) = (Number of common cells in layer z) * (Multiplier) + (Number of common cells connected to layer z-1).\n * 4. After building the two sets of cells B1 and B2, we partition them into three sets:\n *    - C: Common cells (B1 \u2229 B2)\n *    - O1: Only in B1 (B1 \\ B2)\n *    - O2: Only in B2 (B2 \\ B1)\n * 5. Connected components in C, O1, and O2 form the blocks.\n * \n * Complexity: O(D * D^4 * D) = O(D^6) which is approximately 14^6 = 7.5e6, well within 6 seconds.\n */\n\nstruct Cell {\n    int x, y, z;\n};\n\n// Find connected components in the provided 3D mask\nvoid find_components(const vector<vector<vector<bool>>>& mask, int D,\n                    vector<vector<vector<int>>>& b1, vector<vector<vector<int>>>& b2,\n                    int& block_id, int type) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    static const int dx[] = {1, -1, 0, 0, 0, 0};\n    static const int dy[] = {0, 0, 1, -1, 0, 0};\n    static const int dz[] = {0, 0, 0, 0, 1, -1};\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (mask[x][y][z] && !visited[x][y][z]) {\n                    block_id++;\n                    queue<Cell> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    while (!q.empty()) {\n                        Cell curr = q.front();\n                        q.pop();\n\n                        if (type == 0) { // Both\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        } else if (type == 1) { // Only 1\n                            b1[curr.x][curr.y][curr.z] = block_id;\n                        } else { // Only 2\n                            b2[curr.x][curr.y][curr.z] = block_id;\n                        }\n\n                        for (int i = 0; i < 6; ++i) {\n                            int nx = curr.x + dx[i];\n                            int ny = curr.y + dy[i];\n                            int nz = curr.z + dz[i];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                                mask[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                visited[nx][ny][nz] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; ++i) cin >> f1[i];\n    for (int i = 0; i < D; ++i) cin >> r1[i];\n    for (int i = 0; i < D; ++i) cin >> f2[i];\n    for (int i = 0; i < D; ++i) cin >> r2[i];\n\n    vector<vector<vector<bool>>> B1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> B2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> common_prev(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; ++z) {\n        vector<int> X1, Y1, X2, Y2;\n        vector<bool> is_X1(D, false), is_Y1(D, false), is_X2(D, false), is_Y2(D, false);\n        for (int x = 0; x < D; ++x) if (f1[z][x] == '1') { X1.push_back(x); is_X1[x] = true; }\n        for (int y = 0; y < D; ++y) if (r1[z][y] == '1') { Y1.push_back(y); is_Y1[y] = true; }\n        for (int x = 0; x < D; ++x) if (f2[z][x] == '1') { X2.push_back(x); is_X2[x] = true; }\n        for (int y = 0; y < D; ++y) if (r2[z][y] == '1') { Y2.push_back(y); is_Y2[y] = true; }\n\n        long long max_score = -1;\n        int bx1 = X1[0], by1 = Y1[0], bx2 = X2[0], by2 = Y2[0];\n\n        for (int x1 : X1) {\n            for (int y1 : Y1) {\n                // Pre-calculate cells for B1 based on (x1, y1) to speed up intersection counting\n                vector<pair<int, int>> cells_B1;\n                for (int x : X1) cells_B1.push_back({x, y1});\n                for (int y : Y1) if (y != y1) cells_B1.push_back({x1, y});\n\n                for (int x2 : X2) {\n                    for (int y2 : Y2) {\n                        int inter = 0;\n                        int conn = 0;\n                        for (auto& cell : cells_B1) {\n                            int cx = cell.first;\n                            int cy = cell.second;\n                            // Check if (cx, cy) is in B2: cross centered at (x2, y2)\n                            if ((cx == x2 && is_Y2[cy]) || (cy == y2 && is_X2[cx])) {\n                                inter++;\n                                if (z > 0 && common_prev[cx][cy][z - 1]) conn++;\n                            }\n                        }\n                        // Multiplier 1000 is large enough to prioritize total intersection over connectivity\n                        long long score = (long long)inter * 1000 + conn;\n                        if (score > max_score) {\n                            max_score = score;\n                            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Construct the selected crosses for B1 and B2\n        for (int x : X1) B1[x][by1][z] = true;\n        for (int y : Y1) B1[bx1][y][z] = true;\n        for (int x : X2) B2[x][by2][z] = true;\n        for (int y : Y2) B2[bx2][y][z] = true;\n\n        // Record common cells to be used by the next layer's connection score\n        for (int x = 0; x < D; ++x) {\n            for (int y = 0; y < D; ++y) {\n                if (B1[x][y][z] && B2[x][y][z]) {\n                    common_prev[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Partitioning into Common (C), Only in 1 (O1), and Only in 2 (O2)\n    vector<vector<vector<bool>>> mask_C(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> mask_O1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> mask_O2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (B1[x][y][z] && B2[x][y][z]) mask_C[x][y][z] = true;\n                else if (B1[x][y][z]) mask_O1[x][y][z] = true;\n                else if (B2[x][y][z]) mask_O2[x][y][z] = true;\n            }\n        }\n    }\n\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int block_id = 0;\n\n    // Form blocks using connected components in each partition\n    find_components(mask_C, D, b1, b2, block_id, 0);\n    find_components(mask_O1, D, b1, b2, block_id, 1);\n    find_components(mask_O2, D, b1, b2, block_id, 2);\n\n    // Final Output\n    cout << block_id << \"\\n\";\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                cout << b1[x][y][z] << ( (x == D - 1 && y == D - 1 && z == D - 1) ? \"\" : \" \" );\n            }\n        }\n    }\n    cout << \"\\n\";\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                cout << b2[x][y][z] << ( (x == D - 1 && y == D - 1 && z == D - 1) ? \"\" : \" \" );\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\ntypedef long long ll;\nconst ll INF_LL = 1e18;\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int id;\n};\n\nstruct Resident {\n    int x, y;\n};\n\nstruct Station {\n    int x, y;\n};\n\nint main() {\n    // Optimize I/O speed\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) cin >> stations[i].x >> stations[i].y;\n\n    vector<Edge> edges(M);\n    vector<vector<ll>> dist_matrix(N, vector<ll>(N, INF_LL));\n    vector<vector<int>> next_node(N, vector<int>(N, -1));\n    vector<vector<int>> adj_edge_idx(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) dist_matrix[i][i] = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        ll w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        if (w < dist_matrix[u][v]) {\n            dist_matrix[u][v] = dist_matrix[v][u] = w;\n            next_node[u][v] = v;\n            next_node[v][u] = u;\n            adj_edge_idx[u][v] = adj_edge_idx[v][u] = i;\n        }\n    }\n\n    // Floyd-Warshall to compute all-pairs shortest paths and paths reconstruction info\n    for (int k = 0; k < N; ++k) {\n        for (int i = 0; i < N; ++i) {\n            if (dist_matrix[i][k] == INF_LL) continue;\n            for (int j = 0; j < N; ++j) {\n                if (dist_matrix[k][j] == INF_LL) continue;\n                if (dist_matrix[i][k] + dist_matrix[k][j] < dist_matrix[i][j]) {\n                    dist_matrix[i][j] = dist_matrix[i][k] + dist_matrix[k][j];\n                    next_node[i][j] = next_node[i][k];\n                    adj_edge_idx[i][j] = adj_edge_idx[i][k]; // In case we need the exact edge index\n                    // Note: To correctly find the edge on the path, the next_node strategy is standard.\n                }\n            }\n        }\n    }\n\n    // We need to re-fill adj_edge_idx after Floyd-Warshall to ensure it stores the correct path edges\n    // But the simpler way to reconstruct paths is to use the edge matrix to find which neighbor is on the shortest path.\n    // Let's redefine next_node[i][j] to be the node v such that (i,v) is an edge and dist[i][j] = w(i,v) + dist[v][j].\n    // However, next_node[i][j] = next_node[i][k] already works for path reconstruction.\n    // Let's just update adj_edge_idx to be the direct edge index between i and next_node[i][j].\n\n    vector<Resident> residents(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    vector<vector<double>> res_dist(K, vector<double>(N));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 0; i < N; ++i) {\n            double dx = (double)stations[i].x - residents[k].x;\n            double dy = (double)stations[i].y - residents[k].y;\n            res_dist[k][i] = sqrt(dx * dx + dy * dy);\n        }\n    }\n\n    vector<int> assigned_to(K);\n    vector<multiset<double>> station_dists(N);\n    vector<int> station_count(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int best_i = 0;\n        double min_d = res_dist[k][0];\n        for (int i = 1; i < N; ++i) {\n            if (res_dist[k][i] < min_d) {\n                min_d = res_dist[k][i];\n                best_i = i;\n            }\n        }\n        assigned_to[k] = best_i;\n        station_count[best_i]++;\n        station_dists[best_i].insert(res_dist[k][best_i]);\n    }\n\n    auto get_P2_of_station = [&](int i) {\n        if (station_count[i] == 0) return 0LL;\n        double max_d = *station_dists[i].rbegin();\n        ll p = (ll)ceil(max_d - 1e-9);\n        return p * p;\n    };\n\n    auto get_mst_weight = [&](const vector<int>& counts, const vector<vector<ll>>& dm) {\n        vector<int> A;\n        for (int i = 0; i < N; ++i) {\n            if (i == 0 || counts[i] > 0) A.push_back(i);\n        }\n        if (A.size() <= 1) return 0LL;\n        int n = A.size();\n        vector<ll> min_d(n, INF_LL);\n        vector<bool> visited(n, false);\n        min_d[0] = 0;\n        ll total_w = 0;\n        for (int i = 0; i < n; ++i) {\n            int u = -1;\n            for (int j = 0; j < n; ++j) {\n                if (!visited[j] && (u == -1 || min_d[j] < min_d[u])) u = j;\n            }\n            if (u == -1 || min_d[u] == INF_LL) break;\n            visited[u] = true;\n            total_w += min_d[u];\n            for (int v = 0; v < n; ++v) {\n                if (!visited[v]) {\n                    ll d = dm[A[u]][A[v]];\n                    if (d < min_d[v]) min_d[v] = d;\n                }\n            }\n        }\n        return total_w;\n    };\n\n    ll current_P2 = 0;\n    for (int i = 0; i < N; ++i) current_P2 += get_P2_of_station(i);\n    ll current_W = get_mst_weight(station_count, dist_matrix);\n    ll current_S = current_P2 + current_W;\n\n    vector<int> best_assigned = assigned_to;\n    ll best_S = current_S;\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 127) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n        }\n        iter++;\n\n        int k = uniform_int_distribution<int>(0, K - 1)(rng);\n        int old_i = assigned_to[k];\n        int new_j = uniform_int_distribution<int>(0, N - 1)(rng);\n        if (old_i == new_j) continue;\n\n        bool a_changed = (old_i != 0 && station_count[old_i] == 1) || (new_j != 0 && station_count[new_j] == 0);\n\n        ll old_P2_i = get_P2_of_station(old_i);\n        ll old_P2_j = get_P2_of_station(new_j);\n\n        // Perform movement\n        station_count[old_i]--;\n        station_dists[old_i].erase(station_dists[old_i].find(res_dist[k][old_i]));\n        station_count[new_j]++;\n        station_dists[new_j].insert(res_dist[k][new_j]);\n        assigned_to[k] = new_j;\n\n        ll new_P2_i = get_P2_of_station(old_i);\n        ll new_P2_j = get_P2_of_station(new_j);\n        ll new_P2 = current_P2 - old_P2_i - old_P2_j + new_P2_i + new_P2_j;\n        ll new_W = a_changed ? get_mst_weight(station_count, dist_matrix) : current_W;\n        ll new_S = new_P2 + new_W;\n\n        if (new_S < current_S) {\n            current_S = new_S;\n            current_P2 = new_P2;\n            current_W = new_W;\n            if (current_S < best_S) {\n                best_S = current_S;\n                best_assigned = assigned_to;\n            }\n        } else {\n            // Revert\n            station_count[old_i]++;\n            station_dists[old_i].insert(res_dist[k][old_i]);\n            station_count[new_j]--;\n            station_dists[new_j].erase(station_dists[new_j].find(res_dist[k][new_j]));\n            assigned_to[k] = old_i;\n        }\n    }\n\n    // Reconstruction\n    vector<int> final_assigned = best_assigned;\n    vector<int> final_station_count(N, 0);\n    vector<multiset<double>> final_station_dists(N);\n    for (int k = 0; k < K; ++k) {\n        int i = final_assigned[k];\n        final_station_count[i]++;\n        final_station_dists[i].insert(res_dist[k][i]);\n    }\n\n    vector<int> P(N, 0);\n    for (int i = 0; i < N; ++i) {\n        if (final_station_count[i] > 0) {\n            double max_d = *final_station_dists[i].rbegin();\n            P[i] = (int)ceil(max_d - 1e-9);\n        }\n    }\n\n    vector<int> A;\n    for (int i = 0; i < N; ++i) {\n        if (i == 0 || final_station_count[i] > 0) A.push_back(i);\n    }\n\n    vector<int> B(M, 0);\n    if (A.size() > 1) {\n        int n = A.size();\n        vector<ll> min_d(n, INF_LL);\n        vector<int> parent(n, -1);\n        vector<bool> visited(n, false);\n        min_d[0] = 0;\n        for (int i = 0; i < n; ++i) {\n            int u = -1;\n            for (int j = 0; j < n; ++j) {\n                if (!visited[j] && (u == -1 || min_d[j] < min_d[u])) u = j;\n            }\n            if (u == -1 || min_d[u] == INF_LL) break;\n            visited[u] = true;\n            if (parent[u] != -1) {\n                int start_node = A[parent[u]];\n                int end_node = A[u];\n                int curr = start_node;\n                while (curr != end_node) {\n                    int nxt = next_node[curr][end_node];\n                    // Find the edge between curr and nxt\n                    for (int m = 0; m < M; ++m) {\n                        if ((edges[m].u == curr && edges[m].v == nxt) || (edges[m].u == nxt && edges[m].v == curr)) {\n                            if (edges[m].w == dist_matrix[curr][nxt] || edges[m].w >= 0) { // Check if this edge is actually on the shortest path\n                                // Since it's a simple graph, the first edge we find connecting them is the one\n                                B[m] = 1;\n                                break;\n                            }\n                        }\n                    }\n                    curr = nxt;\n                }\n            }\n            for (int v = 0; v < n; ++v) {\n                if (!visited[v]) {\n                    ll d = dist_matrix[A[u]][A[v]];\n                    if (d < min_d[v]) {\n                        min_d[v] = d;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << P[i] << (i == N - 1 ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int i = 0; i < M; ++i) cout << B[i] << (i == M - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The problem asks us to transform a random N-tiered pyramid into a min-heap\n * where every ball (x, y) is smaller than its children (x+1, y) and (x+1, y+1).\n * Swaps are allowed only between adjacent balls in 6 directions.\n * \n * Goal: E = 0 (satisfy heap property) and minimize K (swaps), where K <= 10,000.\n * Score: 100,000 - 5K.\n * \n * Approach:\n * A standard heapify (sift-down) algorithm is very efficient (O(M) swaps),\n * where M = N(N+1)/2. For N=30, the maximum number of swaps is roughly 4,500,\n * which guarantees E=0 and a score of at least 100,000 - 5(4500) = 77,500.\n * \n * To improve this, we can use a greedy \"max-violation\" approach.\n * Instead of building the heap in a fixed order, we always pick the most\n * \"severe\" violation (the pair (parent, child) with the largest difference\n * b[parent] - b[child]) and swap them. This is essentially a hill-climbing\n * approach that directly addresses the largest heap property violations.\n * \n * This greedy approach is likely to reduce the total number of swaps K\n * compared to a standard bottom-up heapify, leading to a higher score.\n */\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nstruct Violation {\n    int diff;\n    int x, y;\n    int type; // 0 for child (x+1, y), 1 for child (x+1, y+1)\n\n    bool operator<(const Violation& other) const {\n        return diff < other.diff;\n    }\n};\n\nconst int N = 30;\nint pyramid[N][N];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> pyramid[i][j])) break;\n        }\n    }\n\n    vector<Swap> swaps;\n    priority_queue<Violation> pq;\n\n    // Function to check for a violation at (x, y) and add to pq\n    auto check_violation = [&](int x, int y) {\n        if (x < 0 || x >= N - 1) return;\n        // Check child 1: (x+1, y)\n        if (y <= x + 1 && pyramid[x][y] > pyramid[x + 1][y]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y], x, y, 0});\n        }\n        // Check child 2: (x+1, y+1)\n        if (y + 1 <= x + 1 && pyramid[x][y] > pyramid[x + 1][y + 1]) {\n            pq.push({pyramid[x][y] - pyramid[x + 1][y + 1], x, y, 1});\n        }\n    };\n\n    // Initialize priority queue with all initial violations\n    for (int x = 0; x < N - 1; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            check_violation(x, y);\n        }\n    }\n\n    // Greedy swap approach\n    while (!pq.empty() && swaps.size() < 10000) {\n        Violation top = pq.top();\n        pq.pop();\n\n        int x = top.x;\n        int y = top.y;\n        int cx = x + 1;\n        int cy = y + top.type;\n\n        // Check if the violation is still valid and has the same difference\n        if (pyramid[x][y] - pyramid[cx][cy] != top.diff) continue;\n\n        // Perform the swap\n        swaps.push_back({x, y, cx, cy});\n        swap(pyramid[x][y], pyramid[cx][cy]);\n\n        // After swap, violations might have changed for:\n        // 1. (x, y) and its children\n        // 2. (cx, cy) and its children\n        // 3. (x, y)'s parents\n        // 4. (cx, cy)'s parents\n        \n        // Re-check (x, y) and its children\n        check_violation(x, y);\n        // Re-check (cx, cy) and its children\n        check_violation(cx, cy);\n        // Re-check parents of (x, y)\n        if (x > 0) {\n            check_violation(x - 1, y - 1);\n            check_violation(x - 1, y);\n        }\n        // Re-check parents of (cx, cy)\n        if (cx > 0) {\n            check_violation(cx - 1, cy - 1);\n            check_violation(cx - 1, cy);\n        }\n    }\n\n    // Output the results\n    cout << swaps.size() << \"\\n\";\n    for (const auto& s : swaps) {\n        cout << s.x1 << \" \" << s.y1 << \" \" << s.x2 << \" \" << s.y2 << \"\\n\";\n    }\n\n    return 0;\n}\n","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int r, c;\n    bool operator==(const Pos& other) const { return r == other.r && c == other.c; }\n    bool operator!=(const Pos& other) const { return !(*this == other); }\n};\n\nint D, N;\nbool is_obstacle[10][10];\nbool is_occupied[10][10];\nint id_at_square[10][10];\nint dist_val[10][10];\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D && !is_obstacle[r][c];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            is_obstacle[i][j] = false;\n            is_occupied[i][j] = false;\n            id_at_square[i][j] = -1;\n            dist_val[i][j] = 1000;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        is_occupied[r][c] = true;\n    }\n\n    Pos entrance = {0, (D - 1) / 2};\n\n    vector<Pos> bfs_order;\n    queue<Pos> q_bfs;\n    q_bfs.push(entrance);\n    dist_val[entrance.r][entrance.c] = 0;\n    \n    vector<vector<bool>> visited_bfs(D, vector<bool>(D, false));\n    visited_bfs[entrance.r][entrance.c] = true;\n\n    while(!q_bfs.empty()){\n        Pos curr = q_bfs.front();\n        q_bfs.pop();\n        if (curr != entrance) bfs_order.push_back(curr);\n\n        for(int i=0; i<4; ++i){\n            int nr = curr.r + dr[i], nc = curr.c + dc[i];\n            if(is_valid(nr, nc) && !visited_bfs[nr][nc]){\n                visited_bfs[nr][nc] = true;\n                dist_val[nr][nc] = dist_val[curr.r][curr.c] + 1;\n                q_bfs.push({nr, nc});\n            }\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    for (int d = 0; d < M; ++d) {\n        int t_d;\n        if (!(cin >> t_d)) break;\n\n        int ideal_dist = 1000;\n        if (t_d < (int)bfs_order.size()) {\n            ideal_dist = dist_val[bfs_order[t_d].r][bfs_order[t_d].c];\n        } else if (!bfs_order.empty()) {\n            ideal_dist = dist_val[bfs_order.back().r][bfs_order.back().c];\n        }\n\n        vector<Pos> reachable_empty;\n        queue<Pos> rq;\n        rq.push(entrance);\n        vector<vector<bool>> visited_reach(D, vector<bool>(D, false));\n        visited_reach[entrance.r][entrance.c] = true;\n\n        while (!rq.empty()) {\n            Pos curr = rq.front();\n            rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                if (is_valid(nr, nc) && !visited_reach[nr][nc] && !is_occupied[nr][nc]) {\n                    visited_reach[nr][nc] = true;\n                    reachable_empty.push_back({nr, nc});\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        vector<Pos> safe_squares;\n        for (auto& s : reachable_empty) {\n            bool safe = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = s.r + dr[i], nc = s.c + dc[i];\n                if (is_valid(nr, nc) && dist_val[nr][nc] > dist_val[s.r][s.c] && !is_occupied[nr][nc]) {\n                    safe = false;\n                    break;\n                }\n            }\n            if (safe) safe_squares.push_back(s);\n        }\n\n        Pos best_s = {-1, -1};\n        auto pick_best = [&](const vector<Pos>& candidates) {\n            int min_diff = 1000;\n            int max_dist_found = -1;\n            for (auto& s : candidates) {\n                int diff = abs(dist_val[s.r][s.c] - ideal_dist);\n                if (diff < min_diff) {\n                    min_diff = diff;\n                    max_dist_found = dist_val[s.r][s.c];\n                    best_s = s;\n                } else if (diff == min_diff) {\n                    if (dist_val[s.r][s.c] > max_dist_found) {\n                        max_dist_found = dist_val[s.r][s.c];\n                        best_s = s;\n                    }\n                }\n            }\n        };\n\n        if (!safe_squares.empty()) pick_best(safe_squares);\n        else if (!reachable_empty.empty()) pick_best(reachable_empty);\n\n        if (best_s.r == -1) {\n            for(int r=0; r<D; ++r)\n                for(int c=0; c<D; ++c)\n                    if (is_valid(r, c) && !is_occupied[r][c] && !(r == entrance.r && c == entrance.c))\n                        { best_s = {r, c}; goto placed; }\n        }\n        placed:\n\n        is_occupied[best_s.r][best_s.c] = true;\n        id_at_square[best_s.r][best_s.c] = t_d;\n        cout << best_s.r << \" \" << best_s.c << endl;\n    }\n\n    vector<bool> transported(M, false);\n    for (int step = 0; step < M; ++step) {\n        vector<vector<bool>> reach_grid(D, vector<bool>(D, false));\n        queue<Pos> rq;\n        rq.push(entrance);\n        reach_grid[entrance.r][entrance.c] = true;\n        while (!rq.empty()) {\n            Pos curr = rq.front(); rq.pop();\n            for (int i = 0; i < 4; ++i) {\n                int nr = curr.r + dr[i], nc = curr.c + dc[i];\n                if (is_valid(nr, nc) && !reach_grid[nr][nc] && !is_occupied[nr][nc]) {\n                    reach_grid[nr][nc] = true;\n                    rq.push({nr, nc});\n                }\n            }\n        }\n\n        int best_id = 1e9;\n        Pos best_pos = {-1, -1};\n        for (int r = 0; r < D; ++r) {\n            for (int c = 0; c < D; ++c) {\n                int id = id_at_square[r][c];\n                if (id != -1 && !transported[id]) {\n                    bool can_reach = false;\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r + dr[i], nc = c + dc[i];\n                        if (nr >= 0 && nr < D && nc >= 0 && nc < D && reach_grid[nr][nc]) {\n                            can_reach = true; break;\n                        }\n                    }\n                    if (can_reach && id < best_id) {\n                        best_id = id;\n                        best_pos = {r, c};\n                    }\n                }\n            }\n        }\n\n        if (best_id != 1e9) {\n            transported[best_id] = true;\n            is_occupied[best_pos.r][best_pos.c] = false;\n            id_at_square[best_pos.r][best_pos.c] = -1;\n            cout << best_pos.r << \" \" << best_pos.c << \"\\n\";\n        } else break;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to represent a given adjacency graph of colors (wards) on an n x n grid,\n * minimizing the number of tiles used for the wards (maximizing the number of color 0 tiles).\n * The adjacencies between any two colors (including color 0) must be identical to the original.\n * Each color must form a connected set of tiles.\n * \n * Since the adjacency graph is planar (derived from a map), and the grid (50x50) is much larger \n * than the number of colors (100), we can use a greedy approach.\n * We place each color one by one using a BFS-based path construction.\n * To maintain the \"identical adjacency\" property, we use a \"safe cell\" condition:\n * a cell is safe for color c if it is currently color 0 and all its non-zero neighbors \n * are colors that c is actually adjacent to in the original map.\n * \n * Algorithm:\n * 1. Construct the adjacency graph G from the input.\n * 2. Use a BFS order starting from color 0 to decide the order of placing colors.\n * 3. For each color c:\n *    a. Identify the set T of colors already placed that c is adjacent to in G.\n *    b. Find a path of \"safe\" cells that connects c to all colors in T.\n *    c. A cell is safe if it's 0 and all its neighbors in the current grid belong to T.\n *    d. Use BFS to find the shortest paths connecting these target colors.\n *    e. Update the grid by coloring these cells with c.\n * 4. Output the resulting grid.\n */\n\nconst int N = 50;\nint grid[N][N];\nint n, m;\n\nstruct Pos {\n    int r, c;\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nbool is_valid(int r, int c) {\n    return r >= 0 && r < n && c >= 0 && c < n;\n}\n\n// A cell is safe for color c if it's 0 and its non-0 neighbors are all in the target set T.\nbool is_safe(int r, int c, const set<int>& T) {\n    if (grid[r][c] != 0) return false;\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (is_valid(nr, nc)) {\n            if (grid[nr][nc] != 0) {\n                if (T.find(grid[nr][nc]) == T.end()) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    // Faster I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> original_grid(n, vector<int>(n));\n    set<int> adj[105]; // m can be up to 100\n    \n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> original_grid[i][j];\n        }\n    }\n\n    // Build the adjacency graph from the input map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = original_grid[i][j];\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (is_valid(ni, nj)) {\n                    int nc = original_grid[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                        adj[nc].insert(c);\n                    }\n                } else {\n                    // Adjacent to the outside (represented by color 0)\n                    if (c != 0) {\n                        adj[c].insert(0);\n                        adj[0].insert(c);\n                    }\n                }\n            }\n        }\n    }\n\n    // Initialize the output grid with 0\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            grid[i][j] = 0;\n        }\n    }\n\n    // Determine the order of placement using BFS from color 0\n    vector<int> bfs_order;\n    queue<int> q_bfs;\n    q_bfs.push(0);\n    vector<bool> visited_bfs(m + 1, false);\n    visited_bfs[0] = true;\n    while (!q_bfs.empty()) {\n        int u = q_bfs.front();\n        q_bfs.pop();\n        if (u != 0) bfs_order.push_back(u);\n        for (int v : adj[u]) {\n            if (v <= m && v != 0 && !visited_bfs[v]) {\n                visited_bfs[v] = true;\n                q_bfs.push(v);\n            }\n        }\n    }\n    // Add any unvisited colors just in case\n    for (int i = 1; i <= m; ++i) {\n        if (!visited_bfs[i]) bfs_order.push_back(i);\n    }\n\n    set<int> P = {0}; // Colors already placed in the output grid\n\n    for (int c : bfs_order) {\n        // T is the set of colors already in the grid that c must be adjacent to\n        set<int> T;\n        for (int neighbor : adj[c]) {\n            if (P.count(neighbor)) {\n                T.insert(neighbor);\n            }\n        }\n\n        if (T.empty()) continue;\n\n        vector<Pos> Sc; // Set of cells to be assigned color c\n        Pos start_pos = {-1, -1};\n        bool found_start = false;\n        \n        // Find a starting safe cell adjacent to the first color in T\n        int d_first = *T.begin();\n        if (d_first != 0) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (grid[i][j] == d_first) {\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && is_safe(ni, nj, T)) {\n                                start_pos = {ni, nj};\n                                found_start = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            // If the first color is 0, any safe cell adjacent to 0 works\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        bool adj_to_zero = false;\n                        for (int k = 0; k < 4; ++k) {\n                            int ni = i + dr[k], nj = j + dc[k];\n                            if (is_valid(ni, nj) && grid[ni][nj] == 0) {\n                                adj_to_zero = true;\n                                break;\n                            }\n                        }\n                        if (adj_to_zero) {\n                            start_pos = {i, j};\n                            found_start = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: if no specifically adjacent start cell is found, pick any safe cell\n        if (!found_start) {\n            for (int i = 0; i < n && !found_start; ++i) {\n                for (int j = 0; j < n && !found_start; ++j) {\n                    if (is_safe(i, j, T)) {\n                        start_pos = {i, j};\n                        found_start = true;\n                    }\n                }\n            }\n        }\n\n        if (found_start) {\n            Sc.push_back(start_pos);\n            // Iteratively connect Sc to every other color in T using BFS\n            for (int d : T) {\n                if (d == d_first) continue;\n                \n                // Check if Sc is already adjacent to color d\n                bool already_adj = false;\n                for (auto p : Sc) {\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = p.r + dr[k], nj = p.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            already_adj = true;\n                            break;\n                        }\n                    }\n                    if (already_adj) break;\n                }\n                if (already_adj) continue;\n\n                // BFS to find the shortest path of safe cells to color d\n                queue<Pos> q;\n                vector<vector<int>> dist(n, vector<int>(n, -1));\n                vector<vector<Pos>> parent(n, vector<Pos>(n, {-1, -1}));\n                for (auto p : Sc) {\n                    q.push(p);\n                    dist[p.r][p.c] = 0;\n                }\n                Pos end_pos = {-1, -1};\n                while (!q.empty()) {\n                    Pos curr = q.front(); q.pop();\n                    bool adj_to_d = false;\n                    for (int k = 0; k < 4; ++k) {\n                        int ni = curr.r + dr[k], nj = curr.c + dc[k];\n                        if (is_valid(ni, nj) && grid[ni][nj] == d) {\n                            adj_to_d = true; \n                            break;\n                        }\n                    }\n                    if (adj_to_d) {\n                        end_pos = curr;\n                        break;\n                    }\n                    for (int k = 0; k < 4; ++k) {\n                        int nr = curr.r + dr[k], nc = curr.c + dc[k];\n                        if (is_valid(nr, nc) && dist[nr][nc] == -1 && is_safe(nr, nc, T)) {\n                            dist[nr][nc] = dist[curr.r][curr.c] + 1;\n                            parent[nr][nc] = curr;\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                // If a path is found, add it to the set Sc\n                if (end_pos.r != -1) {\n                    Pos curr = end_pos;\n                    while (dist[curr.r][curr.c] != 0) {\n                        Sc.push_back(curr);\n                        curr = parent[curr.r][curr.c];\n                    }\n                }\n            }\n            // Update grid with color c\n            for (auto p : Sc) grid[p.r][p.c] = c;\n            P.insert(c);\n        }\n    }\n\n    // Print the resulting map\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc025":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Divide N items into D sets with nearly equal total weight.\n * Item weights are unknown. Use a balance to compare sets.\n * \n * Strategy:\n * 1. Weight Estimation:\n *    - We model the weights using log-weights x_i = log(w_i) to ensure positivity.\n *    - An Adam optimizer is used to find x_i that satisfy the balance query results.\n *    - We use a squared-error-style loss function for the hinge loss:\n *      If result is '>', we want sum(L) - sum(R) > 0.\n *      If result is '<', we want sum(L) - sum(R) < 0.\n *      If result is '=', we want sum(L) - sum(R) = 0.\n *    - The loss is calculated based on the deviation when the balance condition is not met.\n * \n * 2. Query Selection:\n *    - Instead of always picking the same items, we use a randomized greedy approach.\n *    - For each query, we pick a random subset of items and use a greedy approach \n *      to partition them into L and R to minimize |sum(L) - sum(R)|.\n * \n * 3. Final Partitioning:\n *    - After all queries, we estimate final weights and use Simulated Annealing (SA) \n *      to minimize the sum of squared set weights, which is equivalent to minimizing variance.\n *    - We use an optimized SA with an efficient delta-energy calculation.\n */\n\nstruct Adam {\n    int N;\n    vector<double> x, m, v;\n    double beta1 = 0.9, beta2 = 0.999, eps = 1e-8, alpha = 0.05;\n    int t = 0;\n\n    Adam(int n) : N(n), x(n, 0.0), m(n, 0.0), v(n, 0.0) {}\n\n    void update(const vector<double>& g) {\n        t++;\n        double b1_t = pow(beta1, t);\n        double b2_t = pow(beta2, t);\n        for (int i = 0; i < N; ++i) {\n            m[i] = beta1 * m[i] + (1.0 - beta1) * g[i];\n            v[i] = beta2 * v[i] + (1.0 - beta2) * g[i] * g[i];\n            double m_hat = m[i] / (1.0 - b1_t);\n            double v_hat = v[i] / (1.0 - b2_t);\n            x[i] -= alpha * m_hat / (sqrt(v_hat) + eps);\n        }\n    }\n\n    double get_w(int i) { return exp(x[i]); }\n};\n\nstruct Query {\n    vector<int> L, R;\n    char res;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    Adam adam(N);\n    vector<Query> queries;\n    mt19937 rng(42);\n\n    for (int q = 0; q < Q; ++q) {\n        // 1. Randomized Greedy Query Selection\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        \n        vector<double> current_weights(N);\n        for(int i = 0; i < N; ++i) current_weights[i] = adam.get_w(i);\n\n        // Pick a random subset size k and partition it\n        int k = uniform_int_distribution<int>(2, N)(rng);\n        vector<int> subset;\n        for(int i = 0; i < k; ++i) subset.push_back(indices[i]);\n        sort(subset.begin(), subset.end(), [&](int a, int b) {\n            return current_weights[a] > current_weights[b];\n        });\n\n        vector<int> L, R;\n        double sumL = 0, sumR = 0;\n        for (int idx : subset) {\n            if (sumL <= sumR) { L.push_back(idx); sumL += current_weights[idx]; }\n            else { R.push_back(idx); sumR += current_weights[idx]; }\n        }\n\n        // Ensure sets are non-empty\n        if (L.empty()) { L.push_back(R.back()); R.pop_back(); }\n        if (R.empty()) { R.push_back(L.back()); L.pop_back(); }\n\n        cout << L.size() << \" \" << R.size();\n        for (int idx : L) cout << \" \" << idx;\n        for (int idx : R) cout << \" \" << idx;\n        cout << endl;\n\n        char res;\n        if (!(cin >> res)) break;\n        queries.push_back({L, R, res});\n\n        // 2. Weight Estimation: Adam with Squared Hinge Loss\n        int window = min((int)queries.size(), 100);\n        vector<double> g(N, 0.0);\n        for (int i = 0; i < window; ++i) {\n            const auto& query = queries[queries.size() - 1 - i];\n            double sL = 0, sR = 0;\n            for (int idx : query.L) sL += adam.get_w(idx);\n            for (int idx : query.R) sR += adam.get_w(idx);\n\n            if (query.res == '>') {\n                if (sL < sR) {\n                    double diff = sR - sL;\n                    for (int idx : query.L) g[idx] -= 2.0 * diff * adam.get_w(idx);\n                    for (int idx : query.R) g[idx] += 2.0 * diff * adam.get_w(idx);\n                }\n            } else if (query.res == '<') {\n                if (sL > sR) {\n                    double diff = sL - sR;\n                    for (int idx : query.L) g[idx] += 2.0 * diff * adam.get_w(idx);\n                    for (int idx : query.R) g[idx] -= 2.0 * diff * adam.get_w(idx);\n                }\n            } else if (query.res == '=') {\n                double diff = sL - sR;\n                for (int idx : query.L) g[idx] += 2.0 * diff * adam.get_w(idx);\n                for (int idx : query.R) g[idx] -= 2.0 * diff * adam.get_w(idx);\n            }\n        }\n        for (int i = 0; i < N; ++i) g[i] += 0.001 * adam.x[i]; // Regularization\n        adam.update(g);\n    }\n\n    // 3. Final Partitioning: Simulated Annealing\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = adam.get_w(i);\n\n    vector<int> d(N);\n    vector<double> set_sum(D, 0.0);\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) { return w[a] > w[b]; });\n\n    // Initial Greedy Partitioning\n    for (int idx : p) {\n        int best_s = 0;\n        for (int s = 1; s < D; ++s) if (set_sum[s] < set_sum[best_s]) best_s = s;\n        d[idx] = best_s;\n        set_sum[best_s] += w[idx];\n    }\n\n    double max_w = 0;\n    for (double val : w) max_w = max(max_w, val);\n    double T_start = 2.0 * max_w * max_w;\n    double T_end = 1e-4;\n    int total_iters = 2000000;\n    double factor = pow(T_end / T_start, 1.0 / total_iters);\n    double T = T_start;\n\n    double current_energy = 0;\n    for (int s = 0; s < D; ++s) current_energy += set_sum[s] * set_sum[s];\n\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.85;\n\n    for (int iter = 0; iter < total_iters; ++iter) {\n        if ((iter & 2047) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0 > time_limit) break;\n        }\n\n        int type = rng() % 2;\n        if (type == 0) { // Move item i\n            int i = rng() % N;\n            int old_s = d[i];\n            int new_s = rng() % D;\n            if (old_s != new_s) {\n                double delta_E = 2.0 * w[i] * (w[i] + set_sum[new_s] - set_sum[old_s]);\n                if (delta_E < 0 || exp(-delta_E / T) > (double)rng() / mt19937::max()) {\n                    set_sum[old_s] -= w[i];\n                    set_sum[new_s] += w[i];\n                    d[i] = new_s;\n                    current_energy += delta_E;\n                }\n            }\n        } else { // Swap item i and j\n            int i = rng() % N, j = rng() % N;\n            int s_i = d[i], s_j = d[j];\n            if (s_i != s_j) {\n                double diff_w = w[i] - w[j];\n                double diff_s = set_sum[s_i] - set_sum[s_j];\n                double delta_E = 2.0 * diff_w * (diff_w - diff_s);\n                if (delta_E < 0 || exp(-delta_E / T) > (double)rng() / mt19937::max()) {\n                    set_sum[s_i] = set_sum[s_i] - w[i] + w[j];\n                    set_sum[s_j] = set_sum[s_j] - w[j] + w[i];\n                    d[i] = s_j;\n                    d[j] = s_i;\n                    current_energy += delta_E;\n                }\n            }\n        }\n        T *= factor;\n    }\n\n    for (int i = 0; i < N; ++i) cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc026":"#include <iostream>\n#include <vector>\n#include <deque>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to remove boxes in order 1, 2, ..., n.\n * - A box can be removed (Operation 2, cost 0) only if it is at the top of its stack.\n * - If a box v is not at the top, we must move all boxes above it to another stack (Operation 1, cost k+1).\n * - Our goal is to minimize total energy (sum of k+1).\n * \n * Key Insight:\n * - To minimize future costs, we want stacks to be in \"descending order\" from bottom to top.\n * - If a stack is [..., 5, 4, 3, 2, 1] (top is 1), then after removing 1, 2 becomes the top, then 3, etc.\n * - This way, many boxes can be removed using Operation 2 (cost 0) instead of Operation 1.\n * - A \"violation\" is defined as a pair (x, y) where x is below y but x < y.\n * - We use a greedy approach: when moving boxes above v to another stack, we pick the stack\n *   that minimizes the number of violations in the resulting stack, with a tie-breaker\n *   of minimizing the total stack size.\n * \n * Complexity:\n * - n=200, m=10.\n * - For each of the n boxes, we check m-1 possible target stacks.\n * - Each check takes O(n) to count violations.\n * - Total complexity: O(n^2 * m), which is ~400,000 operations. Well within 2.0s.\n */\n\n// Function to count the number of violations (x < y where x is below y) in a stack\nint count_violations(const deque<int>& s) {\n    int violations = 0;\n    for (size_t i = 0; i + 1 < s.size(); ++i) {\n        if (s[i] < s[i + 1]) {\n            violations++;\n        }\n    }\n    return violations;\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    // stacks[i] stores the boxes in stack i (bottom to top)\n    vector<deque<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n\n    // Record all operations to output at the end\n    // (v, 0) for Operation 2, (v, i) for Operation 1 (i is 1-indexed)\n    vector<pair<int, int>> operations;\n\n    for (int v = 1; v <= n; ++v) {\n        int current_stack_idx = -1;\n        int v_pos = -1;\n\n        // Step 1: Find the current position and stack of box v\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                    current_stack_idx = i;\n                    v_pos = j;\n                    break;\n                }\n            }\n            if (current_stack_idx != -1) break;\n        }\n\n        // Step 2: If v is not at the top, move all boxes above it to another stack\n        if (v_pos < (int)stacks[current_stack_idx].size() - 1) {\n            // The box immediately above v is our target for Operation 1\n            int u_idx = v_pos + 1;\n            int u = stacks[current_stack_idx][u_idx];\n\n            // Collect all boxes to be moved (from u to the current top)\n            vector<int> to_move;\n            for (int k = u_idx; k < (int)stacks[current_stack_idx].size(); ++k) {\n                to_move.push_back(stacks[current_stack_idx][k]);\n            }\n\n            // Greedy decision: Which stack to move these boxes to?\n            int best_target_idx = -1;\n            long long min_cost = -1;\n\n            for (int i = 0; i < m; ++i) {\n                if (i == current_stack_idx) continue;\n\n                // Simulate adding the moved part to stack i\n                deque<int> simulated_stack = stacks[i];\n                for (int val : to_move) {\n                    simulated_stack.push_back(val);\n                }\n\n                // Cost function: prioritize minimizing violations, then minimize stack size\n                // Large weight for violations to ensure it is the primary objective\n                long long cost = (long long)count_violations(simulated_stack) * 10000LL + (long long)simulated_stack.size();\n\n                if (best_target_idx == -1 || cost < min_cost) {\n                    min_cost = cost;\n                    best_target_idx = i;\n                }\n            }\n\n            // Perform the chosen move\n            // Remove the moved boxes from the current stack\n            for (size_t k = 0; k < to_move.size(); ++k) {\n                stacks[current_stack_idx].pop_back();\n            }\n            // Add the moved boxes to the target stack\n            for (int val : to_move) {\n                stacks[best_target_idx].push_back(val);\n            }\n\n            // Record Operation 1 (u, target_stack_1_indexed)\n            operations.push_back({u, best_target_idx + 1});\n        }\n\n        // Step 3: v is now at the top of its stack, remove it using Operation 2\n        operations.push_back({v, 0});\n        stacks[current_stack_idx].pop_back();\n    }\n\n    // Step 4: Output the operations\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The objective is to minimize the average dirtiness over an infinite period.\n * The average dirtiness of a square (i, j) is given by (d_{i,j} * (T_{i,j} - 1) / 2),\n * where T_{i,j} is the interval between visits to square (i, j).\n * If we have a cleaning route of length L, and m_{i,j} is the number of visits to \n * square (i, j), then T_{i,j} = L / m_{i,j}.\n * The total average dirtiness is S = sum_{i,j} [d_{i,j} * (L/m_{i,j} - 1) / 2].\n * S = (L/2) * sum_{i,j} (d_{i,j}/m_{i,j}) - (1/2) * sum_{i,j} d_{i,j}.\n * To minimize this, the frequency f_{i,j} = m_{i,j}/L should be proportional to sqrt(d_{i,j}).\n *\n * Algorithm:\n * 1. Generate an initial cleaning route using DFS that visits all reachable squares \n *    and returns to (0, 0). This route ensures each edge is traversed twice.\n * 2. Use a greedy approach to add \"detours\" to this route. A detour on edge (u, v) \n *    consists of moves u -> v -> u -> v, which increases m_u and m_v by 1 and \n *    increases the total length L by 2.\n * 3. The benefit (change in S) of adding a detour to edge (u, v) is:\n *    Delta S = -((L/2) + 1) * (d_u / (m_u * (m_u + 1)) + d_v / (m_v * (m_v + 1))) + Sigma,\n *    where Sigma = sum_{i,j} (d_{i,j}/m_{i,j}).\n * 4. We use a priority queue to greedily select the edge that provides the most \n *    negative Delta S, updating Sigma and L as we add detours, until the length \n *    reaches 10^5 or no more improvements are possible.\n */\n\nstruct Square {\n    int r, c;\n};\n\nint N;\nvector<string> h_walls;\nvector<string> v_walls;\nvector<vector<int>> d;\nbool visited[40][40];\nvector<Square> path;\nvector<char> move_chars;\n\n// DFS to generate a route that visits all reachable squares and returns to (0,0).\nvoid dfs(int r, int c) {\n    visited[r][c] = true;\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n    char move_c[] = {'R', 'D', 'L', 'U'};\n    char back_c[] = {'L', 'U', 'R', 'D'};\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited[nr][nc]) {\n            bool wall = false;\n            if (i == 0) wall = (v_walls[r][c] == '1'); // Right\n            else if (i == 1) wall = (h_walls[r][c] == '1'); // Down\n            else if (i == 2) wall = (v_walls[nr][nc] == '1'); // Left\n            else if (i == 3) wall = (h_walls[nr][nc] == '1'); // Up\n\n            if (!wall) {\n                move_chars.push_back(move_c[i]);\n                path.push_back({nr, nc});\n                dfs(nr, nc);\n                move_chars.push_back(back_c[i]);\n                path.push_back({r, c});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[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    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited[i][j] = false;\n        }\n    }\n\n    path.push_back({0, 0});\n    dfs(0, 0);\n\n    int L = move_chars.size();\n    vector<int> m(N * N, 0);\n    for (int i = 0; i < L; ++i) {\n        m[path[i].r * N + path[i].c]++;\n    }\n\n    double sigma = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sigma += (double)d[i][j] / m[i * N + j];\n        }\n    }\n\n    auto get_delta = [&](int k, int current_L) {\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double term1 = (double)d[u / N][u % N] / (m[u] * (m[u] + 1.0));\n        double term2 = (double)d[v / N][v % N] / (m[v] * (m[v] + 1.0));\n        double delta = -(current_L / 2.0 + 1.0) * (term1 + term2) + sigma;\n        return delta;\n    };\n\n    priority_queue<pair<double, int>> pq;\n    for (int k = 0; k < L; ++k) {\n        pq.push({-get_delta(k, L), k});\n    }\n\n    vector<int> detours(L, 0);\n    int current_L = L;\n\n    while (current_L + 2 <= 100000 && !pq.empty()) {\n        pair<double, int> top = pq.top();\n        pq.pop();\n\n        int k = top.second;\n        double neg_delta = top.first;\n\n        double current_delta = get_delta(k, current_L);\n        if (current_delta > -1e-9) break; \n\n        // Lazy update check\n        if (abs(neg_delta - (-current_delta)) > 1e-7) {\n            pq.push({-current_delta, k});\n            continue;\n        }\n\n        // Add detour\n        detours[k]++;\n        int u = path[k].r * N + path[k].c;\n        int v = path[k + 1].r * N + path[k + 1].c;\n        double du = (double)d[u / N][u % N];\n        double dv = (double)d[v / N][v % N];\n        double mu = (double)m[u];\n        double mv = (double)m[v];\n\n        sigma = sigma - du / mu - dv / mv + du / (mu + 1.0) + dv / (mv + 1.0);\n        m[u]++;\n        m[v]++;\n        current_L += 2;\n\n        pq.push({-get_delta(k, current_L), k});\n    }\n\n    string final_route = \"\";\n    for (int k = 0; k < L; ++k) {\n        final_route += move_chars[k];\n        if (detours[k] > 0) {\n            char move_k = move_chars[k];\n            char rev_move_k;\n            if (move_k == 'R') rev_move_k = 'L';\n            else if (move_k == 'L') rev_move_k = 'R';\n            else if (move_k == 'U') rev_move_k = 'D';\n            else rev_move_k = 'U';\n\n            for (int i = 0; i < detours[k]; ++i) {\n                final_route += rev_move_k;\n                final_route += move_k;\n            }\n        }\n    }\n\n    cout << final_route << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Kakizome Taikai\n * Strategy:\n * 1. Precompute distances and overlaps between strings.\n * 2. Precompute the minimum cost to add a suffix of each target string t[k]\n *    starting from any (r_s, c_s) and ending at any (r_e, c_e).\n *    Since the number of states (M * 5 * N^2 * N^2) is around 5 * 10^7,\n *    we store it in an unsigned short array of about 100 MB.\n * 3. Use Simulated Annealing to optimize the order in which we attempt to cover the target strings.\n *    The scoring function for SA prioritizes covering all M strings (K=M) \n *    and then minimizes the total cost T.\n * 4. Reconstruct the final path using the best order found.\n */\n\nconst int MAX_N = 15;\nconst int MAX_M = 200;\nconst int MAX_S = 225;\nconst unsigned short INF = 32767;\n\nint N, M;\nint si, sj;\nstring A[MAX_N];\nstring t[MAX_M];\nint dist[MAX_N][MAX_N][MAX_N][MAX_N];\nint overlap_mat[MAX_M][MAX_M];\n\n// pre[k][p][r_s*N+c_s][r_e*N+c_e]\nunsigned short pre[MAX_M][5][MAX_S][MAX_S];\n\nvoid precompute() {\n    for (int r1 = 0; r1 < N; ++r1)\n        for (int c1 = 0; c1 < N; ++c1)\n            for (int r2 = 0; r2 < N; ++r2)\n                for (int c2 = 0; c2 < N; ++c2)\n                    dist[r1][c1][r2][c2] = abs(r1 - r2) + abs(c1 - c2) + 1;\n\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            int max_ov = 0;\n            for (int len = 1; len <= 4; ++len) {\n                if (t[i].substr(5 - len) == t[j].substr(0, len)) {\n                    max_ov = len;\n                }\n            }\n            overlap_mat[i][j] = max_ov;\n        }\n    }\n\n    for (int k = 0; k < M; ++k) {\n        for (int p = 0; p < 5; ++p) {\n            string suffix = t[k].substr(p);\n            int L = suffix.length();\n            for (int rs = 0; rs < N; ++rs) {\n                for (int cs = 0; cs < N; ++cs) {\n                    vector<vector<unsigned short>> dp(L + 1, vector<unsigned short>(N * N, INF));\n                    // Base case: first character of suffix\n                    for (int r = 0; r < N; ++r) {\n                        for (int c = 0; c < N; ++c) {\n                            if (A[r][c] == suffix[0]) {\n                                if (L == 1) {\n                                    // if L=1, dp[1][r][c] is already the cost to type first char.\n                                    // But we need it relative to (rs, cs).\n                                    // To simplify, let's just let dp[1][r][c] be the movement + 1.\n                                }\n                                dp[1][r * N + c] = dist[rs][cs][r][c];\n                            }\n                        }\n                    }\n\n                    for (int idx = 2; idx <= L; ++idx) {\n                        for (int curr = 0; curr < N * N; ++curr) {\n                            int r = curr / N, c = curr % N;\n                            if (A[r][c] == suffix[idx - 1]) {\n                                for (int prev = 0; prev < N * N; ++prev) {\n                                    if (dp[idx - 1][prev] != INF) {\n                                        int pr = prev / N, pc = prev % N;\n                                        int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                        if (d < dp[idx][curr]) dp[idx][curr] = (unsigned short)d;\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    for (int re = 0; re < N; ++re) {\n                        for (int ce = 0; ce < N; ++ce) {\n                            if (L == 0) pre[k][p][rs * N + cs][re * N + ce] = 0;\n                            else pre[k][p][rs * N + cs][re * N + ce] = dp[L][re * N + ce];\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nstruct EvalResult {\n    long long score;\n    int total_cost;\n    int covered_count;\n    vector<pair<int, int>> sequence;\n};\n\nint get_overlap(const string& S, const string& target) {\n    int max_ov = 0;\n    int len_s = S.length();\n    int len_t = target.length();\n    for (int len = 1; len <= min(4, min(len_s, len_t - 1)); ++len) {\n        if (S.substr(len_s - len) == target.substr(0, len)) {\n            max_ov = len;\n        }\n    }\n    // The problem says overlap is suffix of S and prefix of target.\n    // Since target length is 5, the prefix can be up to 4 chars.\n    // But a 5-char overlap means the target is already a substring.\n    // However, the problem states the target string is length 5.\n    // A 5-char overlap would only happen if target is exactly S.suffix(5).\n    // Let's check len=4, 3, 2, 1.\n    return max_ov;\n}\n\n// More robust overlap\nint get_overlap_robust(const string& S, const string& target) {\n    int max_ov = 0;\n    int s_len = S.length();\n    int t_len = target.length();\n    for (int len = 1; len <= 4; ++len) {\n        if (len <= s_len && len < t_len) {\n            if (S.substr(s_len - len) == target.substr(0, len)) {\n                max_ov = len;\n            }\n        }\n    }\n    return max_ov;\n}\n\nEvalResult evaluate(const vector<int>& order) {\n    string S = \"\";\n    int curr_r = si, curr_c = sj;\n    int cost = 0;\n    int covered_count = 0;\n    vector<bool> covered(M, false);\n    vector<pair<int, int>> sequence;\n\n    for (int k : order) {\n        if (covered[k]) continue;\n\n        int p = get_overlap_robust(S, t[k]);\n        string suffix = t[k].substr(p);\n        \n        int best_cost = 30000;\n        int best_r = -1, best_c = -1;\n        \n        int rs_idx = curr_r * N + curr_c;\n        for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n            if (pre[k][p][rs_idx][re_idx] < best_cost) {\n                best_cost = pre[k][p][rs_idx][re_idx];\n                best_r = re_idx / N;\n                best_c = re_idx % N;\n            }\n        }\n\n        if (best_r == -1) continue;\n\n        cost += best_cost;\n        for (int i = 0; i < suffix.length(); ++i) {\n            // This is tricky: we need to find the exact path to add to S.\n            // But for SA, we only need the cost and end position.\n            // We'll reconstruct the string S in a simpler way for SA.\n        }\n        // To keep SA fast, we won't build the full S, just track its end.\n        // But we need to know which strings are covered. \n        // Let's just build S. It's not that slow.\n        // Actually, to find which strings are covered, we need the characters.\n        // Let's use a simplified approach for SA.\n        // Since we only need to know if t[j] is a substring, and strings have len 5:\n        // A new t[j] can only be formed if it overlaps with the current S and the added suffix.\n        // Let's just build the added string characters. \n        // We can precompute the path if needed, but let's see.\n        \n        // Wait, a better way: instead of building S, let's just build the *suffix*\n        // that we actually added.\n        \n        // For simplicity, we'll find the path using the DP.\n        // However, doing this in evaluate is too slow.\n        // Let's just track the last 4 characters of S.\n        \n        // Re-calculating S in evaluate:\n        // To make it fast, we need to know what characters were added.\n        // Instead of the full path, let's just track the last 4 chars of S.\n        // But that's not enough to check if a *new* t[j] is covered.\n        // A new t[j] could be covered if it's entirely within the new suffix, \n        // or if it overlaps with the old S.\n        \n        // Let's use a simpler SA: only track cost and covered_count.\n        // To find covered_count, we'll just assume every string is covered in order.\n        // That's not correct. Let's build S.\n        // To build S without full path, we can precompute the added characters.\n        // But the path can be different for different (rs, cs, re, ce).\n        // Let's just use the current get_min_cost_to_add to build the string.\n    }\n    return {0, 0, 0, {}};\n}\n\n// Due to the complexity of the evaluate function, let's use a simpler greedy\n// and then optimize it with SA. The key is a very efficient evaluate.\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    precompute();\n\n    // Since the SA with full string building is slow, let's use a greedy\n    // with a bit of randomness and several restarts.\n\n    auto solve = [&]() {\n        string S = \"\";\n        int curr_r = si, curr_c = sj;\n        int total_cost = 0;\n        vector<bool> covered(M, false);\n        int covered_count = 0;\n        vector<pair<int, int>> final_path;\n\n        while (covered_count < M && final_path.size() < 5000) {\n            int best_k = -1;\n            int best_p = -1;\n            int best_r = -1, best_c = -1;\n            int best_cost = 1e9;\n            double best_ratio = 1e18;\n\n            for (int k = 0; k < M; ++k) {\n                if (covered[k]) continue;\n                int p = get_overlap_robust(S, t[k]);\n                int rs_idx = curr_r * N + curr_c;\n                \n                // We need to find the (re, ce) that minimizes pre[k][p][rs_idx][re_idx]\n                // but also considers how many new strings are covered.\n                // For speed, let's just pick the one with minimum cost.\n                int min_c = 1e9;\n                int min_re = -1, min_ce = -1;\n                for (int re_idx = 0; re_idx < N * N; ++re_idx) {\n                    if (pre[k][p][rs_idx][re_idx] < min_c) {\n                        min_c = pre[k][p][rs_idx][re_idx];\n                        min_re = re_idx / N;\n                        min_ce = re_idx % N;\n                    }\n                }\n\n                if (min_re == -1) continue;\n\n                // To correctly calculate newly_covered, we need the actual added characters.\n                // Since we don't have the path in 'pre', we must reconstruct it.\n                // But we can only do this for the *best* k.\n                \n                // For now, let's use a simple ratio: min_c / (1.0 + epsilon)\n                double ratio = (double)min_c; \n                if (ratio < best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    best_p = p;\n                    best_r = min_re;\n                    best_c = min_ce;\n                    best_cost = min_c;\n                }\n            }\n\n            if (best_k == -1) break;\n\n            // Reconstruct path for best_k\n            string suffix = t[best_k].substr(best_p);\n            int L = suffix.length();\n            vector<pair<int, int>> path;\n            int tr = best_r, tc = best_c;\n            \n            // Use DP to find the path\n            vector<vector<int>> dp(L + 1, vector<int>(N * N, 1e9));\n            vector<vector<int>> parent(L + 1, vector<int>(N * N, -1));\n            \n            // Re-run the DP for the specific suffix and start pos\n            int rs_idx = curr_r * N + curr_c;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (A[r][c] == suffix[0]) {\n                        dp[1][r * N + c] = dist[curr_r][curr_c][r][c];\n                    }\n                }\n            }\n            for (int idx = 2; idx <= L; ++idx) {\n                for (int curr = 0; curr < N * N; ++curr) {\n                    int r = curr / N, c = curr % N;\n                    if (A[r][c] == suffix[idx - 1]) {\n                        for (int prev = 0; prev < N * N; ++prev) {\n                            if (dp[idx - 1][prev] != 1e9) {\n                                int pr = prev / N, pc = prev % N;\n                                int d = dp[idx - 1][prev] + dist[pr][pc][r][c];\n                                if (d < dp[idx][curr]) {\n                                    dp[idx][curr] = d;\n                                    parent[idx][curr] = prev;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int cur_idx = best_r * N + best_c;\n            for (int i = L; i >= 1; --i) {\n                path.push_back({cur_idx / N, cur_idx % N});\n                cur_idx = parent[i][cur_idx];\n            }\n            reverse(path.begin(), path.end());\n\n            string added_chars = \"\";\n            for (auto p_idx : path) added_chars += A[p_idx.first][p_idx.second];\n            \n            S += added_chars;\n            for (auto p_idx : path) final_path.push_back(p_idx);\n            total_cost += best_cost;\n            curr_r = best_r;\n            curr_c = best_c;\n\n            for (int i = 0; i < M; ++i) {\n                if (!covered[i] && S.find(t[i]) != string::npos) {\n                    covered[i] = true;\n                    covered_count++;\n                }\n            }\n        }\n\n        for (auto p_idx : final_path) cout << p_idx.first << \" \" << p_idx.second << \"\\n\";\n    };\n\n    solve();\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS:\n * The problem asks to identify all squares (i, j) with oil reserves v(i, j) > 0.\n * We have three operations:\n * 1. Drill: Costs 1, reveals exact v(i, j).\n * 2. Divine: Costs 1/sqrt(|S|), returns noisy sum of v(S).\n * 3. Guess: Costs 1, identifies all v(i, j) > 0.\n * \n * The operational limit is 2 * N^2. For N=20, this is 800.\n * \n * STRATEGY:\n * A direct and robust strategy is to drill every square in the N x N island.\n * Total drills: N^2.\n * Total guesses: 1.\n * Total operations: N^2 + 1, which is <= 2 * N^2 for N >= 1.\n * \n * This strategy is guaranteed to find all oil-containing squares because \n * drilling provides exact values.\n */\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n\n    // Read initial parameters: island size, number of fields, and error parameter\n    if (!(cin >> N >> M >> eps)) {\n        return 0;\n    }\n\n    // Read field shapes. These are not required for the N^2 drill strategy.\n    for (int m = 0; m < M; ++m) {\n        int d;\n        if (!(cin >> d)) break;\n        for (int i = 0; i < d; ++i) {\n            int r, c;\n            if (!(cin >> r >> c)) break;\n        }\n    }\n\n    // List to store all squares discovered to have oil\n    vector<pair<int, int>> oil_squares;\n\n    // Drill every square (i, j) from (0,0) to (N-1, N-1)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // Command to drill square (i, j)\n            // Using endl ensures the output is flushed to the judge\n            cout << \"q 1 \" << i << \" \" << j << endl;\n\n            int v;\n            // Read the exact revealed value v(i, j)\n            if (!(cin >> v)) {\n                return 0;\n            }\n\n            // If v(i, j) is greater than 0, square (i, j) is identified as having oil\n            if (v > 0) {\n                oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // After drilling all squares, we know the exact set of oil-containing squares.\n    // Output the final guess in the specified format.\n    cout << \"a \" << oil_squares.size();\n    for (const auto& sq : oil_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n\n    // Read the final response from the judge (1 if correct, 0 if not)\n    int response;\n    if (!(cin >> response)) {\n        return 0;\n    }\n\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * The goal is to minimize the total cost: 100 * area shortfall + partition change cost.\n * Partition change cost is proportional to the length of partition segments that change between days.\n * \n * Strategy:\n * 1. A robust strategy is to use either a single column of full-width rectangles or a \n *    two-column layout of rectangles.\n * 2. In a two-column layout, we pick a split index 'n1' and a width 'w'.\n *    - Column 1: Rectangles 0 to n1-1 with width 'w'.\n *    - Column 2: Rectangles n1 to N-1 with width 'W-w'.\n * 3. The vertical boundary at x=w is kept constant to incur zero partition cost.\n * 4. For each column, we use Dynamic Programming to find the optimal y-coordinates for \n *    the horizontal boundaries to maximize shared boundaries with the previous day,\n *    which minimizes the partition change cost.\n * 5. The error in previous attempts was a potential division by zero in the configuration\n *    search and some indexing issues.\n */\n\nint W, D, N;\nvector<vector<int>> a;\n\n// solve_dp computes the optimal y-coordinates for the boundaries in a single column.\nvoid solve_dp(int n, int width, const vector<int>& areas, const vector<int>& prev_y, vector<int>& res_y) {\n    res_y.assign(n + 1, 0);\n    res_y[0] = 0;\n    res_y[n] = W;\n    if (n <= 1) return;\n\n    vector<int> H(n);\n    for (int k = 0; k < n; ++k) H[k] = (areas[k] + width - 1) / width;\n\n    vector<int> PreH(n + 1, 0);\n    for (int k = 0; k < n; ++k) PreH[k + 1] = PreH[k] + H[k];\n\n    vector<int> SufH(n + 1, 0);\n    for (int k = n - 1; k >= 0; --k) SufH[k] = SufH[k + 1] + H[k];\n\n    vector<bool> is_in_S_prev(W + 1, false);\n    for (int k = 1; k < n; ++k) {\n        if (prev_y[k] >= 0 && prev_y[k] <= W)\n            is_in_S_prev[prev_y[k]] = true;\n    }\n\n    // dp[k][y] = max shared boundaries in {y_{d,1}, ..., y_{d,k}} with y_{d,k} = y.\n    // k ranges from 0 to n-1. Boundary 0 is always at y=0.\n    vector<vector<int>> dp(n, vector<int>(W + 1, -1000000000));\n    vector<vector<int>> parent(n, vector<int>(W + 1, -1));\n\n    dp[0][0] = 0;\n\n    for (int k = 1; k < n; ++k) {\n        // Prefix max optimization to make transitions O(1)\n        vector<int> pref_max(W + 1, -1000000000);\n        vector<int> pref_max_idx(W + 1, -1);\n        int cur_max = -1000000000;\n        int cur_idx = -1;\n        for (int i = 0; i <= W; ++i) {\n            if (dp[k - 1][i] > cur_max) {\n                cur_max = dp[k - 1][i];\n                cur_idx = i;\n            }\n            pref_max[i] = cur_max;\n            pref_max_idx[i] = cur_idx;\n        }\n\n        for (int y = PreH[k]; y <= W - SufH[k]; ++y) {\n            int max_y_prev = y - H[k - 1];\n            if (max_y_prev >= 0) {\n                int val = pref_max[max_y_prev];\n                if (val > -500000000) {\n                    dp[k][y] = val + (is_in_S_prev[y] ? 1 : 0);\n                    parent[k][y] = pref_max_idx[max_y_prev];\n                }\n            }\n        }\n    }\n\n    int best_y = -1, max_val = -1000000000;\n    for (int y = PreH[n - 1]; y <= W - SufH[n - 1]; ++y) {\n        if (dp[n - 1][y] > max_val) {\n            max_val = dp[n - 1][y];\n            best_y = y;\n        }\n    }\n\n    if (best_y != -1) {\n        res_y[n - 1] = best_y;\n        for (int k = n - 1; k >= 1; --k) {\n            res_y[k - 1] = parent[k][res_y[k]];\n        }\n    } else {\n        // Fallback if no valid y found\n        for (int k = 1; k < n; ++k) res_y[k] = PreH[k];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> W >> D >> N)) return 0;\n    a.assign(D, vector<int>(N));\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> a[i][j];\n        }\n    }\n\n    // Find best (n1, w) configuration\n    int best_n1 = N, best_w = W;\n    bool found = false;\n    for (int w = 1; w < W; ++w) {\n        for (int n1 = 1; n1 < N; ++n1) {\n            bool ok = true;\n            for (int d = 0; d < D; ++d) {\n                long long h1 = 0;\n                for (int k = 0; k < n1; ++k) h1 += (a[d][k] + w - 1) / w;\n                long long h2 = 0;\n                for (int k = n1; k < N; ++k) h2 += (a[d][k] + (W - w) - 1) / (W - w);\n                if (h1 > W || h2 > W) { ok = false; break; }\n            }\n            if (ok) {\n                best_n1 = n1;\n                best_w = w;\n                found = true;\n                goto configuration_found;\n            }\n        }\n    }\n    configuration_found:;\n\n    vector<vector<int>> col1_y(D), col2_y(D);\n\n    for (int d = 0; d < D; ++d) {\n        if (best_n1 == N || best_n1 == 0) {\n            vector<int> prev_y = (d == 0) ? vector<int>(N + 1, -1) : col1_y[d - 1];\n            solve_dp(N, W, a[d], prev_y, col1_y[d]);\n        } else {\n            // Column 1 (0 to n1-1)\n            vector<int> areas1;\n            for (int k = 0; k < best_n1; ++k) areas1.push_back(a[d][k]);\n            vector<int> prev_y1 = (d == 0) ? vector<int>(best_n1 + 1, -1) : col1_y[d - 1];\n            solve_dp(best_n1, best_w, areas1, prev_y1, col1_y[d]);\n\n            // Column 2 (n1 to N-1)\n            vector<int> areas2;\n            for (int k = best_n1; k < N; ++k) areas2.push_back(a[d][k]);\n            vector<int> prev_y2 = (d == 0) ? vector<int>(N - best_n1 + 1, -1) : col2_y[d - 1];\n            solve_dp(N - best_n1, W - best_w, areas2, prev_y2, col2_y[d]);\n        }\n    }\n\n    // Output results\n    for (int d = 0; d < D; ++d) {\n        if (best_n1 == N || best_n1 == 0) {\n            for (int k = 0; k < N; ++k) {\n                cout << col1_y[d][k] << \" \" << 0 << \" \" << col1_y[d][k + 1] << \" \" << W << \"\\n\";\n            }\n        } else {\n            // Column 1\n            for (int k = 0; k < best_n1; ++k) {\n                cout << col1_y[d][k] << \" \" << 0 << \" \" << col1_y[d][k + 1] << \" \" << best_w << \"\\n\";\n            }\n            // Column 2\n            for (int k = best_n1; k < N; ++k) {\n                cout << col2_y[d][k - best_n1] << \" \" << best_w << \" \" << col2_y[d][k - best_n1 + 1] << \" \" << W << \"\\n\";\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\nlong long a[N][N];\nlong long s[M][3][3];\nlong long b[N][N];\n\nstruct Operation {\n    int m, p, q;\n};\n\nOperation slots[K];\nbool occupied[K];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in, k_in;\n    if (!(cin >> n_in >> m_in >> k_in)) return 0;\n\n    // Input initial board\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    // Input stamps\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 >> s[m][i][j];\n\n    // Initialize board and current score\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            b[i][j] = a[i][j];\n\n    long long current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            current_score += b[i][j] % P;\n\n    mt19937_64 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n\n    long long best_score = current_score;\n    vector<Operation> best_ops;\n    for (int i = 0; i < K; ++i) occupied[i] = false;\n\n    // SA parameters\n    double T_start = 1e9;\n    double T_end = 1e-1;\n\n    // Pre-allocate buffers to speed up loop\n    bool is_aff[N][N];\n    pair<int, int> affected[18];\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.85) break; // Leave time for final output\n\n        double T = T_start * pow(T_end / T_start, elapsed / 1.85);\n\n        int i = rng() % K;\n\n        if (occupied[i]) {\n            // Decide between REMOVE or MODIFY\n            int move_type = rng() % 100;\n            if (move_type < 30) { // REMOVE move\n                int m = slots[i].m;\n                int p = slots[i].p;\n                int q = slots[i].q;\n\n                long long delta = 0;\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p + di, c = q + dj;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v - s[m][di][dj];\n                        delta += (new_v % P) - (old_v % P);\n                    }\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int r = p + di, c = q + dj;\n                            b[r][c] -= s[m][di][dj];\n                        }\n                    }\n                    occupied[i] = false;\n                    current_score += delta;\n                }\n            } else { // MODIFY move\n                int m_new = rng() % M;\n                int p_new = rng() % (N - 2);\n                int q_new = rng() % (N - 2);\n                int m_old = slots[i].m;\n                int p_old = slots[i].p;\n                int q_old = slots[i].q;\n\n                if (m_new == m_old && p_new == p_old && q_new == q_old) continue;\n\n                // Identify union of cells affected by old and new stamp\n                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) is_aff[r][c] = false;\n                int aff_cnt = 0;\n\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_old + di, c = q_old + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        if (!is_aff[r][c]) {\n                            is_aff[r][c] = true;\n                            affected[aff_cnt++] = {r, c};\n                        }\n                    }\n                }\n\n                long long delta = 0;\n                for (int k = 0; k < aff_cnt; ++k) {\n                    int r = affected[k].first, c = affected[k].second;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v;\n                    if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                        new_v -= s[m_old][r - p_old][c - q_old];\n                    if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                        new_v += s[m_new][r - p_new][c - q_new];\n                    delta += (new_v % P) - (old_v % P);\n                }\n\n                if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                    for (int k = 0; k < aff_cnt; ++k) {\n                        int r = affected[k].first, c = affected[k].second;\n                        long long old_v = b[r][c];\n                        long long new_v = old_v;\n                        if (r >= p_old && r < p_old + 3 && c >= q_old && c < q_old + 3)\n                            new_v -= s[m_old][r - p_old][c - q_old];\n                        if (r >= p_new && r < p_new + 3 && c >= q_new && c < q_new + 3)\n                            new_v += s[m_new][r - p_new][c - q_new];\n                        b[r][c] = new_v;\n                    }\n                    slots[i] = {m_new, p_new, q_new};\n                    current_score += delta;\n                }\n            }\n        } else { // ADD move\n            int m_new = rng() % M;\n            int p_new = rng() % (N - 2);\n            int q_new = rng() % (N - 2);\n\n            long long delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int r = p_new + di, c = q_new + dj;\n                    long long old_v = b[r][c];\n                    long long new_v = old_v + s[m_new][di][dj];\n                    delta += (new_v % P) - (old_v % P);\n                }\n            }\n\n            if (delta > 0 || (T > 1e-9 && exp((double)delta / T) > (double)rng() / rng.max())) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int r = p_new + di, c = q_new + dj;\n                        b[r][c] += s[m_new][di][dj];\n                    }\n                }\n                slots[i] = {m_new, p_new, q_new};\n                occupied[i] = true;\n                current_score += delta;\n            }\n        }\n\n        // Update best known solution\n        if (current_score > best_score) {\n            best_score = current_score;\n            best_ops.clear();\n            for (int k = 0; k < K; ++k) {\n                if (occupied[k]) best_ops.push_back(slots[k]);\n            }\n        }\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n/*\nProblem Analysis:\n- The goal is to dispatch N^2 = 25 containers from specific Dispatch Gates.\n- Containers must be dispatched in a specific order: 0, 1, ..., 24.\n- The scoring favors minimizing the total turns (M0), the number of inversions (M1),\n  wrong dispatch gates (M2), and undispatched containers (M3).\n- To minimize M1, M2, and M3, the most important thing is to dispatch containers\n  in the correct order 0, 1, ..., 24 at their respective correct gates (c/N, N-1).\n- We use a single large crane (crane 0) to pick up each container one by one in \n  increasing order.\n- All other cranes are immediately bombed to ensure they don't block the path.\n- The large crane is capable of moving through squares with other containers.\n- BFS is used to find the shortest path for the large crane between target locations.\n*/\n\nint N;\nint A[5][5];\nint grid[5][5];\nint arrival_idx[5];\nint crane_x[5], crane_y[5];\nint crane_holding[5];\nbool container_on_grid[25];\nint container_pos_x[25], container_pos_y[25];\nbool container_dispatched[25];\nint target_c = 0;\n\n// Returns the direction char to move from (sx, sy) to (nx, ny)\nchar get_move_char(int sx, int sy, int nx, int ny) {\n    if (nx < sx) return 'U';\n    if (nx > sx) return 'D';\n    if (ny < sy) return 'L';\n    if (ny > sy) return 'R';\n    return '.';\n}\n\n// BFS to find the next step towards (tx, ty) on a 5x5 grid\npair<int, int> get_next_step(int sx, int sy, int tx, int ty) {\n    if (sx == tx && sy == ty) return {sx, sy};\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    queue<pair<int, int>> q;\n    q.push({sx, sy});\n    int dist[5][5];\n    pair<int, int> parent[5][5];\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    dist[sx][sy] = 0;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        if (curr.first == tx && curr.second == ty) break;\n\n        for (int i = 0; i < 4; ++i) {\n            int nx = curr.first + dx[i];\n            int ny = curr.second + dy[i];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                parent[nx][ny] = curr;\n                q.push({nx, ny});\n            }\n        }\n    }\n\n    if (dist[tx][ty] == -1) return {sx, sy};\n\n    // Backtrack to find the first step along the path from (sx, sy)\n    int cx = tx, cy = ty;\n    while (parent[cx][cy].first != sx || parent[cx][cy].second != sy) {\n        pair<int, int> p = parent[cx][cy];\n        cx = p.first;\n        cy = p.second;\n    }\n    return {cx, cy};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n            grid[i][j] = -1;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        arrival_idx[i] = 0;\n        crane_x[i] = i;\n        crane_y[i] = 0;\n        crane_holding[i] = -1;\n    }\n    crane_x[0] = 0;\n    crane_y[0] = 0;\n    for (int i = 0; i < 25; ++i) {\n        container_on_grid[i] = false;\n        container_dispatched[i] = false;\n    }\n\n    // Pre-allocate strings for outputs\n    vector<string> actions(N, string(10000, '.'));\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // 1. Arrivals (Step 1)\n        for (int i = 0; i < N; ++i) {\n            bool crane_holding_at_gate = false;\n            for (int k = 0; k < N; ++k) {\n                if (crane_holding[k] != -1 && crane_x[k] == i && crane_y[k] == 0) {\n                    crane_holding_at_gate = true;\n                    break;\n                }\n            }\n            if (arrival_idx[i] < N && grid[i][0] == -1 && !crane_holding_at_gate) {\n                int c = A[i][arrival_idx[i]];\n                grid[i][0] = c;\n                container_on_grid[c] = true;\n                container_pos_x[c] = i;\n                container_pos_y[c] = 0;\n                arrival_idx[i]++;\n            }\n        }\n\n        // 2. Crane Actions (Step 2)\n        // First turn: Bomb all small cranes to clear paths\n        if (turn == 1) {\n            for (int i = 1; i < N; ++i) {\n                actions[i][0] = 'B';\n                // Small cranes are effectively removed from the simulation now\n            }\n        }\n\n        // Decision for the large crane (crane 0)\n        if (crane_holding[0] == -1) {\n            if (target_c < 25) {\n                // Check if target container is on the grid\n                if (container_on_grid[target_c]) {\n                    int rx = container_pos_x[target_c];\n                    int ry = container_pos_y[target_c];\n                    if (crane_x[0] == rx && crane_y[0] == ry) {\n                        // If at the container, pick it up\n                        actions[0][turn - 1] = 'P';\n                        crane_holding[0] = target_c;\n                        grid[rx][ry] = -1;\n                        container_on_grid[target_c] = false;\n                    } else {\n                        // Otherwise, move towards it\n                        pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                        actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                        crane_x[0] = next_pos.first;\n                        crane_y[0] = next_pos.second;\n                    }\n                } else {\n                    // Target container hasn't arrived yet\n                    actions[0][turn - 1] = '.';\n                }\n            } else {\n                actions[0][turn - 1] = '.';\n            }\n        } else {\n            // Large crane is holding a container\n            int c = crane_holding[0];\n            int rx = c / N, ry = N - 1;\n            if (crane_x[0] == rx && crane_y[0] == ry) {\n                // If at target dispatch gate, release it\n                actions[0][turn - 1] = 'Q';\n                grid[rx][ry] = c;\n                crane_holding[0] = -1;\n                target_c++;\n            } else {\n                // Move towards the dispatch gate\n                pair<int, int> next_pos = get_next_step(crane_x[0], crane_y[0], rx, ry);\n                actions[0][turn - 1] = get_move_char(crane_x[0], crane_y[0], next_pos.first, next_pos.second);\n                crane_x[0] = next_pos.first;\n                crane_y[0] = next_pos.second;\n            }\n        }\n\n        // 3. Dispatches (Step 3)\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][N - 1] != -1) {\n                int c = grid[i][N - 1];\n                grid[i][N - 1] = -1;\n                container_on_grid[c] = false;\n                container_dispatched[c] = true;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - The goal is to level the ground by making all h[i][j] = 0.\n * - Costs: \n *   - Loading/unloading d units of soil: d.\n *   - Moving to an adjacent square: 100 + current_load.\n * - The sum of all heights h[i][j] is 0.\n * - Total operations T must be <= 100,000.\n * \n * Strategy:\n * - We use a greedy \"nearest target\" approach.\n * - At each step:\n *   1. If the current square has soil to load (h[i][j] > 0), load all of it.\n *   2. If the current square needs soil and we have soil (h[i][j] < 0 and cur_load > 0), unload as much as possible.\n *   3. If neither is possible (the square is empty or we are at a source but have no soil to unload, etc.), \n *      find the nearest useful target.\n *      - A target is useful if it's a source (h[i][j] > 0) or a sink (h[i][j] < 0).\n *      - If the truck is empty (cur_load == 0), we only look for the nearest source.\n *      - If the truck has soil (cur_load > 0), we look for the nearest source or sink.\n *   4. Move to the chosen target.\n * - This ensures that we always make progress towards zeroing out the heights.\n * - The output format requires us to list only the operations, not the number of operations T.\n * - The error \"Invalid action: 832\" from previous attempts was due to outputting T first.\n * \n * Time and Space complexity:\n * - The number of operations is roughly O(N^2 * N), which is about 20^3 = 8,000. \n *   Even with movement, it's well within the 100,000 turn limit.\n * - Time complexity per iteration is O(N^2) to find the nearest target.\n * - Overall complexity: O(T * N^2), where T is the number of operations.\n * - With N=20 and T=100,000, this is ~40,000,000 operations, which fits in 2 seconds.\n */\n\nint N;\nint h[20][20];\nint cur_r = 0, cur_c = 0, cur_load = 0;\n\n// Calculate Manhattan distance between two squares\nint get_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    if (!(cin >> N)) return 0;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n        }\n    }\n\n    vector<string> ops;\n\n    // Main loop: continue until all squares are 0 and truck is empty\n    while (ops.size() < 100000) {\n        // 1. Perform loading/unloading at current square if possible\n        if (h[cur_r][cur_c] > 0) {\n            // Load all available soil from current square\n            int d = h[cur_r][cur_c];\n            h[cur_r][cur_c] = 0;\n            cur_load += d;\n            ops.push_back(\"+\" + to_string(d));\n            continue;\n        }\n        if (h[cur_r][cur_c] < 0 && cur_load > 0) {\n            // Unload soil to current sink\n            int d = min(cur_load, -h[cur_r][cur_c]);\n            h[cur_r][cur_c] += d;\n            cur_load -= d;\n            ops.push_back(\"-\" + to_string(d));\n            continue;\n        }\n\n        // 2. Find the nearest target to move to\n        int target_r = -1, target_c = -1;\n        int min_dist = 1000000;\n\n        // If truck is empty, we look for the nearest source (h > 0)\n        if (cur_load == 0) {\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] > 0) {\n                        int d = get_dist(cur_r, cur_c, i, j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            target_r = i;\n                            target_c = j;\n                        }\n                    }\n                }\n            }\n        } else {\n            // If truck has soil, we can go to either a source (to pick up more) or a sink (to unload)\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] > 0 || h[i][j] < 0) {\n                        int d = get_dist(cur_r, cur_c, i, j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            target_r = i;\n                            target_c = j;\n                        }\n                    }\n                }\n            }\n        }\n\n        // If no target is found, all soil is leveled\n        if (target_r == -1) break;\n\n        // 3. Move the dump truck step-by-step to the target square\n        while (cur_r < target_r) { ops.push_back(\"D\"); cur_r++; }\n        while (cur_r > target_r) { ops.push_back(\"U\"); cur_r--; }\n        while (cur_c < target_c) { ops.push_back(\"R\"); cur_c++; }\n        while (cur_c > target_c) { ops.push_back(\"L\"); cur_c--; }\n    }\n\n    // Output the final sequence of operations (no T prefix)\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Final Strategy:\n * 1. SA with Geometric Cooling on a hybrid selection + placement problem.\n * 2. Objective function: max_v + 0.001 * sum_v.\n * 3. Greedy refinement after SA to improve the single best seed.\n * 4. Efficient score calculation by scanning all 60 pairs.\n */\n\nconst int MAX_N = 6;\nconst int MAX_M = 15;\nconst int MAX_SEEDS = 60;\nconst int MAX_PAIRS = 60;\n\nint N, M, T;\nint seed_count;\nint grid_size;\n\nstruct Seed {\n    int x[MAX_M];\n    int v;\n};\n\nSeed seeds[MAX_SEEDS];\nint grid[MAX_N][MAX_N];\nint pos[MAX_SEEDS]; \n\nstruct Pair {\n    int r1, c1, r2, c2;\n};\nPair adj_pairs[MAX_PAIRS];\nint cell_to_pairs[MAX_N][MAX_N][4];\nint cell_to_pairs_size[MAX_N][MAX_N];\ndouble pair_scores[MAX_PAIRS];\n\ninline double calculate_pair_vmax(int k1, int k2) {\n    double vmax = 0;\n    const int* x1 = seeds[k1].x;\n    const int* x2 = seeds[k2].x;\n    for (int l = 0; l < M; ++l) {\n        vmax += (x1[l] > x2[l] ? x1[l] : x2[l]);\n    }\n    return vmax;\n}\n\nstruct Score {\n    double max_v;\n    double sum_v;\n    double total() const { return max_v + 0.001 * sum_v; }\n};\n\nint pair_idx_global;\n\ninline Score calculate_score() {\n    double max_v = 0;\n    double sum_v = 0;\n    for (int i = 0; i < pair_idx_global; ++i) {\n        if (pair_scores[i] > max_v) max_v = pair_scores[i];\n        sum_v += pair_scores[i];\n    }\n    return {max_v, sum_v};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> T)) return 0;\n\n    seed_count = 2 * N * (N - 1);\n    grid_size = N * N;\n\n    for (int i = 0; i < seed_count; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> seeds[i].x[j];\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    int pair_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cell_to_pairs_size[i][j] = 0;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            adj_pairs[pair_idx] = {i, j, i, j + 1};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i][j + 1][cell_to_pairs_size[i][j + 1]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            adj_pairs[pair_idx] = {i, j, i + 1, j};\n            cell_to_pairs[i][j][cell_to_pairs_size[i][j]++] = pair_idx;\n            cell_to_pairs[i + 1][j][cell_to_pairs_size[i + 1][j]++] = pair_idx;\n            pair_idx++;\n        }\n    }\n    pair_idx_global = pair_idx;\n\n    mt19937 rng(1337);\n\n    for (int t = 0; t < T; ++t) {\n        for (int i = 0; i < seed_count; ++i) pos[i] = -1;\n        for (int i = 0; i < grid_size; ++i) {\n            grid[i / N][i % N] = i;\n            pos[i] = i;\n        }\n\n        for (int i = 0; i < pair_idx; ++i) {\n            pair_scores[i] = calculate_pair_vmax(grid[adj_pairs[i].r1][adj_pairs[i].c1], grid[adj_pairs[i].r2][adj_pairs[i].c2]);\n        }\n\n        Score current_score = calculate_score();\n        auto start_time = chrono::steady_clock::now();\n        const double time_limit = 0.175;\n        const double initial_temp = 5.0;\n        const double final_temp = 0.01;\n\n        int iter = 0;\n        while (true) {\n            if ((iter & 255) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - start_time).count();\n                if (elapsed > time_limit) break;\n            }\n            iter++;\n\n            int r = uniform_int_distribution<int>(0, N - 1)(rng);\n            int c = uniform_int_distribution<int>(0, N - 1)(rng);\n            int s = uniform_int_distribution<int>(0, seed_count - 1)(rng);\n\n            int r2 = -1, c2 = -1;\n            if (pos[s] != -1) {\n                r2 = pos[s] / N; c2 = pos[s] % N;\n            }\n\n            if (r == r2 && c == c2) continue;\n\n            int old_seed_rc = grid[r][c];\n            int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n\n            int changed_pairs[10];\n            double old_pair_scores[10];\n            int cp_cnt = 0;\n\n            auto record_affected_pairs = [&](int row, int col) {\n                for (int i = 0; i < cell_to_pairs_size[row][col]; ++i) {\n                    int p_idx = cell_to_pairs[row][col][i];\n                    bool already_recorded = false;\n                    for (int k = 0; k < cp_cnt; ++k) {\n                        if (changed_pairs[k] == p_idx) {\n                            already_recorded = true;\n                            break;\n                        }\n                    }\n                    if (!already_recorded) {\n                        changed_pairs[cp_cnt] = p_idx;\n                        old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                        cp_cnt++;\n                    }\n                }\n            };\n\n            record_affected_pairs(r, c);\n            if (r2 != -1) record_affected_pairs(r2, c2);\n\n            if (r2 != -1) {\n                grid[r][c] = s; grid[r2][c2] = old_seed_rc;\n                pos[s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n            } else {\n                grid[r][c] = s; pos[old_seed_rc] = -1; pos[s] = r * N + c;\n            }\n\n            for (int i = 0; i < cp_cnt; ++i) {\n                int p_idx = changed_pairs[i];\n                pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n            }\n\n            Score next_score = calculate_score();\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double temp = initial_temp * pow(final_temp / initial_temp, elapsed / time_limit);\n\n            if (next_score.total() > current_score.total() || exp((next_score.total() - current_score.total()) / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_score = next_score;\n            } else {\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc; grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2; pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc; pos[s] = -1; pos[old_seed_rc] = r * N + c;\n                }\n                for (int i = 0; i < cp_cnt; ++i) pair_scores[changed_pairs[i]] = old_pair_scores[i];\n            }\n        }\n\n        // Greedy Refinement\n        for (int i = 0; i < grid_size; ++i) {\n            int r = i / N, c = i % N;\n            int original_seed = grid[r][c];\n            int best_s = original_seed;\n            Score best_score = current_score;\n\n            for (int s = 0; s < seed_count; ++s) {\n                if (s == original_seed) continue;\n\n                int r2 = -1, c2 = -1;\n                if (pos[s] != -1) { r2 = pos[s] / N; c2 = pos[s] % N; }\n\n                int old_seed_rc = grid[r][c];\n                int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n                int changed_pairs[10];\n                double old_pair_scores[10];\n                int cp_cnt = 0;\n\n                auto record_affected_pairs_greedy = [&](int row, int col) {\n                    for (int k = 0; k < cell_to_pairs_size[row][col]; ++k) {\n                        int p_idx = cell_to_pairs[row][col][k];\n                        bool already_recorded = false;\n                        for (int m = 0; m < cp_cnt; ++m) {\n                            if (changed_pairs[m] == p_idx) { already_recorded = true; break; }\n                        }\n                        if (!already_recorded) {\n                            changed_pairs[cp_cnt] = p_idx;\n                            old_pair_scores[cp_cnt] = pair_scores[p_idx];\n                            cp_cnt++;\n                        }\n                    }\n                };\n\n                record_affected_pairs_greedy(r, c);\n                if (r2 != -1) record_affected_pairs_greedy(r2, c2);\n\n                if (r2 != -1) {\n                    grid[r][c] = s; grid[r2][c2] = old_seed_rc;\n                    pos[s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n                } else {\n                    grid[r][c] = s; pos[old_seed_rc] = -1; pos[s] = r * N + c;\n                }\n\n                for (int k = 0; k < cp_cnt; ++k) {\n                    int p_idx = changed_pairs[k];\n                    pair_scores[p_idx] = calculate_pair_vmax(grid[adj_pairs[p_idx].r1][adj_pairs[p_idx].c1], grid[adj_pairs[p_idx].r2][adj_pairs[p_idx].c2]);\n                }\n\n                Score next_score = calculate_score();\n                if (next_score.total() > best_score.total()) {\n                    best_score = next_score;\n                    best_s = s;\n                }\n\n                if (r2 != -1) {\n                    grid[r][c] = old_seed_rc; grid[r2][c2] = old_seed_r2c2;\n                    pos[s] = r2 * N + c2; pos[old_seed_rc] = r * N + c;\n                } else {\n                    grid[r][c] = old_seed_rc; pos[s] = -1; pos[old_seed_rc] = r * N + c;\n                }\n                for (int k = 0; k < cp_cnt; ++k) pair_scores[changed_pairs[k]] = old_pair_scores[k];\n            }\n\n            if (best_s != original_seed) {\n                int r2 = -1, c2 = -1;\n                if (pos[best_s] != -1) { r2 = pos[best_s] / N; c2 = pos[best_s] % N; }\n                int old_seed_rc = grid[r][c];\n                int old_seed_r2c2 = (r2 != -1) ? grid[r2][c2] : -1;\n                if (r2 != -1) {\n                    grid[r][c] = best_s; grid[r2][c2] = old_seed_rc;\n                    pos[best_s] = r * N + c; pos[old_seed_rc] = r2 * N + c2;\n                } else {\n                    grid[r][c] = best_s; pos[old_seed_rc] = -1; pos[best_s] = r * N + c;\n                }\n                for (int k = 0; k < pair_idx; ++k) {\n                    pair_scores[k] = calculate_pair_vmax(grid[adj_pairs[k].r1][adj_pairs[k].c1], grid[adj_pairs[k].r2][adj_pairs[k].c2]);\n                }\n                current_score = calculate_score();\n            }\n        }\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        for (int i = 0; i < seed_count; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                cin >> seeds[i].x[j];\n                seeds[i].v += seeds[i].x[j];\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// State of the robotic arm\nstruct State {\n    int rx, ry, dir_idx;\n};\n\nint N, M, V;\nvector<string> s_grid, t_grid;\nint curr_rx, curr_ry, curr_dir_idx;\n\n// Directions: 0: Down (1,0), 1: Right (0,1), 2: Up (-1,0), 3: Left (0,-1)\nint dx[] = {1, 0, -1, 0};\nint dy[] = {0, 1, 0, -1};\n\n// Calculate the minimum turns required to move from one state to another\nint dist(State s1, State s2) {\n    int D = abs(s1.rx - s2.rx) + abs(s1.ry - s2.ry);\n    int rot_ccw = (s2.dir_idx - s1.dir_idx + 4) % 4;\n    int rot_cw = (s1.dir_idx - s2.dir_idx + 4) % 4;\n    int R = min(rot_ccw, rot_cw);\n    return max(D, R);\n}\n\n// Find the root position and direction required to place the fingertip at (sx, sy)\nState find_state(int sx, int sy) {\n    for (int d = 0; d < 4; ++d) {\n        int rx = sx - dx[d];\n        int ry = sy - dy[d];\n        if (rx >= 0 && rx < N && ry >= 0 && ry < N) {\n            return {rx, ry, d};\n        }\n    }\n    return {0, 0, 0};\n}\n\n// Execute moves, rotations, and actions to reach a target state\nvoid move_to(State target, bool is_action) {\n    int dr = abs(target.rx - curr_rx);\n    int dc = abs(target.ry - curr_ry);\n    int D = dr + dc;\n    \n    int rot_ccw = (target.dir_idx - curr_dir_idx + 4) % 4;\n    int rot_cw = (curr_dir_idx - target.dir_idx + 4) % 4;\n    \n    int R, rot_char;\n    if (rot_ccw <= rot_cw) {\n        R = rot_ccw;\n        rot_char = 'L';\n    } else {\n        R = rot_cw;\n        rot_char = 'R';\n    }\n    \n    int turns = max(D, R);\n    // If the target is already reached but we need to perform an action (grab/release), take one turn.\n    if (is_action && turns == 0) turns = 1;\n\n    for (int i = 0; i < turns; ++i) {\n        char move_char = '.';\n        if (curr_rx < target.rx) { move_char = 'D'; curr_rx++; }\n        else if (curr_rx > target.rx) { move_char = 'U'; curr_rx--; }\n        else if (curr_ry < target.ry) { move_char = 'R'; curr_ry++; }\n        else if (curr_ry > target.ry) { move_char = 'L'; curr_ry--; }\n\n        char cur_rot_char = '.';\n        if (R > 0) {\n            cur_rot_char = rot_char;\n            if (rot_char == 'L') curr_dir_idx = (curr_dir_idx + 1) % 4;\n            else curr_dir_idx = (curr_dir_idx + 3) % 4;\n            R--;\n        }\n\n        char action_char = (is_action && i == turns - 1) ? 'P' : '.';\n        // Output turn format: Move(1) + Rotation(1) + RootAction(1) + LeafAction(1)\n        // For V=2, root is vertex 0, leaf is vertex 1.\n        cout << move_char << cur_rot_char << '.' << action_char << \"\\n\";\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    s_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    t_grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Design: 2 vertices (root 0 and fingertip 1), edge length 1.\n    cout << 2 << \"\\n\";\n    cout << \"0 1\" << \"\\n\";\n    cout << \"0 0\" << \"\\n\";\n\n    curr_rx = 0;\n    curr_ry = 0;\n    curr_dir_idx = 1; // Initial direction is Right\n\n    vector<pair<int, int>> s_only, t_only;\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') s_only.push_back({i, j});\n            if (s_grid[i][j] == '0' && t_grid[i][j] == '1') t_only.push_back({i, j});\n        }\n    }\n\n    // Greedy matching: Always pick the (takoyaki, target) pair that minimizes travel distance.\n    while (!s_only.empty()) {\n        int best_si = -1, best_tj = -1;\n        int min_dist = 1e9;\n        State curr_state = {curr_rx, curr_ry, curr_dir_idx};\n        \n        for (int i = 0; i < (int)s_only.size(); ++i) {\n            State si_state = find_state(s_only[i].first, s_only[i].second);\n            int d_to_si = dist(curr_state, si_state);\n            for (int j = 0; j < (int)t_only.size(); ++j) {\n                State tj_state = find_state(t_only[j].first, t_only[j].second);\n                int d_si_to_tj = dist(si_state, tj_state);\n                if (d_to_si + d_si_to_tj < min_dist) {\n                    min_dist = d_to_si + d_si_to_tj;\n                    best_si = i;\n                    best_tj = j;\n                }\n            }\n        }\n\n        if (best_si != -1) {\n            // 1. Move to pick up takoyaki\n            State pick_state = find_state(s_only[best_si].first, s_only[best_si].second);\n            move_to(pick_state, true);\n            // 2. Move to drop off takoyaki\n            State drop_state = find_state(t_only[best_tj].first, t_only[best_tj].second);\n            move_to(drop_state, true);\n\n            // Remove the used takoyaki and target position\n            s_only.erase(s_only.begin() + best_si);\n            t_only.erase(t_only.begin() + best_tj);\n        } else {\n            break;\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We are given N mackerels (weight +1) and N sardines (weight -1).\n * We need to find an axis-parallel polygon that maximizes the sum of weights of fish inside it.\n * The polygon must have at most 1000 vertices, edge length at most 4*10^5, \n * and coordinates between 0 and 10^5. It must not self-intersect.\n * \n * The maximum weight rectangle problem can be solved in O(N^2) by iterating \n * through all pairs of y-coordinates and using Kadane's algorithm on x-coordinates.\n * With N = 5000, O(N^2) is approximately 2.5 * 10^7, which fits within the 2-second limit.\n * Specifically, if we collect unique x and y coordinates, the complexity becomes O(L^2 + LN),\n * where L is the number of unique y-coordinates and N is the total number of fish.\n */\n\nstruct Fish {\n    int x, y, weight;\n};\n\nint main() {\n    // Speed up I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<Fish> all_fish;\n    vector<int> all_x, all_y;\n\n    // Read mackerels\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, 1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n    // Read sardines\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        all_fish.push_back({x, y, -1});\n        all_x.push_back(x);\n        all_y.push_back(y);\n    }\n\n    // Pre-process unique coordinates for compression\n    sort(all_x.begin(), all_x.end());\n    all_x.erase(unique(all_x.begin(), all_x.end()), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    all_y.erase(unique(all_y.begin(), all_y.end()), all_y.end());\n\n    int K = all_x.size();\n    int L = all_y.size();\n\n    // Group fish by their unique y-coordinate index\n    vector<vector<pair<int, int>>> fish_at_y(L);\n    for (const auto& f : all_fish) {\n        int xi = lower_bound(all_x.begin(), all_x.end(), f.x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), f.y) - all_y.begin();\n        fish_at_y[yi].push_back({xi, f.weight});\n    }\n\n    // Initialize with a single mackerel to ensure a minimum score of 2 (a-b+1 = 1-0+1 = 2)\n    // (assuming mackerels are the first N fish)\n    int best_sum = 0;\n    int bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n\n    // A single mackerel at index i (0 <= i < N) provides sum 1\n    for (int i = 0; i < N; ++i) {\n        // Since all_fish[0...N-1] are mackerels\n        int xi = lower_bound(all_x.begin(), all_x.end(), all_fish[i].x) - all_x.begin();\n        int yi = lower_bound(all_y.begin(), all_y.end(), all_fish[i].y) - all_y.begin();\n        if (1 > best_sum) {\n            best_sum = 1;\n            bx1 = xi; bx2 = xi;\n            by1 = yi; by2 = yi;\n        }\n    }\n\n    // O(L^2 + LN) algorithm to find the maximum weight rectangle\n    vector<int> f(K, 0);\n    for (int i = 0; i < L; ++i) {\n        // Reset x-coordinate weights for the new starting y-coordinate\n        fill(f.begin(), f.end(), 0);\n        for (int j = i; j < L; ++j) {\n            // Add fish at current y-coordinate j to the weights\n            for (auto& p : fish_at_y[j]) {\n                f[p.first] += p.second;\n            }\n            \n            // Find maximum subarray sum of weights in f using Kadane's\n            int cur_sum = 0;\n            int start = 0;\n            for (int k = 0; k < K; ++k) {\n                cur_sum += f[k];\n                if (cur_sum > best_sum) {\n                    best_sum = cur_sum;\n                    bx1 = start; bx2 = k;\n                    by1 = i; by2 = j;\n                }\n                if (cur_sum < 0) {\n                    cur_sum = 0;\n                    start = k + 1;\n                }\n            }\n        }\n    }\n\n    // Convert the discrete indices back to actual coordinates\n    int x1 = all_x[bx1], x2 = all_x[bx2];\n    int y1 = all_y[by1], y2 = all_y[by2];\n\n    // Ensure we form a valid non-zero area polygon\n    if (x1 == x2) {\n        if (x1 < 100000) x2 = x1 + 1;\n        else { x1 = x1 - 1; x2 = x1 + 1; }\n    }\n    if (y1 == y2) {\n        if (y1 < 100000) y2 = y1 + 1;\n        else { y1 = y1 - 1; y2 = y1 + 1; }\n    }\n\n    // Output the 4 vertices of the rectangle\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << endl;\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Rectangular packing in a single cardboard box.\n * Goal: Minimize W + H + Sum(unused rectangles' dimensions).\n * Method: Randomized Greedy approach with time-limited iterations.\n * \n * Rules:\n * - Rectangles must be placed in increasing order of indices.\n * - Each can be rotated 90 degrees.\n * - Directions: U (upward, move towards y=0) or L (leftward, move towards x=0).\n * - U with reference b: x_left_new = x_right_b (or 0).\n * - L with reference b: y_top_new = y_bottom_b (or 0).\n * - Movement stops when it hits an edge of a previously placed rectangle or axis.\n */\n\nstruct Rect {\n    int id;\n    long long w, h;\n    long long x, y;\n    long long x_right, y_bottom;\n};\n\nstruct Placement {\n    int p, r, d, b; \n};\n\nstruct State {\n    vector<Rect> placed;\n    vector<Placement> placements;\n    long long W, H;\n    long long score;\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<pair<long long, long long>> measured_wh(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> measured_wh[i].first >> measured_wh[i].second;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; ++t) {\n        // Time management to avoid TLE in system tests\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 2.7) break;\n\n        State best_state;\n        best_state.score = 4e18; \n\n        // Perform randomized greedy iterations in batches\n        for (int batch = 0; batch < 100; ++batch) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) break;\n\n            for (int iter = 0; iter < 5; ++iter) {\n                State current_state;\n                current_state.W = 0;\n                current_state.H = 0;\n                long long unused_sum = 0;\n                for (int i = 0; i < N; ++i) unused_sum += (measured_wh[i].first + measured_wh[i].second);\n\n                for (int i = 0; i < N; ++i) {\n                    long long wi = measured_wh[i].first;\n                    long long hi = measured_wh[i].second;\n\n                    struct Option {\n                        int r, d, b;\n                        long long new_W, new_H;\n                    };\n                    static Option options[405];\n                    int opt_count = 0;\n                    long long best_new_W_H = 4e18;\n\n                    for (int r : {0, 1}) {\n                        long long w = (r == 0 ? wi : hi);\n                        long long h = (r == 0 ? hi : wi);\n                        \n                        for (int d : {0, 1}) { // 0 for U, 1 for L\n                            // Try Case 1: Reference rectangle b = -1\n                            long long x_l, x_r, y_t, y_b;\n                            if (d == 0) { // U\n                                x_l = 0; x_r = w; y_t = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                }\n                                y_b = y_t + h;\n                            } else { // L\n                                y_t = 0; y_b = h; x_l = 0;\n                                for (const auto& p : current_state.placed) {\n                                    if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                }\n                                x_r = x_l + w;\n                            }\n                            long long nw = max(current_state.W, x_r);\n                            long long nh = max(current_state.H, y_b);\n                            if (nw + nh < best_new_W_H) {\n                                best_new_W_H = nw + nh;\n                                opt_count = 0;\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            } else if (nw + nh == best_new_W_H) {\n                                options[opt_count++] = {r, d, -1, nw, nh};\n                            }\n\n                            // Try Case 2: Reference rectangle b is a previously placed rectangle\n                            for (const auto& prev : current_state.placed) {\n                                int b_id = prev.id;\n                                if (d == 0) { // U\n                                    x_l = prev.x_right; x_r = x_l + w; y_t = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(x_r <= p.x || x_l >= p.x_right)) y_t = max(y_t, p.y_bottom);\n                                    }\n                                    y_b = y_t + h;\n                                } else { // L\n                                    y_t = prev.y_bottom; y_b = y_t + h; x_l = 0;\n                                    for (const auto& p : current_state.placed) {\n                                        if (!(y_b <= p.y || y_t >= p.y_bottom)) x_l = max(x_l, p.x_right);\n                                    }\n                                    x_r = x_l + w;\n                                }\n                                nw = max(current_state.W, x_r);\n                                nh = max(current_state.H, y_b);\n                                if (nw + nh < best_new_W_H) {\n                                    best_new_W_H = nw + nh;\n                                    opt_count = 0;\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                } else if (nw + nh == best_new_W_H) {\n                                    options[opt_count++] = {r, d, b_id, nw, nh};\n                                }\n                            }\n                        }\n                    }\n\n                    // Greedy decision: Include rectangle i if the score improvement is worth it.\n                    long long delta = best_new_W_H - (current_state.W + current_state.H);\n                    if (delta < wi + hi && opt_count > 0) {\n                        uniform_int_distribution<int> dist(0, opt_count - 1);\n                        Option opt = options[dist(rng)];\n                        long long w = (opt.r == 0 ? wi : hi);\n                        long long h = (opt.r == 0 ? hi : wi);\n                        Rect nr; nr.id = i; nr.w = w; nr.h = h;\n                        if (opt.d == 0) { // Direction U\n                            if (opt.b == -1) nr.x = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.x = p.x_right; break; }\n                            }\n                            nr.x_right = nr.x + w;\n                            long long yt = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.x_right <= p.x || nr.x >= p.x_right)) yt = max(yt, p.y_bottom);\n                            nr.y = yt; nr.y_bottom = yt + h;\n                        } else { // Direction L\n                            if (opt.b == -1) nr.y = 0;\n                            else {\n                                for (const auto& p : current_state.placed) if (p.id == opt.b) { nr.y = p.y_bottom; break; }\n                            }\n                            nr.y_bottom = nr.y + h;\n                            long long xl = 0;\n                            for (const auto& p : current_state.placed) if (!(nr.y_bottom <= p.y || nr.y >= p.y_bottom)) xl = max(xl, p.x_right);\n                            nr.x = xl; nr.x_right = xl + w;\n                        }\n                        current_state.placed.push_back(nr);\n                        current_state.placements.push_back({i, opt.r, opt.d, opt.b});\n                        current_state.W = max(current_state.W, nr.x_right);\n                        current_state.H = max(current_state.H, nr.y_bottom);\n                        unused_sum -= (wi + hi);\n                    }\n                }\n                current_state.score = current_state.W + current_state.H + unused_sum;\n                if (current_state.score < best_state.score) best_state = current_state;\n            }\n        }\n\n        // Output the best arrangement found for the current turn.\n        cout << best_state.placed.size() << \"\\n\";\n        for (const auto& pl : best_state.placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << (pl.d == 0 ? \"U\" : \"L\") << \" \" << pl.b << \"\\n\";\n        }\n        cout.flush();\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n    }\n\n    return 0;\n}\n","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Problem: Partition a planar graph into rooted trees to maximize sum (h_v + 1) * A_v,\n * subject to height constraint h_v <= H.\n * \n * The main reason for the previous WRONG_ANSWER was the incorrect update of subtree \n * properties (subtree_sum_A and max_rel_depth) in the initial greedy construction \n * and during simulated annealing. If the properties were not updated correctly, \n * the height constraint check could fail.\n * \n * Strategy:\n * 1. Initial Solution: Greedy approach. Sort nodes by beauty (A_v) ascending.\n *    For each node, try to attach it to an existing node in a tree that has \n *    the maximum depth < H. This aims to put high-beauty nodes at greater depths.\n * 2. Optimization: Simulated Annealing (SA).\n *    Moves: Change the parent of a node v to a neighbor u (or -1 for root).\n *    Constraints:\n *      - No cycles: u must not be in v's subtree.\n *      - Height: new_depth_v + max_rel_depth_v <= H.\n *    Efficiency:\n *      - Depth and ancestor check in O(H).\n *      - Maintain subtree_sum_A and max_rel_depth for each node.\n *      - Updating these values takes O(H * average_degree) by walking up ancestors.\n *    Since H is small (H=10), this allows for millions of SA iterations.\n */\n\nconst int MAXN = 1005;\nint N, M, H;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_rel_depth[MAXN];\n\n// Returns the distance from node v to its root (root distance is 0)\nint get_depth(int v) {\n    int d = 0;\n    while (v != -1) {\n        v = parent[v];\n        d++;\n    }\n    return d - 1;\n}\n\n// Checks if node v is an ancestor of node u\nbool is_ancestor(int v, int u) {\n    int curr = u;\n    while (curr != -1) {\n        if (curr == v) return true;\n        curr = parent[curr];\n    }\n    return false;\n}\n\n// Updates subtree_sum_A and max_rel_depth for node v and all its ancestors.\n// Since height is at most H, the path to the root is at most H+1.\nvoid update_subtree_info(int v) {\n    if (v == -1) return;\n    int curr = v;\n    while (curr != -1) {\n        long long new_sum = A[curr];\n        int new_max_rd = 0;\n        for (int c : children[curr]) {\n            new_sum += subtree_sum_A[c];\n            new_max_rd = max(new_max_rd, max_rel_depth[c] + 1);\n        }\n        \n        // If the node's properties don't change, the ancestors won't change either.\n        // However, in the initial greedy construction, we must ensure we actually\n        // update the ancestors even if the initial values were already set.\n        // Using a simple update loop without a premature break should be safe and fast.\n        subtree_sum_A[curr] = new_sum;\n        max_rel_depth[curr] = new_max_rd;\n        curr = parent[curr];\n    }\n}\n\nint main() {\n    // Optimization for faster standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> H)) return 0;\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // Skip coordinate input as they aren't needed for this approach\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Initialize state\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_rel_depth[i] = 0;\n    }\n\n    // Initial greedy construction\n    vector<int> order(N);\n    for (int i = 0; i < N; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return A[a] < A[b];\n    });\n\n    vector<bool> processed(N, false);\n    for (int v : order) {\n        int best_u = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (processed[u]) {\n                int d = get_depth(u);\n                if (d < H && d > max_d) {\n                    max_d = d;\n                    best_u = u;\n                }\n            }\n        }\n        \n        // v's own info is already set to A[v] and 0\n        subtree_sum_A[v] = A[v];\n        max_rel_depth[v] = 0;\n\n        if (best_u != -1) {\n            parent[v] = best_u;\n            children[best_u].push_back(v);\n            // Update ancestors of the new parent\n            update_subtree_info(best_u);\n        }\n        processed[v] = true;\n    }\n\n    // Simulated Annealing (SA) refinement\n    auto start_time = chrono::high_resolution_clock::now();\n    mt19937 rng(42);\n    \n    double T_start = 100.0;\n    double T_end = 0.01;\n    int iterations = 1000000;\n    double cooling_rate = pow(T_end / T_start, 1.0 / iterations);\n    double T = T_start;\n\n    for (int iter = 0; iter < iterations; ++iter) {\n        if ((iter & 1023) == 0) { // Periodic time check\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1850) break;\n        }\n\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int u_idx = uniform_int_distribution<int>(-1, (int)adj[v].size() - 1)(rng);\n        int u = (u_idx == -1) ? -1 : adj[v][u_idx];\n\n        if (u == parent[v]) {\n            T *= cooling_rate;\n            continue;\n        }\n        if (u != -1 && is_ancestor(v, u)) {\n            T *= cooling_rate;\n            continue;\n        }\n\n        int old_p = parent[v];\n        int new_p = u;\n        int old_depth_v = get_depth(v);\n        int new_depth_v = (new_p == -1) ? 0 : get_depth(new_p) + 1;\n\n        // Constraint check: ensures no node in v's subtree exceeds height H\n        if (new_depth_v + max_rel_depth[v] > H) {\n            T *= cooling_rate;\n            continue;\n        }\n\n        // Change in score\n        long long delta = (long long)(new_depth_v - old_depth_v) * subtree_sum_A[v];\n\n        if (delta > 0 || uniform_real_distribution<double>(0, 1)(rng) < exp((double)delta / T)) {\n            // Accept the move\n            if (old_p != -1) {\n                auto& old_children = children[old_p];\n                old_children.erase(remove(old_children.begin(), old_children.end(), v), old_children.end());\n                update_subtree_info(old_p);\n            }\n            parent[v] = new_p;\n            if (new_p != -1) {\n                children[new_p].push_back(v);\n                update_subtree_info(new_p);\n            }\n        }\n        T *= cooling_rate;\n    }\n\n    // Final output\n    for (int i = 0; i < N; ++i) {\n        cout << parent[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem: Oni wa Soto, Fuku wa Uchi\n * \n * Objective: Remove all Oni ('x') from an NxN board without removing any Fukunokami ('o').\n * Strategy:\n * 1. Use a \"push and pull\" strategy for each Oni:\n *    If an Oni is at (r, c), and there's no Fukunokami in an edge direction (e.g., Up),\n *    we can shift the column j upward (r+1) times and then downward (r+1) times.\n *    This removes the Oni at (r, c) and returns the board to its original state.\n *    This is safe and ensures zero Fukunokami are removed.\n * 2. Each such move covers a subset of Oni in a row or column.\n * 3. The goal is to cover all Oni with the minimum total number of shifts (cost).\n * 4. We model this as a Set Cover problem and solve it using Randomized Greedy heuristics.\n *    Since the number of Oni and potential moves is small (N=20, Oni <= 40), \n *    we can run many randomized trials within the time limit to find a near-optimal sequence.\n */\n\nstruct Oni {\n    int r, c;\n};\n\nstruct Move {\n    char d;\n    int p;\n    int k;\n    int cost;\n    vector<int> covered_indices;\n};\n\nint main() {\n    // Optimize Standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> board(N);\n    vector<Oni> oni_list;\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_list.push_back({i, j});\n            }\n        }\n    }\n\n    vector<Move> all_possible_moves;\n\n    // Generate the set of all \"minimal\" push-and-pull moves that are safe (no Fukunokami in the way).\n    // For each Oni, we consider its 4 potential directions.\n    for (int idx = 0; idx < (int)oni_list.size(); ++idx) {\n        int r = oni_list[idx].r;\n        int c = oni_list[idx].c;\n\n        // Check Upward direction\n        bool up_safe = true;\n        for (int k = 0; k < r; ++k) {\n            if (board[k][c] == 'o') {\n                up_safe = false;\n                break;\n            }\n        }\n        if (up_safe) {\n            Move m;\n            m.d = 'U'; m.p = c; m.k = r + 1; m.cost = 2 * (r + 1);\n            for (int i = 0; i < (int)oni_list.size(); ++i) {\n                if (oni_list[i].c == c && oni_list[i].r < r + 1) {\n                    m.covered_indices.push_back(i);\n                }\n            }\n            all_possible_moves.push_back(m);\n        }\n\n        // Check Downward direction\n        bool down_safe = true;\n        for (int k = r + 1; k < N; ++k) {\n            if (board[k][c] == 'o') {\n                down_safe = false;\n                break;\n            }\n        }\n        if (down_safe) {\n            Move m;\n            m.d = 'D'; m.p = c; m.k = N - r; m.cost = 2 * (N - r);\n            for (int i = 0; i < (int)oni_list.size(); ++i) {\n                if (oni_list[i].c == c && oni_list[i].r >= r) {\n                    m.covered_indices.push_back(i);\n                }\n            }\n            all_possible_moves.push_back(m);\n        }\n\n        // Check Leftward direction\n        bool left_safe = true;\n        for (int k = 0; k < c; ++k) {\n            if (board[r][k] == 'o') {\n                left_safe = false;\n                break;\n            }\n        }\n        if (left_safe) {\n            Move m;\n            m.d = 'L'; m.p = r; m.k = c + 1; m.cost = 2 * (c + 1);\n            for (int i = 0; i < (int)oni_list.size(); ++i) {\n                if (oni_list[i].r == r && oni_list[i].c < c + 1) {\n                    m.covered_indices.push_back(i);\n                }\n            }\n            all_possible_moves.push_back(m);\n        }\n\n        // Check Rightward direction\n        bool right_safe = true;\n        for (int k = c + 1; k < N; ++k) {\n            if (board[r][k] == 'o') {\n                right_safe = false;\n                break;\n            }\n        }\n        if (right_safe) {\n            Move m;\n            m.d = 'R'; m.p = r; m.k = N - c; m.cost = 2 * (N - c);\n            for (int i = 0; i < (int)oni_list.size(); ++i) {\n                if (oni_list[i].r == r && oni_list[i].c >= c) {\n                    m.covered_indices.push_back(i);\n                }\n            }\n            all_possible_moves.push_back(m);\n        }\n    }\n\n    // Randomized Greedy search with multiple trials\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int best_total_cost = 2000000000; // Infinity\n    vector<Move> best_chosen_moves;\n\n    auto start_time = chrono::steady_clock::now();\n\n    int trial = 0;\n    while (true) {\n        trial++;\n        // Check elapsed time every 10 trials to avoid overhead\n        if (trial % 10 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) {\n                break;\n            }\n        }\n\n        vector<bool> uncovered(oni_list.size(), true);\n        int remaining_oni = (int)oni_list.size();\n        int current_total_cost = 0;\n        vector<Move> current_chosen_moves;\n\n        while (remaining_oni > 0) {\n            double max_ratio = -1.0;\n            vector<int> candidate_indices;\n\n            // Calculate the efficiency (count / cost) for each possible move\n            for (int i = 0; i < (int)all_possible_moves.size(); ++i) {\n                int count = 0;\n                for (int idx : all_possible_moves[i].covered_indices) {\n                    if (uncovered[idx]) count++;\n                }\n                if (count > 0) {\n                    double ratio = (double)count / all_possible_moves[i].cost;\n                    if (ratio > max_ratio) {\n                        max_ratio = ratio;\n                        candidate_indices.clear();\n                        candidate_indices.push_back(i);\n                    } else if (ratio > max_ratio * 0.95) { \n                        // Allow some stochasticity by picking from near-optimal moves\n                        candidate_indices.push_back(i);\n                    }\n                }\n            }\n\n            if (candidate_indices.empty()) break;\n\n            // Random selection from candidates to explore the solution space\n            uniform_int_distribution<int> dist(0, (int)candidate_indices.size() - 1);\n            int chosen_idx = candidate_indices[dist(rng)];\n            \n            current_chosen_moves.push_back(all_possible_moves[chosen_idx]);\n            current_total_cost += all_possible_moves[chosen_idx].cost;\n            for (int idx : all_possible_moves[chosen_idx].covered_indices) {\n                if (uncovered[idx]) {\n                    uncovered[idx] = false;\n                    remaining_oni--;\n                }\n            }\n        }\n\n        // Keep the best result found across all trials\n        if (remaining_oni == 0 && current_total_cost < best_total_cost) {\n            best_total_cost = current_total_cost;\n            best_chosen_moves = current_chosen_moves;\n        }\n    }\n\n    // Output the resulting moves in the specified format\n    for (const auto& m : best_chosen_moves) {\n        char d1 = m.d;\n        char d2;\n        if (m.d == 'U') d2 = 'D';\n        else if (m.d == 'D') d2 = 'U';\n        else if (m.d == 'L') d2 = 'R';\n        else d2 = 'L';\n\n        // Perform push (k times) and pull (k times)\n        for (int i = 0; i < m.k; ++i) cout << d1 << \" \" << m.p << \"\\n\";\n        for (int i = 0; i < m.k; ++i) cout << d2 << \" \" << m.p << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Global variables for efficiency in the optimization loop\nint N;\nlong long L;\nvector<long long> T;\nvector<int> a, b;\nvector<long long> S;\nlong long current_err = 0;\n\n// Function to update the sum of T_j for the nodes a[j] and b[j]\n// We maintain the error term 'current_err' = sum |S_i - 2*T_i| in O(1)\nvoid apply_a(int j, int new_a) {\n    int old_a = a[j];\n    if (old_a == new_a) return;\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] -= T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] += T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    a[j] = new_a;\n}\n\nvoid revert_a(int j, int old_a, int new_a) {\n    if (old_a == new_a) return;\n    current_err -= abs(S[new_a] - 2 * T[new_a]);\n    S[new_a] -= T[j];\n    current_err += abs(S[new_a] - 2 * T[new_a]);\n    current_err -= abs(S[old_a] - 2 * T[old_a]);\n    S[old_a] += T[j];\n    current_err += abs(S[old_a] - 2 * T[old_a]);\n    a[j] = old_a;\n}\n\nvoid apply_b(int j, int new_b) {\n    int old_b = b[j];\n    if (old_b == new_b) return;\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] -= T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] += T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    b[j] = new_b;\n}\n\nvoid revert_b(int j, int old_b, int new_b) {\n    if (old_b == new_b) return;\n    current_err -= abs(S[new_b] - 2 * T[new_b]);\n    S[new_b] -= T[j];\n    current_err += abs(S[new_b] - 2 * T[new_b]);\n    current_err -= abs(S[old_b] - 2 * T[old_b]);\n    S[old_b] += T[j];\n    current_err += abs(S[old_b] - 2 * T[old_b]);\n    b[j] = old_b;\n}\n\nint visited[105];\nint timestamp = 0;\nint q[105];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> L)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    a.resize(N);\n    b.resize(N);\n    S.assign(N, 0);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Initial random assignment\n    for (int i = 0; i < N; ++i) {\n        a[i] = rng() % N;\n        b[i] = rng() % N;\n        S[a[i]] += T[i];\n        S[b[i]] += T[i];\n    }\n\n    current_err = 0;\n    for (int i = 0; i < N; ++i) {\n        current_err += abs(S[i] - 2 * T[i]);\n    }\n\n    // BFS-based reachability check to calculate the penalty\n    auto get_total_cost = [&]() {\n        timestamp++;\n        int head = 0, tail = 0;\n        q[tail++] = 0;\n        visited[0] = timestamp;\n        while (head < tail) {\n            int u = q[head++];\n            if (visited[a[u]] != timestamp) {\n                visited[a[u]] = timestamp;\n                q[tail++] = a[u];\n            }\n            if (visited[b[u]] != timestamp) {\n                visited[b[u]] = timestamp;\n                q[tail++] = b[u];\n            }\n        }\n        long long penalty = 0;\n        for (int i = 0; i < N; ++i) {\n            // If an employee with assigned duties is not reachable, penalize heavily\n            if (T[i] > 0 && visited[i] != timestamp) {\n                penalty += 1000000LL;\n            }\n        }\n        return current_err + penalty;\n    };\n\n    long long current_cost = get_total_cost();\n    \n    // Simulated Annealing parameters\n    int total_iters = 1000000;\n    double T_start = 1000000.0;\n    double T_end = 0.5;\n\n    for (int iter = 0; iter < total_iters; ++iter) {\n        int j = rng() % N;\n        int old_a = a[j], old_b = b[j];\n        int type = rng() % 3; // 0: change a, 1: change b, 2: change both\n        int new_a = old_a, new_b = old_b;\n        \n        if (type == 0) new_a = rng() % N;\n        else if (type == 1) new_b = rng() % N;\n        else { new_a = rng() % N; new_b = rng() % N; }\n\n        if (new_a == old_a && new_b == old_b) continue;\n\n        bool a_changed = (new_a != old_a);\n        bool b_changed = (new_b != old_b);\n\n        if (a_changed) apply_a(j, new_a);\n        if (b_changed) apply_b(j, new_b);\n\n        long long next_cost = get_total_cost();\n        double temp = T_start * pow(T_end / T_start, (double)iter / total_iters);\n\n        if (next_cost < current_cost || dist(rng) < exp((double)(current_cost - next_cost) / temp)) {\n            current_cost = next_cost;\n        } else {\n            // Revert changes if not accepted\n            if (b_changed) revert_b(j, old_b, new_b);\n            if (a_changed) revert_a(j, old_a, new_a);\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <cstdint>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Strategy Refinement:\n * \n * 1. Coordinate Estimation & Spatial Locality:\n *    Estimate city coordinates using the center of their given rectangular bounds.\n *    Sort cities using a Morton curve (Z-order) to ensure that cities near each other\n *    in 2D space are likely to be placed in the same or adjacent groups.\n * \n * 2. Improved Grouping via Local Search:\n *    Initial grouping follows the Morton order.\n *    We use a Randomized Local Search (swap heuristic) to optimize the grouping.\n *    In each iteration, we swap two cities from different groups if the swap reduces\n *    the total estimated Minimum Spanning Tree (MST) cost (calculated using center coordinates).\n *    This is done within a time limit to avoid TLE.\n * \n * 3. Optimized Query Strategy:\n *    The query limit Q=400 and N=800 allows for roughly 2 cities per query if we want to cover all.\n *    We use a sliding window approach within each group. \n *    For a group of size G_i:\n *    - If G_i <= L, one query covers the group.\n *    - If G_i > L, we use a sliding window where each subsequent query adds exactly \n *      S = 2 new cities. This is achieved by having an overlap of (L - S) = (L - 2) cities.\n *    - Total queries: Sum_{G_i > 1} (1 + max(0, ceil((G_i - L) / 2))) is guaranteed \n *      to be <= 400 for N=800, Q=400, and L >= 3.\n * \n * 4. Final Road Selection:\n *    Within each group, we collect all edges returned by the queries.\n *    To ensure we choose \"good\" edges, we sort these edges by their estimated distance \n *    and use Kruskal's algorithm to find the MST for that group.\n *    If connectivity is not achieved (unlikely with S=2), we add fallback edges.\n */\n\n// Morton (Z-order) curve encoding for 2D points.\nuint64_t interleave(uint32_t x, uint32_t y) {\n    uint64_t z = 0;\n    for (int i = 0; i < 32; ++i) {\n        z |= (static_cast<uint64_t>((x >> i) & 1) << (2 * i));\n        z |= (static_cast<uint64_t>((y >> i) & 1) << (2 * i + 1));\n    }\n    return z;\n}\n\nstruct City {\n    int id;\n    uint64_t morton;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int i) {\n        if (parent[i] == i) return i;\n        return parent[i] = find(parent[i]);\n    }\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j;\n            return true;\n        }\n        return false;\n    }\n};\n\ndouble estimated_dist(int i, int j, const vector<pair<int, int>>& centers) {\n    double dx = (double)centers[i].first - centers[j].first;\n    double dy = (double)centers[i].second - centers[j].second;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Prim's algorithm for calculating MST cost of a group of cities using center points.\ndouble calculate_group_mst_cost(const vector<int>& group_cities, const vector<pair<int, int>>& centers) {\n    int n = group_cities.size();\n    if (n <= 1) return 0;\n    vector<double> min_dist(n, 1e18);\n    vector<bool> visited(n, false);\n    min_dist[0] = 0;\n    double total_cost = 0;\n    for (int i = 0; i < n; ++i) {\n        int u = -1;\n        for (int j = 0; j < n; ++j) {\n            if (!visited[j] && (u == -1 || min_dist[j] < min_dist[u]))\n                u = j;\n        }\n        if (u == -1 || min_dist[u] == 1e18) break; \n        visited[u] = true;\n        total_cost += min_dist[u];\n        for (int v = 0; v < n; ++v) {\n            if (!visited[v]) {\n                double d = estimated_dist(group_cities[u], group_cities[v], centers);\n                if (d < min_dist[v]) min_dist[v] = d;\n            }\n        }\n    }\n    return total_cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<pair<int, int>> centers(N);\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        int cx = (lx + rx) / 2;\n        int cy = (ly + ry) / 2;\n        centers[i] = {cx, cy};\n        cities[i] = {i, interleave((uint32_t)cx, (uint32_t)cy)};\n    }\n\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        return a.morton < b.morton;\n    });\n\n    vector<int> current_assignment(N);\n    vector<vector<int>> groups(M);\n    int curr_idx = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            int city_id = cities[curr_idx++].id;\n            groups[i].push_back(city_id);\n            current_assignment[city_id] = i;\n        }\n    }\n\n    vector<double> group_mst_costs(M);\n    for (int i = 0; i < M; ++i) {\n        group_mst_costs[i] = calculate_group_mst_cost(groups[i], centers);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 600) {\n        int u = uniform_int_distribution<int>(0, N - 1)(rng);\n        int v = uniform_int_distribution<int>(0, N - 1)(rng);\n        int gu = current_assignment[u];\n        int gv = current_assignment[v];\n        if (gu == gv) continue;\n\n        vector<int> new_group_u, new_group_v;\n        for (int city : groups[gu]) if (city != u) new_group_u.push_back(city);\n        new_group_u.push_back(v);\n        for (int city : groups[gv]) if (city != v) new_group_v.push_back(city);\n        new_group_v.push_back(u);\n\n        double new_cost_u = calculate_group_mst_cost(new_group_u, centers);\n        double new_cost_v = calculate_group_mst_cost(new_group_v, centers);\n\n        if (new_cost_u + new_cost_v < group_mst_costs[gu] + group_mst_costs[gv]) {\n            groups[gu] = new_group_u;\n            groups[gv] = new_group_v;\n            current_assignment[u] = gv;\n            current_assignment[v] = gu;\n            group_mst_costs[gu] = new_cost_u;\n            group_mst_costs[gv] = new_cost_v;\n        }\n    }\n\n    vector<vector<pair<int, int>>> edges_in_group(M);\n    int S = 2; // Number of new cities per query\n\n    for (int i = 0; i < M; ++i) {\n        int g_size = groups[i].size();\n        if (g_size <= 1) continue;\n\n        vector<pair<int, int>> collected_edges;\n        \n        int start = 0;\n        int end = min(L - 1, g_size - 1);\n        \n        auto perform_query = [&](int s, int e) {\n            int subset_size = e - s + 1;\n            cout << \"? \" << subset_size;\n            for (int k = s; k <= e; ++k) cout << \" \" << groups[i][k];\n            cout << endl;\n            for (int k = 0; k < subset_size - 1; ++k) {\n                int u_e, v_e;\n                cin >> u_e >> v_e;\n                collected_edges.push_back({u_e, v_e});\n            }\n        };\n\n        perform_query(start, end);\n\n        // Sliding window: each query adds S = 2 new cities. \n        // To add 2 new cities, the overlap must be (L - 2).\n        int overlap = L - S;\n        while (end < g_size - 1) {\n            start = end - overlap + 1;\n            end = min(start + L - 1, g_size - 1);\n            perform_query(start, end);\n        }\n\n        DSU dsu(N);\n        sort(collected_edges.begin(), collected_edges.end(), [&](const pair<int,int>& a, const pair<int,int>& b) {\n            return estimated_dist(a.first, a.second, centers) < estimated_dist(b.first, b.second, centers);\n        });\n\n        for (auto& edge : collected_edges) {\n            if (dsu.unite(edge.first, edge.second)) {\n                edges_in_group[i].push_back(edge);\n            }\n        }\n        for (int k = 1; k < g_size; ++k) {\n            if (dsu.unite(groups[i][0], groups[i][k])) {\n                edges_in_group[i].push_back({groups[i][0], groups[i][k]});\n            }\n        }\n    }\n\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            cout << groups[i][j] << (j == (int)groups[i].size() - 1 ? \"\" : \" \");\n        }\n        cout << endl;\n        for (auto& edge : edges_in_group[i]) {\n            cout << edge.first << \" \" << edge.second << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - Grid size: 20x20.\n * - Number of target squares: M-1 = 39.\n * - Total turns allowed: 1600.\n * - Score formula: M + 2NM - T, where T is the number of turns.\n * - Goals: Visit all targets in order and minimize T.\n * \n * Insights from Initial Approach:\n * - The 'Move' (M) only strategy achieves a score of ~1100.\n * - A better strategy should utilize 'Slide' (S) to reduce the number of turns T.\n * - 'Slide' is useful when it can cover a large distance by hitting a boundary or a block.\n * - Boundary sliding can be used to jump from (r, c) to (0, c) or (N-1, c) in one turn.\n * \n * Refined Strategy:\n * - Use Dijkstra's algorithm to find the shortest path between consecutive target squares.\n * - The state for Dijkstra will be the current (row, col) position.\n * - Transitions include:\n *   1. Move (M) in 4 cardinal directions (cost 1, only if the cell is in bounds and not a block).\n *   2. Slide (S) in 4 cardinal directions (cost 1, stops at the first block or boundary encountered).\n * - This approach naturally optimizes both 'Move' and 'Slide' actions, including boundary jumps.\n * - Since the grid is small (20x20), Dijkstra is computationally efficient.\n */\n\nconst int INF = 1e9;\n\n// State for Dijkstra\nstruct State {\n    int d, r, c;\n    bool operator>(const State& other) const {\n        return d > other.d;\n    }\n};\n\n// Parent pointer to reconstruct the path\nstruct Parent {\n    int r, c;\n    char action;\n    int dir;\n};\n\nint N, M;\nbool G[20][20]; // Grid representing block positions\nint dr[] = {-1, 1, 0, 0}; // Directions: Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar dir_chars[] = {'U', 'D', 'L', 'R'};\n\nvoid solve() {\n    // Input N and M\n    if (!(cin >> N >> M)) return;\n    int r0, c0;\n    if (!(cin >> r0 >> c0)) return;\n    \n    // Read the sequence of target squares\n    vector<pair<int, int>> targets(M);\n    targets[0] = {r0, c0};\n    for (int i = 1; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    // Initialize grid (initially no blocks)\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            G[i][j] = false;\n\n    int curr_r = r0, curr_c = c0;\n\n    // Iterate through target squares in order\n    for (int k = 1; k < M; ++k) {\n        int tr = targets[k].first;\n        int tc = targets[k].second;\n\n        // Dijkstra algorithm to find the shortest path from curr to target\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<Parent>> parent(N, vector<Parent>(N, {-1, -1, ' ', -1}));\n\n        priority_queue<State, vector<State>, greater<State>> pq;\n        dist[curr_r][curr_c] = 0;\n        pq.push({0, curr_r, curr_c});\n\n        while (!pq.empty()) {\n            State top = pq.top();\n            pq.pop();\n            int d = top.d, r = top.r, c = top.c;\n\n            if (d > dist[r][c]) continue;\n            if (r == tr && c == tc) break;\n\n            for (int i = 0; i < 4; ++i) {\n                // Action 1: Move (M)\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !G[nr][nc]) {\n                    if (dist[nr][nc] > d + 1) {\n                        dist[nr][nc] = d + 1;\n                        parent[nr][nc] = {r, c, 'M', i};\n                        pq.push({dist[nr][nc], nr, nc});\n                    }\n                }\n\n                // Action 2: Slide (S)\n                int sr = r, sc = c;\n                while (true) {\n                    int next_r = sr + dr[i], next_c = sc + dc[i];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                // A Slide is only considered if it actually results in a movement\n                if (sr != r || sc != c) {\n                    if (dist[sr][sc] > d + 1) {\n                        dist[sr][sc] = d + 1;\n                        parent[sr][sc] = {r, c, 'S', i};\n                        pq.push({dist[sr][sc], sr, sc});\n                    }\n                }\n            }\n        }\n\n        // Reconstruct the sequence of actions taken to reach target (tr, tc)\n        vector<pair<char, int>> path;\n        if (dist[tr][tc] == INF) {\n            // Safety fallback: manual Manhattan movement if Dijkstra fails\n            int temp_r = curr_r, temp_c = curr_c;\n            while (temp_r != tr) {\n                int d_dir = (tr > temp_r) ? 1 : 0;\n                path.push_back({'M', d_dir});\n                temp_r += dr[d_dir];\n            }\n            while (temp_c != tc) {\n                int d_dir = (tc > temp_c) ? 3 : 2;\n                path.push_back({'M', d_dir});\n                temp_c += dc[d_dir];\n            }\n        } else {\n            int pr = tr, pc = tc;\n            while (pr != curr_r || pc != curr_c) {\n                Parent p = parent[pr][pc];\n                path.push_back({p.action, p.dir});\n                pr = p.r; pc = p.c;\n            }\n            reverse(path.begin(), path.end());\n        }\n\n        // Output the actions and update current position\n        for (auto& step : path) {\n            cout << step.first << \" \" << dir_chars[step.second] << \"\\n\";\n            if (step.first == 'M') {\n                curr_r += dr[step.second];\n                curr_c += dc[step.second];\n            } else if (step.first == 'S') {\n                int sr = curr_r, sc = curr_c;\n                while (true) {\n                    int next_r = sr + dr[step.second], next_c = sc + dc[step.second];\n                    if (next_r >= 0 && next_r < N && next_c >= 0 && next_c < N && !G[next_r][next_c]) {\n                        sr = next_r; sc = next_c;\n                    } else {\n                        break;\n                    }\n                }\n                curr_r = sr; curr_c = sc;\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    solve();\n    return 0;\n}\n"}}}