{"model_name":"gemini-3-flash-preview-high","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nstruct Company {\n    int x, y, r;\n    Rect rect;\n};\n\n// Satisfaction level p_i calculation\ndouble get_p(long long s, long long r) {\n    if (s <= 0) return 0.0;\n    double ratio = (s < r) ? (double)s / r : (double)r / s;\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\nint main() {\n    // Faster 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<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        // Start with 1x1 rectangles containing the required points\n        companies[i].rect = {companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1};\n    }\n\n    mt19937 rng(42);\n\n    // Phase 1: Initial Greedy Expansion\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n    for (int iter = 0; iter < 50; ++iter) {\n        shuffle(idx.begin(), idx.end(), rng);\n        bool changed = false;\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3};\n            shuffle(dirs, dirs + 4, rng);\n            for (int dir : dirs) {\n                long long s = (long long)(companies[i].rect.c - companies[i].rect.a) * (companies[i].rect.d - companies[i].rect.b);\n                if (s >= companies[i].r) continue;\n\n                int range_min, range_max;\n                if (dir == 0) { // Expand left side (a_i)\n                    range_min = 0; range_max = companies[i].x;\n                    for (int j = 0; j < n; ++j) {\n                        if (i == j) continue;\n                        if (companies[i].rect.b < companies[j].rect.d && companies[j].rect.b < companies[i].rect.d) {\n                            if (companies[j].rect.c <= companies[i].x) {\n                                if (companies[j].rect.c > range_min) range_min = companies[j].rect.c;\n                            }\n                        }\n                    }\n                    int target_w = (int)round((double)companies[i].r / (companies[i].rect.d - companies[i].rect.b));\n                    int target_a = max(range_min, min(range_max, companies[i].rect.c - target_w));\n                    if (target_a < companies[i].rect.a) { companies[i].rect.a = target_a; changed = true; }\n                } else if (dir == 1) { // Expand right side (c_i)\n                    range_min = companies[i].x + 1; range_max = 10000;\n                    for (int j = 0; j < n; ++j) {\n                        if (i == j) continue;\n                        if (companies[i].rect.b < companies[j].rect.d && companies[j].rect.b < companies[i].rect.d) {\n                            if (companies[j].rect.a > companies[i].x) {\n                                if (companies[j].rect.a < range_max) range_max = companies[j].rect.a;\n                            }\n                        }\n                    }\n                    int target_w = (int)round((double)companies[i].r / (companies[i].rect.d - companies[i].rect.b));\n                    int target_c = max(range_min, min(range_max, companies[i].rect.a + target_w));\n                    if (target_c > companies[i].rect.c) { companies[i].rect.c = target_c; changed = true; }\n                } else if (dir == 2) { // Expand bottom side (b_i)\n                    range_min = 0; range_max = companies[i].y;\n                    for (int j = 0; j < n; ++j) {\n                        if (i == j) continue;\n                        if (companies[i].rect.a < companies[j].rect.c && companies[j].rect.a < companies[i].rect.c) {\n                            if (companies[j].rect.d <= companies[i].y) {\n                                if (companies[j].rect.d > range_min) range_min = companies[j].rect.d;\n                            }\n                        }\n                    }\n                    int target_h = (int)round((double)companies[i].r / (companies[i].rect.c - companies[i].rect.a));\n                    int target_b = max(range_min, min(range_max, companies[i].rect.d - target_h));\n                    if (target_b < companies[i].rect.b) { companies[i].rect.b = target_b; changed = true; }\n                } else { // Expand top side (d_i)\n                    range_min = companies[i].y + 1; range_max = 10000;\n                    for (int j = 0; j < n; ++j) {\n                        if (i == j) continue;\n                        if (companies[i].rect.a < companies[j].rect.c && companies[j].rect.a < companies[i].rect.c) {\n                            if (companies[j].rect.b > companies[i].y) {\n                                if (companies[j].rect.b < range_max) range_max = companies[j].rect.b;\n                            }\n                        }\n                    }\n                    int target_h = (int)round((double)companies[i].r / (companies[i].rect.c - companies[i].rect.a));\n                    int target_d = max(range_min, min(range_max, companies[i].rect.b + target_h));\n                    if (target_d > companies[i].rect.d) { companies[i].rect.d = target_d; changed = true; }\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    // Phase 2: Simulated Annealing Refinement\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 0.01;\n    double T_end = 0.0001;\n    double T = T_start;\n    const double TIME_LIMIT = 4.8;\n    long long iter = 0;\n    while (true) {\n        if ((iter & 1023) == 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            double progress = elapsed / TIME_LIMIT;\n            T = T_start + (T_end - T_start) * progress;\n        }\n\n        int i = uniform_int_distribution<int>(0, n - 1)(rng);\n        int side = uniform_int_distribution<int>(0, 3)(rng);\n\n        // Compute valid range for picking the boundary to avoid overlap\n        int range_min, range_max;\n        if (side == 0 || side == 1) { // Left (a) or Right (c) side\n            range_min = (side == 0) ? 0 : companies[i].x + 1;\n            range_max = (side == 0) ? companies[i].x : 10000;\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (companies[i].rect.b < companies[j].rect.d && companies[j].rect.b < companies[i].rect.d) {\n                    if (side == 0) { if (companies[j].rect.c <= companies[i].x && companies[j].rect.c > range_min) range_min = companies[j].rect.c; }\n                    else { if (companies[j].rect.a > companies[i].x && companies[j].rect.a < range_max) range_max = companies[j].rect.a; }\n                }\n            }\n        } else { // Bottom (b) or Top (d) side\n            range_min = (side == 2) ? 0 : companies[i].y + 1;\n            range_max = (side == 2) ? companies[i].y : 10000;\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (companies[i].rect.a < companies[j].rect.c && companies[j].rect.a < companies[i].rect.c) {\n                    if (side == 2) { if (companies[j].rect.d <= companies[i].y && companies[j].rect.d > range_min) range_min = companies[j].rect.d; }\n                    else { if (companies[j].rect.b > companies[i].y && companies[j].rect.b < range_max) range_max = companies[j].rect.b; }\n                }\n            }\n        }\n\n        int old_v;\n        int* ptr;\n        if (side == 0) { old_v = companies[i].rect.a; ptr = &companies[i].rect.a; }\n        else if (side == 1) { old_v = companies[i].rect.c; ptr = &companies[i].rect.c; }\n        else if (side == 2) { old_v = companies[i].rect.b; ptr = &companies[i].rect.b; }\n        else { old_v = companies[i].rect.d; ptr = &companies[i].rect.d; }\n\n        int new_v;\n        if (uniform_int_distribution<int>(0, 1)(rng)) { // Target-based move\n            int target_v;\n            if (side == 0 || side == 1) {\n                int target_w = (int)round((double)companies[i].r / (companies[i].rect.d - companies[i].rect.b));\n                target_v = (side == 0) ? (companies[i].rect.c - max(1, target_w)) : (companies[i].rect.a + max(1, target_w));\n            } else {\n                int target_h = (int)round((double)companies[i].r / (companies[i].rect.c - companies[i].rect.a));\n                target_v = (side == 2) ? (companies[i].rect.d - max(1, target_h)) : (companies[i].rect.b + max(1, target_h));\n            }\n            new_v = max(range_min, min(range_max, target_v));\n        } else { // Uniformly random move\n            new_v = uniform_int_distribution<int>(range_min, range_max)(rng);\n        }\n\n        if (new_v != old_v) {\n            long long old_s = (long long)(companies[i].rect.c - companies[i].rect.a) * (companies[i].rect.d - companies[i].rect.b);\n            *ptr = new_v;\n            long long new_s = (long long)(companies[i].rect.c - companies[i].rect.a) * (companies[i].rect.d - companies[i].rect.b);\n            double delta_p = get_p(new_s, companies[i].r) - get_p(old_s, companies[i].r);\n\n            // Accept/Reject based on Simulated Annealing probability\n            if (delta_p < 0 && uniform_real_distribution<double>(0, 1)(rng) >= exp(delta_p / T)) {\n                *ptr = old_v;\n            }\n        }\n        iter++;\n    }\n\n    // Output results\n    for (int i = 0; i < n; ++i) {\n        cout << companies[i].rect.a << \" \" << companies[i].rect.b << \" \"\n             << companies[i].rect.c << \" \" << companies[i].rect.d << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <bitset>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to find a path on a 50x50 grid of squares.\n * - Each square belongs to a tile of size 1x1, 1x2, or 2x1.\n * - Each tile can be visited at most once.\n * - Score is the sum of values p[i][j] of the visited squares.\n * - This is an NP-hard path-finding problem on a graph where nodes are squares and constraints are on tiles.\n * \n * Algorithm:\n * - Beam Search is used with a beam width K.\n * - Each step of the beam search extends the path by one square.\n * - To ensure diversity, we only keep at most B paths ending at the same square.\n * - We use a bitset to keep track of visited tiles for each path in the beam.\n * - To save memory and time, we store the bitsets only for the current beam and \n *   keep a history of path nodes (parent pointers) to reconstruct the final path.\n */\n\nstruct PathNode {\n    short r, c;\n    int parent_idx;\n    char move;\n};\n\nstruct State {\n    short r, c;\n    int score;\n    int history_idx;\n    bitset<2500> visited;\n};\n\nstruct StateInfo {\n    short ni, nj;\n    int score;\n    int current_beam_idx;\n    char move_idx;\n};\n\n// Global variables to store the beam search history\nstatic vector<PathNode> history[2501];\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Track execution time to stop before the 2-second limit\n    auto start_time = chrono::high_resolution_clock::now();\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    int t[50][50];\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) cin >> t[i][j];\n\n    int p[50][50];\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) cin >> p[i][j];\n\n    // Beam search parameters\n    const int K = 5000; // Beam width\n    const int B = 2;    // Maximum paths per grid cell\n\n    vector<State> current_beam;\n    current_beam.reserve(K);\n\n    bitset<2500> initial_visited;\n    initial_visited.set(t[si][sj]);\n    \n    // Initial history and starting beam state\n    history[0].push_back({(short)si, (short)sj, -1, ' '});\n    current_beam.push_back({(short)si, (short)sj, p[si][sj], 0, initial_visited});\n\n    int best_score = p[si][sj];\n    int best_step = 0;\n    int best_idx = 0;\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    vector<StateInfo> next_candidates_info;\n    next_candidates_info.reserve(K * 4);\n    int counts[2500];\n\n    // Run beam search up to the maximum possible steps\n    for (int step = 1; step <= 2500; ++step) {\n        // Exit early if we are near the time limit\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        next_candidates_info.clear();\n        for (int i = 0; i < (int)current_beam.size(); ++i) {\n            const auto& s = current_beam[i];\n            for (int d = 0; d < 4; ++d) {\n                int ni = s.r + dr[d];\n                int nj = s.c + dc[d];\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    if (!s.visited.test(t[ni][nj])) {\n                        next_candidates_info.push_back({(short)ni, (short)nj, s.score + p[ni][nj], i, (char)d});\n                    }\n                }\n            }\n        }\n\n        // If no more valid moves are possible for any path in the beam, stop\n        if (next_candidates_info.empty()) break;\n\n        // Sort candidates by total score to pick the best for the beam\n        sort(next_candidates_info.begin(), next_candidates_info.end(), [](const StateInfo& a, const StateInfo& b) {\n            return a.score > b.score;\n        });\n\n        memset(counts, 0, sizeof(counts));\n        vector<State> next_beam;\n        next_beam.reserve(K);\n        history[step].reserve(K);\n\n        // Fill the next beam while enforcing diversity constraints\n        for (auto& info : next_candidates_info) {\n            int pos = info.ni * 50 + info.nj;\n            if (counts[pos] < B && (int)next_beam.size() < K) {\n                State ns;\n                ns.r = info.ni;\n                ns.c = info.nj;\n                ns.score = info.score;\n                // Deep copy bitset only for selected states to save time\n                ns.visited = current_beam[info.current_beam_idx].visited;\n                ns.visited.set(t[ns.r][ns.c]);\n                \n                // Store the current node and its link to the parent node in the history\n                ns.history_idx = (int)history[step].size();\n                history[step].push_back({(short)ns.r, (short)ns.c, current_beam[info.current_beam_idx].history_idx, move_chars[(int)info.move_idx]});\n                \n                next_beam.push_back(ns);\n                counts[pos]++;\n\n                // Keep track of the overall best state found\n                if (ns.score > best_score) {\n                    best_score = ns.score;\n                    best_step = step;\n                    best_idx = ns.history_idx;\n                }\n            }\n        }\n        \n        // Swap current_beam with next_beam for the next step\n        if (next_beam.empty()) break;\n        current_beam = std::move(next_beam);\n    }\n\n    // Reconstruct the best path from the history pointers\n    string res = \"\";\n    int curr_step = best_step;\n    int curr_idx = best_idx;\n    while (curr_step > 0) {\n        res += history[curr_step][curr_idx].move;\n        curr_idx = history[curr_step][curr_idx].parent_idx;\n        curr_step--;\n    }\n    reverse(res.begin(), res.end());\n    \n    // Output the resulting path\n    cout << res << endl;\n\n    return 0;\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 Summary:\n * We are given a 30x30 undirected grid graph with unknown edge lengths.\n * We need to process 1000 pathfinding queries, each providing a start and destination vertex.\n * After each path we output, we receive a noisy measurement of its length (~10% error).\n * The goal is to maximize the score, which is based on the ratio of the true shortest path \n * to our output path's length, weighted more heavily for later queries.\n *\n * Approach:\n * 1. Maintain estimates for each horizontal and vertical edge length.\n * 2. For each query, use Dijkstra's algorithm to find the shortest path based on current estimates.\n * 3. After receiving the path length measurement, update the edge weights.\n * 4. Use a kernel-based approach for updating weights to exploit the grid structure \n *    (most rows/columns have similar base lengths, according to the problem generation).\n */\n\n// Grid size constant.\nconst int N = 30;\n// Initial estimated length for each edge.\nconst double INIT_WEIGHT = 5000.0;\n// Possible edge length constraints as derived from the generation logic.\nconst double MIN_WEIGHT = 1000.0;\nconst double MAX_WEIGHT = 9000.0;\n// Smoothing factor for spreading information across rows and columns.\nconst double GAMMA = 0.95;\n\nstruct EdgeInfo {\n    int type; // 0 for horizontal, 1 for vertical\n    int i, j;\n};\n\n// Current weight estimates for horizontal and vertical edges.\ndouble h_weights[N][N - 1];\ndouble v_weights[N - 1][N];\n// Precomputed powers of GAMMA for kernel smoothing.\ndouble gamma_pow[N + 1];\n\n// Initialize weight estimates and precompute powers.\nvoid init() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) h_weights[i][j] = INIT_WEIGHT;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) v_weights[i][j] = INIT_WEIGHT;\n    }\n    for (int i = 0; i <= N; ++i) {\n        gamma_pow[i] = pow(GAMMA, i);\n    }\n}\n\n/**\n * find_path uses Dijkstra's algorithm on current weight estimates.\n * Returns the path string (e.g., \"UDRL\") and fills path_edges with edges used.\n */\nstring find_path(int si, int sj, int ti, int tj, vector<EdgeInfo>& path_edges) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<pair<int, int>, char>>> parent(N, vector<pair<pair<int, int>, char>>(N, {{-1, -1}, ' '}));\n    using P = pair<double, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int i = pq.top().second.first;\n        int j = pq.top().second.second;\n        pq.pop();\n\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        // Traverse neighbors: Up, Down, Left, Right\n        // Vertical edges v_weights[i][j] connect (i, j) and (i+1, j)\n        // Horizontal edges h_weights[i][j] connect (i, j) and (i, j+1)\n\n        // Up\n        if (i > 0) {\n            double w = v_weights[i - 1][j];\n            if (dist[i - 1][j] > d + w) {\n                dist[i - 1][j] = d + w;\n                parent[i - 1][j] = {{i, j}, 'U'};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        // Down\n        if (i < N - 1) {\n            double w = v_weights[i][j];\n            if (dist[i + 1][j] > d + w) {\n                dist[i + 1][j] = d + w;\n                parent[i + 1][j] = {{i, j}, 'D'};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double w = h_weights[i][j - 1];\n            if (dist[i][j - 1] > d + w) {\n                dist[i][j - 1] = d + w;\n                parent[i][j - 1] = {{i, j}, 'L'};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        // Right\n        if (j < N - 1) {\n            double w = h_weights[i][j];\n            if (dist[i][j + 1] > d + w) {\n                dist[i][j + 1] = d + w;\n                parent[i][j + 1] = {{i, j}, 'R'};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    // Trace back the path from target to source.\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char dir = parent[ci][cj].second;\n        path += dir;\n        int pi = parent[ci][cj].first.first;\n        int pj = parent[ci][cj].first.second;\n        if (dir == 'U') path_edges.push_back({1, ci, cj});\n        else if (dir == 'D') path_edges.push_back({1, pi, pj});\n        else if (dir == 'L') path_edges.push_back({0, ci, cj});\n        else if (dir == 'R') path_edges.push_back({0, pi, pj});\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/**\n * update_weights adapts estimates using the difference between predicted and actual lengths.\n * A kernel-based smoothing updates edges in the same row/column to utilize structural patterns.\n */\nvoid update_weights(const vector<EdgeInfo>& path_edges, int result, int k) {\n    double hat_L = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) hat_L += h_weights[e.i][e.j];\n        else hat_L += v_weights[e.i][e.j];\n    }\n\n    double error = (double)result - hat_L;\n    // Gradual decay of learning rate ensures stability as k increases.\n    double lr = 0.5 - 0.4 * (k / 1000.0);\n\n    // Track total impact of error distribution across grid edges.\n    vector<vector<double>> coeff_h(N, vector<double>(N - 1, 0.0));\n    vector<vector<double>> coeff_v(N - 1, vector<double>(N, 0.0));\n\n    // Distribution factor based on proximity within the same row/column.\n    for (const auto& e : path_edges) {\n        if (e.type == 0) { // Same-row horizontal edges\n            for (int jp = 0; jp < N - 1; ++jp) {\n                coeff_h[e.i][jp] += gamma_pow[abs(e.j - jp)];\n            }\n        } else { // Same-column vertical edges\n            for (int ip = 0; ip < N - 1; ++ip) {\n                coeff_v[ip][e.j] += gamma_pow[abs(e.i - ip)];\n            }\n        }\n    }\n\n    // Normalization factor to ensure the total weight shift aligns with current learning rate.\n    double S = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) S += coeff_h[e.i][e.j];\n        else S += coeff_v[e.i][e.j];\n    }\n\n    double step = error * lr / S;\n\n    // Apply the weight adjustments to relevant edges.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            if (coeff_h[i][j] > 0) {\n                h_weights[i][j] += step * coeff_h[i][j];\n                h_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, h_weights[i][j]));\n            }\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (coeff_v[i][j] > 0) {\n                v_weights[i][j] += step * coeff_v[i][j];\n                v_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, v_weights[i][j]));\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    init();\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        vector<EdgeInfo> path_edges;\n        string path = find_path(si, sj, ti, tj, path_edges);\n        cout << path << endl; // cout << endl flushes standard output automatically.\n\n        int result;\n        if (!(cin >> result)) break;\n        update_weights(path_edges, result, k);\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <cmath>\n#include <ctime>\n#include <cstring>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Fast xorshift random number generator\nuint32_t xorshift() {\n    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t t = x ^ (x << 11);\n    x = y; y = z; z = w;\n    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n}\n\nconst int N = 20;\nint M;\nint A[N][N];\nint best_A[N][N];\nint current_c = 0;\nint current_d = 0;\nint count_in_matrix[1000]; // Slightly larger than max M to be safe\nint weights[1000];\n\nstruct HashTable {\n    static const int SIZE = 8192;\n    long long keys[SIZE];\n    int values[SIZE];\n    HashTable() { memset(keys, -1, sizeof(keys)); }\n    void insert(long long key, int val) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return;\n            h = (h + 1) & (SIZE - 1);\n        }\n        keys[h] = key;\n        values[h] = val;\n    }\n    int query(long long key) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return values[h];\n            h = (h + 1) & (SIZE - 1);\n        }\n        return -1;\n    }\n} id_map;\n\n// Packing string into 64-bit long long: 3 bits per char (up to 12 chars) + 4 bits for length\nlong long pack(const string& str) {\n    long long res = 0;\n    for (char ch : str) res = (res << 3) | (ch - 'A');\n    return (res << 4) | (long long)str.length();\n}\n\n// Function to pack row substrings\ninline long long pack_row(int r, int start, int L) {\n    long long res = 0;\n    for (int k = 0; k < L; ++k) {\n        int pos = start + k;\n        if (pos >= N) pos -= N;\n        int v = A[r][pos];\n        if (v == 0) return -1;\n        res = (res << 3) | (v - 1);\n    }\n    return (res << 4) | (long long)L;\n}\n\n// Function to pack column substrings\ninline long long pack_col(int c, int start, int L) {\n    long long res = 0;\n    for (int k = 0; k < L; ++k) {\n        int pos = start + k;\n        if (pos >= N) pos -= N;\n        int v = A[pos][c];\n        if (v == 0) return -1;\n        res = (res << 3) | (v - 1);\n    }\n    return (res << 4) | (long long)L;\n}\n\n// Score function as described in the problem statement\ndouble get_score(int c, int d) {\n    if (c < M) return (double)c;\n    return (double)M * 800.0 / (800.0 - (double)d);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n_input;\n    if (!(cin >> n_input >> M)) return 0;\n\n    map<string, int> string_counts;\n    for (int i = 0; i < M; ++i) {\n        string s; cin >> s;\n        string_counts[s]++;\n    }\n\n    int k_unique = 0;\n    for (auto const& [str, weight] : string_counts) {\n        weights[k_unique] = weight;\n        id_map.insert(pack(str), k_unique);\n        k_unique++;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n\n    // Initial random matrix without '.'\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            A[i][j] = (xorshift() % 8) + 1;\n\n    // Initial evaluation of the matrix\n    memset(count_in_matrix, 0, sizeof(count_in_matrix));\n    current_c = 0;\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (int L = 2; L <= 12; ++L) {\n                long long pr = pack_row(r, c, L);\n                if (pr != -1) {\n                    int id = id_map.query(pr);\n                    if (id != -1) {\n                        if (count_in_matrix[id] == 0) current_c += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n                long long pc = pack_col(c, r, L);\n                if (pc != -1) {\n                    int id = id_map.query(pc);\n                    if (id != -1) {\n                        if (count_in_matrix[id] == 0) current_c += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n            }\n        }\n    }\n\n    current_d = 0;\n    double old_score = get_score(current_c, current_d);\n    double best_total_score = old_score;\n    memcpy(best_A, A, sizeof(A));\n\n    double T_start = 0.5;\n    double T_end = 0.01;\n    long long outer_iter = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.9) break;\n        \n        double T = T_start * pow(T_end / T_start, elapsed / 2.9);\n        \n        // Internal batch to reduce overhead of time checking and temperature calculation\n        for (int sub = 0; sub < 1024; ++sub) {\n            int r = xorshift() % N;\n            int c = xorshift() % N;\n            int old_v = A[r][c];\n            int new_v = xorshift() % 9; // 0 is '.', 1-8 are 'A'-'H'\n            if (new_v == old_v) continue;\n\n            int old_c = current_c;\n            int old_d = current_d;\n\n            // Update string counts by iterating only over substrings that contain the modified character\n            for (int L = 2; L <= 12; ++L) {\n                for (int k_idx = 0; k_idx < L; ++k_idx) {\n                    int sc = (c - k_idx + N) % N;\n                    long long pr_old = pack_row(r, sc, L);\n                    A[r][c] = new_v;\n                    long long pr_new = pack_row(r, sc, L);\n                    A[r][c] = old_v;\n\n                    if (pr_old != pr_new) {\n                        if (pr_old != -1) {\n                            int id = id_map.query(pr_old);\n                            if (id != -1) {\n                                count_in_matrix[id]--;\n                                if (count_in_matrix[id] == 0) current_c -= weights[id];\n                            }\n                        }\n                        if (pr_new != -1) {\n                            int id = id_map.query(pr_new);\n                            if (id != -1) {\n                                if (count_in_matrix[id] == 0) current_c += weights[id];\n                                count_in_matrix[id]++;\n                            }\n                        }\n                    }\n\n                    int sr = (r - k_idx + N) % N;\n                    long long pc_old = pack_col(c, sr, L);\n                    A[r][c] = new_v;\n                    long long pc_new = pack_col(c, sr, L);\n                    A[r][c] = old_v;\n\n                    if (pc_old != pc_new) {\n                        if (pc_old != -1) {\n                            int id = id_map.query(pc_old);\n                            if (id != -1) {\n                                count_in_matrix[id]--;\n                                if (count_in_matrix[id] == 0) current_c -= weights[id];\n                            }\n                        }\n                        if (pc_new != -1) {\n                            int id = id_map.query(pc_new);\n                            if (id != -1) {\n                                if (count_in_matrix[id] == 0) current_c += weights[id];\n                                count_in_matrix[id]++;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (old_v == 0) current_d--;\n            if (new_v == 0) current_d++;\n            A[r][c] = new_v;\n\n            double new_score = get_score(current_c, current_d);\n            // Accept or reject change using Simulated Annealing criteria\n            if (new_score >= old_score || (T > 0 && exp((new_score - old_score) / T) > (double)xorshift() / 4294967295.0)) {\n                old_score = new_score;\n                if (new_score > best_total_score) {\n                    best_total_score = new_score;\n                    memcpy(best_A, A, sizeof(A));\n                }\n            } else {\n                // Revert changes back to original state\n                A[r][c] = old_v;\n                current_c = old_c;\n                current_d = old_d;\n                for (int L = 2; L <= 12; ++L) {\n                    for (int k_idx = 0; k_idx < L; ++k_idx) {\n                        int sc = (c - k_idx + N) % N;\n                        long long pr_old = pack_row(r, sc, L);\n                        A[r][c] = new_v;\n                        long long pr_new = pack_row(r, sc, L);\n                        A[r][c] = old_v;\n                        if (pr_old != pr_new) {\n                            if (pr_new != -1) {\n                                int id = id_map.query(pr_new);\n                                if (id != -1) count_in_matrix[id]--;\n                            }\n                            if (pr_old != -1) {\n                                int id = id_map.query(pr_old);\n                                if (id != -1) count_in_matrix[id]++;\n                            }\n                        }\n                        int sr = (r - k_idx + N) % N;\n                        long long pc_old = pack_col(c, sr, L);\n                        A[r][c] = new_v;\n                        long long pc_new = pack_col(c, sr, L);\n                        A[r][c] = old_v;\n                        if (pc_old != pc_new) {\n                            if (pc_new != -1) {\n                                int id = id_map.query(pc_new);\n                                if (id != -1) count_in_matrix[id]--;\n                            }\n                            if (pc_old != -1) {\n                                int id = id_map.query(pc_old);\n                                if (id != -1) count_in_matrix[id]++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the final best matrix found\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (best_A[i][j] == 0) cout << '.';\n            else cout << (char)('A' + best_A[i][j] - 1);\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\nusing namespace std;\n\n// Maximum distance value representing infinity\nconst int INF = 1e9;\n\n// Structure to store square coordinates and move cost\nstruct Square {\n    int r, c, cost;\n};\n\n// Structure to store a point in the patrol route and its responsible segments\nstruct Point {\n    int id;\n    vector<int> responsible_segs;\n};\n\nint N, SI, SJ;\nvector<string> grid;\nvector<Square> roads;\nint road_idx_map[70][70];\nvector<vector<pair<int, int>>> adj;\n// Using 2D arrays for dists and parents to store all-pairs shortest paths\nint dists[4761][4761];\nshort parents[4761][4761];\n\n// Dijkstra's algorithm to calculate shortest paths from a road square\nvoid dijkstra(int start, int* d, short* p) {\n    int R = (int)roads.size();\n    for (int i = 0; i < R; ++i) d[i] = INF;\n    for (int i = 0; i < R; ++i) p[i] = -1;\n    d[start] = 0;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n    pq.push({0, start});\n    while (!pq.empty()) {\n        auto [dist_u, u] = pq.top();\n        pq.pop();\n        if (dist_u > d[u]) continue;\n        for (auto& edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            if (d[v] > d[u] + weight) {\n                d[v] = d[u] + weight;\n                p[v] = (short)u;\n                pq.push({d[v], v});\n            }\n        }\n    }\n}\n\n// Bipartite matching helper function\nbool match_dfs(int u, vector<int>& match_v, vector<bool>& visited, const vector<vector<int>>& bipartite_adj) {\n    for (int v : bipartite_adj[u]) {\n        if (!visited[v]) {\n            visited[v] = true;\n            if (match_v[v] < 0 || match_dfs(match_v[v], match_v, visited, bipartite_adj)) {\n                match_v[v] = u;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read grid size and starting point\n    if (!(cin >> N >> SI >> SJ)) return 0;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // Identify all road squares and map them to indices\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_idx_map[i][j] = (int)roads.size();\n                roads.push_back({i, j, grid[i][j] - '0'});\n            } else {\n                road_idx_map[i][j] = -1;\n            }\n        }\n    }\n\n    int R = (int)roads.size();\n    // Build adjacency list for Dijkstra's\n    adj.resize(R);\n    for (int i = 0; i < R; ++i) {\n        int r = roads[i].r, c = roads[i].c;\n        int dr[] = {-1, 1, 0, 0};\n        int dc[] = {0, 0, -1, 1};\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != '#') {\n                adj[i].push_back({road_idx_map[nr][nc], grid[nr][nc] - '0'});\n            }\n        }\n    }\n\n    // Precalculate all-pairs shortest paths among road squares\n    for (int i = 0; i < R; ++i) {\n        dijkstra(i, dists[i], parents[i]);\n    }\n\n    // Identify maximal horizontal and vertical segments\n    vector<vector<int>> horizontal_segments, vertical_segments;\n    vector<int> h_seg_of(R), v_seg_of(R);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                if (j == 0 || grid[i][j - 1] == '#') {\n                    int sid = (int)horizontal_segments.size();\n                    vector<int> seg;\n                    int k = j;\n                    while (k < N && grid[i][k] != '#') {\n                        seg.push_back(road_idx_map[i][k]);\n                        h_seg_of[road_idx_map[i][k]] = sid;\n                        k++;\n                    }\n                    horizontal_segments.push_back(seg);\n                }\n                if (i == 0 || grid[i - 1][j] == '#') {\n                    int sid = (int)vertical_segments.size();\n                    vector<int> seg;\n                    int k = i;\n                    while (k < N && grid[k][j] != '#') {\n                        seg.push_back(road_idx_map[k][j]);\n                        v_seg_of[road_idx_map[k][j]] = sid;\n                        k++;\n                    }\n                    vertical_segments.push_back(seg);\n                }\n            }\n        }\n    }\n\n    // Create a bipartite graph where nodes are segments and edges are road squares\n    int n_h = (int)horizontal_segments.size();\n    int n_v = (int)vertical_segments.size();\n    vector<vector<int>> bipartite_adj(n_h);\n    for (int i = 0; i < R; ++i) {\n        bipartite_adj[h_seg_of[i]].push_back(v_seg_of[i]);\n    }\n    for (int i = 0; i < n_h; ++i) {\n        sort(bipartite_adj[i].begin(), bipartite_adj[i].end());\n        bipartite_adj[i].erase(unique(bipartite_adj[i].begin(), bipartite_adj[i].end()), bipartite_adj[i].end());\n    }\n\n    // Find maximum matching and minimum vertex cover in the bipartite graph\n    vector<int> match_v(n_v, -1), match_h(n_h, -1);\n    for (int i = 0; i < n_h; ++i) {\n        vector<bool> visited(n_v, false);\n        match_dfs(i, match_v, visited, bipartite_adj);\n    }\n    for (int i = 0; i < n_v; ++i) if (match_v[i] != -1) match_h[match_v[i]] = i;\n\n    // Use K\u00f6nig's Theorem to find Min Vertex Cover segments\n    vector<bool> zh(n_h, false), zv(n_v, false);\n    queue<int> q;\n    for (int i = 0; i < n_h; ++i) if (match_h[i] == -1) { zh[i] = true; q.push(i); }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : bipartite_adj[u]) {\n            if (!zv[v]) {\n                zv[v] = true;\n                int n_h_nxt = match_v[v];\n                if (n_h_nxt != -1 && !zh[n_h_nxt]) { zh[n_h_nxt] = true; q.push(n_h_nxt); }\n            }\n        }\n    }\n    vector<int> min_vertex_cover;\n    vector<bool> is_in_mvc(n_h + n_v, false);\n    for (int i = 0; i < n_h; ++i) if (!zh[i]) { min_vertex_cover.push_back(i); is_in_mvc[i] = true; }\n    for (int i = 0; i < n_v; ++i) if (zv[i]) { min_vertex_cover.push_back(n_h + i); is_in_mvc[n_h + i] = true; }\n\n    // Greedy square selection to cover all segments in the minimum vertex cover\n    vector<Point> P;\n    int start_node = road_idx_map[SI][SJ];\n    P.push_back({start_node, {}});\n    vector<bool> seg_covered(n_h + n_v, false);\n    if (is_in_mvc[h_seg_of[start_node]]) seg_covered[h_seg_of[start_node]] = true;\n    if (is_in_mvc[n_h + v_seg_of[start_node]]) seg_covered[n_h + v_seg_of[start_node]] = true;\n\n    int cur_p = start_node;\n    while (true) {\n        int uncovered_count = 0;\n        for (int s : min_vertex_cover) if (!seg_covered[s]) uncovered_count++;\n        if (uncovered_count == 0) break;\n\n        int best_p = -1, max_new = 0, min_d = INF;\n        vector<int> best_segs;\n        for (int i = 0; i < R; ++i) {\n            vector<int> new_segs;\n            if (is_in_mvc[h_seg_of[i]] && !seg_covered[h_seg_of[i]]) new_segs.push_back(h_seg_of[i]);\n            if (is_in_mvc[n_h + v_seg_of[i]] && !seg_covered[n_h + v_seg_of[i]]) new_segs.push_back(n_h + v_seg_of[i]);\n            \n            int num_new = (int)new_segs.size();\n            if (num_new > max_new || (num_new == max_new && num_new > 0 && dists[cur_p][i] < min_d)) {\n                max_new = num_new; min_d = dists[cur_p][i]; best_p = i; best_segs = new_segs;\n            }\n        }\n        if (best_p == -1) break;\n        P.push_back({best_p, best_segs});\n        for (int s : best_segs) seg_covered[s] = true;\n        cur_p = best_p;\n    }\n\n    // Path improvement using 2-opt TSP heuristic and square refinement\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 1; i < (int)P.size(); ++i) {\n            for (int j = i + 1; j < (int)P.size(); ++j) {\n                int d_before = dists[P[i - 1].id][P[i].id] + dists[P[j].id][P[(j + 1) % P.size()].id];\n                int d_after = dists[P[i - 1].id][P[j].id] + dists[P[i].id][P[(j + 1) % P.size()].id];\n                if (d_after < d_before) { reverse(P.begin() + i, P.begin() + j + 1); improved = true; }\n            }\n        }\n        for (int i = 1; i < (int)P.size(); ++i) {\n            if (P[i].responsible_segs.size() == 1) {\n                int seg = P[i].responsible_segs[0];\n                const vector<int>& options = (seg < n_h) ? horizontal_segments[seg] : vertical_segments[seg - n_h];\n                int best_p_in_seg = P[i].id;\n                int min_d = dists[P[i - 1].id][P[i].id] + dists[P[i].id][P[(i + 1) % P.size()].id];\n                for (int p_new : options) {\n                    int d = dists[P[i - 1].id][p_new] + dists[p_new][P[(i + 1) % P.size()].id];\n                    if (d < min_d) { min_d = d; best_p_in_seg = p_new; }\n                }\n                if (best_p_in_seg != P[i].id) { P[i].id = best_p_in_seg; improved = true; }\n            }\n        }\n    }\n\n    // Construct and output the final movement string\n    string final_path = \"\";\n    auto get_char_dir = [&](int u, int v) {\n        int r1 = roads[u].r, c1 = roads[u].c, r2 = roads[v].r, c2 = roads[v].c;\n        if (r2 == r1 - 1) return 'U'; if (r2 == r1 + 1) return 'D';\n        if (c2 == c1 - 1) return 'L'; if (c2 == c1 + 1) return 'R';\n        return ' ';\n    };\n\n    for (int i = 0; i < P.size(); ++i) {\n        int st = P[i].id, en = P[(i + 1) % P.size()].id;\n        string sub = \"\";\n        int cn = en;\n        while (cn != st) {\n            int pn = parents[st][cn];\n            sub += get_char_dir(pn, cn);\n            cn = pn;\n        }\n        reverse(sub.begin(), sub.end());\n        final_path += sub;\n    }\n\n    cout << final_path << endl;\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\n// Standard constant values from the problem statement\nconst int MAX_DAYS = 2000;\nconst int N_TASKS = 1000;\nconst int M_MEMBERS = 20;\n\nstruct Task {\n    int id;\n    vector<int> d;\n    vector<int> deps;\n    vector<int> rev_deps;\n    int height;\n    int descendants;\n    int status; // -1: not ready, 0: ready, 1: ongoing, 2: completed\n};\n\nstruct Member {\n    int id;\n    vector<double> s;\n    int current_task;\n    int start_day;\n    struct History {\n        vector<int> d;\n        int t;\n    };\n    vector<History> history;\n};\n\nint N, M, K, R;\nvector<Task> tasks;\nvector<Member> members;\n\n// Calculate heights of the tasks based on dependencies to find critical path\nvoid calculate_heights() {\n    for (int i = 0; i < N; ++i) tasks[i].height = 0;\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; ++i) out_degree[i] = (int)tasks[i].rev_deps.size();\n    vector<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (out_degree[i] == 0) {\n            q.push_back(i);\n            tasks[i].height = 1;\n        }\n    }\n    int head = 0;\n    while(head < (int)q.size()){\n        int v = q[head++];\n        for(int u : tasks[v].deps){\n            tasks[u].height = max(tasks[u].height, tasks[v].height + 1);\n            if(--out_degree[u] == 0) q.push_back(u);\n        }\n    }\n}\n\n// Calculate the number of tasks in the dependency subtree rooted at each task\nvoid calculate_descendants() {\n    for (int i = 0; i < N; ++i) {\n        vector<bool> visited(N, false);\n        vector<int> q;\n        q.push_back(i);\n        visited[i] = true;\n        int count = 0;\n        int head = 0;\n        while(head < (int)q.size()){\n            int v = q[head++];\n            for(int next_v : tasks[v].rev_deps){\n                if(!visited[next_v]){\n                    visited[next_v] = true;\n                    q.push_back(next_v);\n                    count++;\n                }\n            }\n        }\n        tasks[i].descendants = count;\n    }\n}\n\n// Helper to calculate estimated difficulty based on current skill level estimates\ndouble get_w(const vector<double>& s, const vector<int>& d) {\n    double w = 0;\n    for (int k = 0; k < K; ++k) w += max(0.0, (double)d[k] - s[k]);\n    return w;\n}\n\n// Calculate the expected number of days for completion based on w_i,j and the random range r_i\ndouble expected_duration(double w) {\n    if (w <= 0) return 1.0;\n    double sum = 0;\n    for (int r = -3; r <= 3; ++r) sum += max(1.0, w + (double)r);\n    return sum / 7.0;\n}\n\n// Use a simple gradient-based update to estimate a team member's skill levels\nvoid update_skills(int m_idx) {\n    auto& m = members[m_idx];\n    if (m.history.empty()) return;\n    for (int iter = 0; iter < 500; ++iter) {\n        double eta = 0.01; // Learning rate\n        for (const auto& h : m.history) {\n            double w = get_w(m.s, h.d);\n            double diff = 0;\n            // The actual duration provides a noisy estimate of w\n            if (h.t > 1) diff = (double)h.t - w;\n            else if (w > 2.0) diff = 2.0 - w; // Durations of 1 day imply w is likely small\n            \n            if (abs(diff) < 1e-6) continue;\n            for (int k = 0; k < K; ++k) {\n                if (h.d[k] > m.s[k]) m.s[k] -= eta * diff;\n            }\n        }\n        for (int k = 0; k < K; ++k) m.s[k] = max(0.0, m.s[k]);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    tasks.resize(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].id = i;\n        tasks[i].d.resize(K);\n        for (int k = 0; k < K; ++k) cin >> tasks[i].d[k];\n        tasks[i].status = -1;\n    }\n    \n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        tasks[v].deps.push_back(u);\n        tasks[u].rev_deps.push_back(v);\n    }\n    \n    calculate_heights();\n    calculate_descendants();\n    \n    members.resize(M);\n    for (int j = 0; j < M; ++j) {\n        members[j].id = j;\n        // Standard initialization for skill levels based on generation distribution\n        members[j].s.assign(K, 40.0 / sqrt((double)K));\n        members[j].current_task = -1;\n    }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        // Check for newly available tasks\n        for (int i = 0; i < N; ++i) {\n            if (tasks[i].status == -1) {\n                bool ok = true;\n                for (int dep : tasks[i].deps) {\n                    if (tasks[dep].status != 2) { ok = false; break; }\n                }\n                if (ok) tasks[i].status = 0;\n            }\n        }\n        \n        vector<int> idle_members, ready_tasks;\n        for (int j = 0; j < M; ++j) if (members[j].current_task == -1) idle_members.push_back(j);\n        for (int i = 0; i < N; ++i) if (tasks[i].status == 0) ready_tasks.push_back(i);\n        \n        vector<pair<int, int>> assignments;\n        vector<bool> task_assigned(N, false), member_assigned(M, false);\n        \n        // Greedily match idle members to available tasks using a priority score\n        while (true) {\n            int best_m = -1, best_t = -1;\n            double max_score = -1e18;\n            for (int j : idle_members) {\n                if (member_assigned[j]) continue;\n                for (int i : ready_tasks) {\n                    if (task_assigned[i]) continue;\n                    double w_est = get_w(members[j].s, tasks[i].d);\n                    // Prioritize tasks on the critical path that the member can complete quickly\n                    double score = (tasks[i].height * 1000.0 + (double)tasks[i].descendants) / expected_duration(w_est);\n                    if (score > max_score) { max_score = score; best_m = j; best_t = i; }\n                }\n            }\n            if (best_m == -1) break;\n            \n            assignments.push_back({best_m, best_t});\n            task_assigned[best_t] = true; member_assigned[best_m] = true;\n            tasks[best_t].status = 1;\n            members[best_m].current_task = best_t;\n            members[best_m].start_day = current_day;\n        }\n        \n        // Output task assignments for the current day\n        cout << (int)assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        cout << endl;\n        \n        // Read input from the judge about which tasks were finished\n        int n_completed;\n        if (!(cin >> n_completed) || n_completed == -1) break;\n        for (int i = 0; i < n_completed; ++i) {\n            int m_id; cin >> m_id; --m_id;\n            int t_idx = members[m_id].current_task;\n            int duration = current_day - members[m_id].start_day + 1;\n            // Record the completion to refine our estimates of the team member's skills\n            members[m_id].history.push_back({tasks[t_idx].d, duration});\n            tasks[t_idx].status = 2; \n            members[m_id].current_task = -1;\n            update_skills(m_id);\n        }\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// Order information and state arrays\nint orders_a[1000], orders_b[1000], orders_c[1000], orders_d[1000];\nint order_in_s[50];\nbool in_s[1000];\nint route[102];\nint pos[101]; // position of point index 0-99 in route\nint cur_x[101], cur_y[101]; // coords of point 0-99, and point 100 is the office (400, 400)\n\n// Calculate Manhattan distance between two points by their index in cur_x/cur_y\ninline int dist_points(int p1, int p2) {\n    return abs(cur_x[p1] - cur_x[p2]) + abs(cur_y[p1] - cur_y[p2]);\n}\n\n// Calculate Manhattan distance between a route index and specific coordinates\ninline int dist_to_coord(int r_idx, int x, int y) {\n    return abs(cur_x[route[r_idx]] - x) + abs(cur_y[route[r_idx]] - y);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read 1000 orders\n    for (int i = 0; i < 1000; i++) {\n        if (!(cin >> orders_a[i] >> orders_b[i] >> orders_c[i] >> orders_d[i])) break;\n    }\n\n    // Heuristic: Pick a pool of candidates closest to the office center (400, 400)\n    vector<pair<int, int>> pool_candidates;\n    for (int i = 0; i < 1000; i++) {\n        int d = abs(orders_a[i] - 400) + abs(orders_b[i] - 400) + abs(orders_c[i] - 400) + abs(orders_d[i] - 400);\n        pool_candidates.push_back({d, i});\n    }\n    sort(pool_candidates.begin(), pool_candidates.end());\n\n    // Use a subset of size 400 for selection\n    int pool_size = 400;\n    vector<int> pool;\n    for (int i = 0; i < pool_size; i++) {\n        pool.push_back(pool_candidates[i].second);\n    }\n\n    // Initialize chosen orders S with the first 50 closest orders\n    for (int i = 0; i < 50; i++) {\n        int order_idx = pool[i];\n        order_in_s[i] = order_idx;\n        in_s[order_idx] = true;\n        cur_x[i] = orders_a[order_idx];      // Pickup coordinate x\n        cur_y[i] = orders_b[order_idx];      // Pickup coordinate y\n        cur_x[i + 50] = orders_c[order_idx]; // Delivery coordinate x\n        cur_y[i + 50] = orders_d[order_idx]; // Delivery coordinate y\n    }\n    cur_x[100] = 400; cur_y[100] = 400; // Office coordinate\n\n    // Build an initial route using a Greedy Pickup-Delivery heuristic\n    int current_x = 400, current_y = 400;\n    vector<bool> visited_p(100, false);\n    route[0] = 100; route[101] = 100;\n    for (int step = 1; step <= 100; step++) {\n        int best_dist = 1e9, best_p = -1;\n        for (int p = 0; p < 100; p++) {\n            if (visited_p[p]) continue;\n            if (p >= 50 && !visited_p[p - 50]) continue; // Cannot deliver before pickup\n            int d = abs(current_x - cur_x[p]) + abs(current_y - cur_y[p]);\n            if (d < best_dist) { best_dist = d; best_p = p; }\n        }\n        route[step] = best_p;\n        pos[best_p] = step;\n        visited_p[best_p] = true;\n        current_x = cur_x[best_p]; current_y = cur_y[best_p];\n    }\n\n    // Initial total travel time\n    int current_t = 0;\n    for (int i = 0; i <= 100; i++) {\n        current_t += dist_points(route[i], route[i+1]);\n    }\n\n    // Simulated Annealing setup\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double t_start = 30.0, t_end = 0.1;\n    long long total_iter = 0;\n\n    while (true) {\n        // Limit total execution time to 1.96 seconds\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.96) break;\n\n        double progress = elapsed / 1.96;\n        double temp = t_start * pow(t_end / t_start, progress);\n\n        // Perform chunks of iterations\n        for (int j = 0; j < 2000; j++) {\n            int move_type = rng() % 100;\n\n            if (move_type < 45) { // Relocate point Move\n                int i = 1 + rng() % 100;\n                int k_pos = 1 + rng() % 100;\n                if (i == k_pos) continue;\n\n                int vi = route[i];\n                // Precedence Constraint Check\n                if (vi < 50) { if (i < k_pos && k_pos >= pos[vi + 50]) continue; }\n                else { if (i > k_pos && k_pos <= pos[vi - 50]) continue; }\n\n                // Distance Delta Calculation\n                int d_before, d_after;\n                if (i < k_pos) {\n                    d_before = dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]) + dist_points(route[k_pos], route[k_pos+1]);\n                    d_after = dist_points(route[i-1], route[i+1]) + dist_points(route[k_pos], route[i]) + dist_points(route[i], route[k_pos+1]);\n                } else {\n                    d_before = dist_points(route[k_pos-1], route[k_pos]) + dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]);\n                    d_after = dist_points(route[k_pos-1], route[i]) + dist_points(route[i], route[k_pos]) + dist_points(route[i-1], route[i+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    int v = route[i];\n                    if (i < k_pos) {\n                        for (int k = i; k < k_pos; k++) { route[k] = route[k+1]; pos[route[k]] = k; }\n                    } else {\n                        for (int k = i; k > k_pos; k--) { route[k] = route[k-1]; pos[route[k]] = k; }\n                    }\n                    route[k_pos] = v; pos[v] = k_pos;\n                }\n            } else if (move_type < 90) { // Swap two points Move\n                int i = 1 + rng() % 100;\n                int j = 1 + rng() % 100;\n                if (i == j) continue;\n                int vi = route[i], vj = route[j];\n\n                // Precedence Constraint Check\n                if (vi < 50) { if (j >= pos[vi + 50]) continue; }\n                else { if (j <= pos[vi - 50]) continue; }\n                if (vj < 50) { if (i >= pos[vj + 50]) continue; }\n                else { if (i <= pos[vj - 50]) continue; }\n\n                int d_before, d_after;\n                int i_low = min(i, j), i_high = max(i, j);\n                if (i_high == i_low + 1) {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                } else {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_low+1]) +\n                               dist_points(route[i_high-1], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low+1]) +\n                              dist_points(route[i_high-1], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    swap(route[i], route[j]);\n                    pos[route[i]] = i; pos[route[j]] = j;\n                }\n            } else { // Replace one order in S Move\n                int k = rng() % 50;\n                int old_idx = order_in_s[k];\n                int new_idx = pool[rng() % pool_size];\n                if (in_s[new_idx]) continue;\n\n                int pk_pos = pos[k], dk_pos = pos[k+50];\n                int nax = orders_a[new_idx], nay = orders_b[new_idx], ncx = orders_c[new_idx], ncy = orders_d[new_idx];\n\n                int d_before = dist_points(route[pk_pos-1], k) + dist_points(k, route[pk_pos+1]) +\n                               dist_points(route[dk_pos-1], k+50) + dist_points(k+50, route[dk_pos+1]);\n                if (pk_pos + 1 == dk_pos) {\n                    d_before = dist_points(route[pk_pos-1], k) + dist_points(k, k+50) + dist_points(k+50, route[dk_pos+1]);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_before = dist_points(route[dk_pos-1], k+50) + dist_points(k+50, k) + dist_points(k, route[pk_pos+1]);\n                }\n\n                int d_after = dist_to_coord(pk_pos-1, nax, nay) + dist_to_coord(pk_pos+1, nax, nay) +\n                              dist_to_coord(dk_pos-1, ncx, ncy) + dist_to_coord(dk_pos+1, ncx, ncy);\n                if (pk_pos + 1 == dk_pos) {\n                    d_after = dist_to_coord(pk_pos-1, nax, nay) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(dk_pos+1, ncx, ncy);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_after = dist_to_coord(dk_pos-1, ncx, ncy) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(pk_pos+1, nax, nay);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    in_s[old_idx] = false; in_s[new_idx] = true;\n                    order_in_s[k] = new_idx;\n                    cur_x[k] = nax; cur_y[k] = nay;\n                    cur_x[k+50] = ncx; cur_y[k+50] = ncy;\n                }\n            }\n        }\n        total_iter++;\n    }\n\n    // Final Output: Number of orders and their 1-indexed IDs\n    cout << 50;\n    for (int i = 0; i < 50; i++) cout << \" \" << order_in_s[i] + 1;\n    cout << \"\\n\";\n\n    // Final Output: Route coordinates (start office, pickups/deliveries, end office)\n    cout << 102;\n    for (int i = 0; i <= 101; i++) {\n        int x, y;\n        if (i == 0 || i == 101) { x = 400; y = 400; }\n        else {\n            int p = route[i];\n            if (p < 50) { x = orders_a[order_in_s[p]]; y = orders_b[order_in_s[p]]; }\n            else { x = orders_c[order_in_s[p - 50]]; y = orders_d[order_in_s[p - 50]]; }\n        }\n        cout << \" \" << x << \" \" << y;\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <cstring>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) structure to maintain connectivity between offices.\nstruct DSU {\n    int parent[400];\n    DSU() {\n        // Initialize parent for each office to itself.\n        for (int i = 0; i < 400; ++i) parent[i] = i;\n    }\n    // Find with path compression for efficient connectivity checks.\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    // Unite two components if they are not already connected.\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) parent[root_i] = root_j;\n    }\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 = 400, M = 1995;\n    vector<int> x(N), y(N);\n    // Read coordinates of each vertex.\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> x[i] >> y[i])) break;\n    }\n\n    vector<int> u(M), v(M), d(M);\n    // Read edge candidates and calculate Euclidean distances.\n    for (int i = 0; i < M; ++i) {\n        if (!(cin >> u[i] >> v[i])) break;\n        double dist = sqrt(pow((double)x[u[i]] - x[v[i]], 2) + pow((double)y[u[i]] - y[v[i]], 2));\n        d[i] = (int)round(dist);\n    }\n\n    // Monte Carlo simulation settings.\n    const int K = 400; \n    mt19937 rng(42);\n    // Pre-sample weights for future edges across all scenarios.\n    // Each scenario k represents one possible set of real weights for edges i..M-1.\n    vector<int> pre_sampled_l(M * K);\n    for (int j = 0; j < M; ++j) {\n        for (int k = 0; k < K; ++k) {\n            // Weights are uniformly distributed between d_j and 3*d_j.\n            pre_sampled_l[j * K + k] = d[j] + (int)(rng() % (2 * d[j] + 1));\n        }\n    }\n\n    // dsu_base maintains the current connectivity from already adopted lines.\n    DSU dsu_base;\n    DSU dsu_sim;\n    vector<int> root_u(M), root_v(M);\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n\n        // Current endpoints of edge i in the base connectivity.\n        int root_ui = dsu_base.find(u[i]);\n        int root_vi = dsu_base.find(v[i]);\n\n        // If vertices u_i and v_i are already connected, edge i is redundant.\n        if (root_ui == root_vi) {\n            cout << 0 << endl; // No need to flush manually; endl flushes.\n            continue;\n        }\n\n        // Pre-calculate current component roots to speed up the DSU in inner simulation loop.\n        for (int j = i; j < M; ++j) {\n            root_u[j] = dsu_base.find(u[j]);\n            root_v[j] = dsu_base.find(v[j]);\n        }\n\n        int count = 0;\n        // Simulation: in each scenario, determine if picking edge i is part of the MST.\n        // Property: Edge i is in the MST iff its endpoints aren't connected by edges with lower weights.\n        for (int k = 0; k < K; ++k) {\n            // Clone the current connectivity state.\n            memcpy(dsu_sim.parent, dsu_base.parent, sizeof(dsu_base.parent));\n            \n            for (int j = i + 1; j < M; ++j) {\n                // If a future edge j has a smaller expected weight than l_i, we consider it.\n                if (root_u[j] != root_v[j] && pre_sampled_l[j * K + k] < l_i) {\n                    dsu_sim.unite(root_u[j], root_v[j]);\n                }\n            }\n            // Check if scenario's cheaper future edges made endpoints of i connected.\n            if (dsu_sim.find(root_u[i]) != dsu_sim.find(root_v[i])) {\n                count++;\n            }\n        }\n\n        // Decision rule: Adopt edge i if it is useful in more than half of the simulated scenarios.\n        // This naturally handles bridge edges (where count will be K).\n        if (count > K / 2) {\n            dsu_base.unite(root_ui, root_vi);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int TURNS = 300;\n\nstruct Pet {\n    int x, y, type;\n};\n\nstruct Human {\n    int x, y;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool is_blocked[GRID_SIZE + 1][GRID_SIZE + 1];\n\nstruct Target {\n    int x, y;\n    bool is_vertical;\n    int corridor_idx;\n};\n\nvector<Target> all_targets;\n\n// Check if any pet is in or adjacent to (x, y)\nbool is_pet_adjacent(int x, int y) {\n    if (x < 1 || x > GRID_SIZE || y < 1 || y > GRID_SIZE) return false;\n    for (const auto& pet : pets) {\n        if (abs(pet.x - x) + abs(pet.y - y) <= 1) return true;\n    }\n    return false;\n}\n\n// Check if any human is currently at (x, y)\nbool is_human_at(int x, int y) {\n    for (const auto& h : humans) {\n        if (h.x == x && h.y == y) return true;\n    }\n    return false;\n}\n\n// BFS to find the first move in the shortest path to (dest_x, dest_y)\nstring bfs_move(int start_x, int start_y, int dest_x, int dest_y, bool avoid_targets) {\n    if (start_x == dest_x && start_y == dest_y) return \".\";\n    queue<pair<int, int>> q;\n    q.push({start_x, start_y});\n    vector<vector<int>> dist(GRID_SIZE + 1, vector<int>(GRID_SIZE + 1, -1));\n    vector<vector<char>> parent(GRID_SIZE + 1, vector<char>(GRID_SIZE + 1, 0));\n    dist[start_x][start_y] = 0;\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    char move_char[] = {'U', 'D', 'L', 'R'};\n    while (!q.empty()) {\n        pair<int, int> curr = q.front(); q.pop();\n        if (curr.first == dest_x && curr.second == dest_y) {\n            int cx = dest_x, cy = dest_y;\n            char m = '.';\n            while (cx != start_x || cy != start_y) {\n                m = parent[cx][cy];\n                if (m == 'U') cx++; else if (m == 'D') cx--; else if (m == 'L') cy++; else if (m == 'R') cy--;\n            }\n            return string(1, m);\n        }\n        for (int i = 0; i < 4; i++) {\n            int nx = curr.first + dx[i], ny = curr.second + dy[i];\n            if (nx >= 1 && nx <= GRID_SIZE && ny >= 1 && ny <= GRID_SIZE && !is_blocked[nx][ny] && dist[nx][ny] == -1) {\n                bool is_target = false;\n                if (avoid_targets) {\n                    for (const auto& t : all_targets) {\n                        if (t.x == nx && t.y == ny && !is_blocked[nx][ny]) { is_target = true; break; }\n                    }\n                }\n                if (!is_target) {\n                    dist[nx][ny] = dist[curr.first][curr.second] + 1;\n                    parent[nx][ny] = move_char[i];\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n    // Retry BFS without avoiding unblocked target squares if no path found\n    if (avoid_targets) return bfs_move(start_x, start_y, dest_x, dest_y, false);\n    return \".\";\n}\n\n// Moves to a square adjacent to the target (tx, ty)\nstring move_to_adjacent(int hx, int hy, int tx, int ty) {\n    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    int min_d = 1000, bax = -1, bay = -1;\n    for (int i = 0; i < 4; i++) {\n        int ax = tx + dx[i], ay = ty + dy[i];\n        if (ax >= 1 && ax <= GRID_SIZE && ay >= 1 && ay <= GRID_SIZE && !is_blocked[ax][ay]) {\n            int d = abs(hx - ax) + abs(hy - ay);\n            if (d < min_d) { min_d = d; bax = ax; bay = ay; }\n        }\n    }\n    if (bax != -1) return bfs_move(hx, hy, bax, bay, true);\n    return \".\";\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N)) return 0;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) cin >> humans[i].x >> humans[i].y;\n\n    // Define vertical walls targets (every 3rd column, except for column 15)\n    for (int j = 1; j <= 9; j++) for (int x = 1; x <= 30; x++) if (x != 15) all_targets.push_back({x, j * 3, true, j});\n    // Define horizontal walls targets (2 per corridor, except column 15)\n    for (int j = 1; j <= 9; j++) {\n        for (int x = 1; x <= 14; x++) { all_targets.push_back({x, 3 * j - 2, false, j}); all_targets.push_back({x, 3 * j - 1, false, j}); }\n        for (int x = 30; x >= 16; x--) { all_targets.push_back({x, 3 * j - 2, false, j}); all_targets.push_back({x, 3 * j - 1, false, j}); }\n    }\n\n    vector<bool> gate_taken(10, false);\n    for (int t = 0; t < TURNS; t++) {\n        string actions = \"\";\n        vector<bool> target_taken(all_targets.size(), false);\n        for (int i = 0; i < M; i++) {\n            // Check if any pet-free gate can be closed\n            int best_gate = -1;\n            for (int j = 9; j >= 1; j--) {\n                int gx = 15, gy = 3 * j;\n                if (is_blocked[gx][gy] || gate_taken[j]) continue;\n                bool safe = true;\n                for (const auto& p : pets) if (p.y <= gy) { safe = false; break; }\n                if (safe) { best_gate = j; break; }\n            }\n            if (best_gate != -1) {\n                gate_taken[best_gate] = true;\n                int gx = 15, gy = 3 * best_gate;\n                if (abs(humans[i].x - gx) + abs(humans[i].y - gy) == 1) {\n                    if (!is_pet_adjacent(gx, gy) && !is_human_at(gx, gy)) {\n                        if (gx < humans[i].x) actions += 'u'; else if (gx > humans[i].x) actions += 'd';\n                        else if (gy < humans[i].y) actions += 'l'; else actions += 'r';\n                        is_blocked[gx][gy] = true;\n                    } else { actions += \".\"; gate_taken[best_gate] = false; }\n                } else actions += move_to_adjacent(humans[i].x, humans[i].y, gx, gy);\n                continue;\n            }\n\n            // Otherwise, find the best wall-building target\n            int best_t = -1, min_d = 1000;\n            for (int ti = 0; ti < (int)all_targets.size(); ti++) {\n                const auto& tg = all_targets[ti];\n                if (is_blocked[tg.x][tg.y] || target_taken[ti]) continue;\n                if (!tg.is_vertical) { // Horizontal target: must push pets to column 15\n                    bool pushed = true;\n                    if (tg.x < 15) {\n                        for (const auto& p : pets) if ((p.y == 3 * tg.corridor_idx - 2 || p.y == 3 * tg.corridor_idx - 1) && p.x <= tg.x) { pushed = false; break; }\n                        if (pushed) for (int xp = 1; xp < tg.x; xp++) if (!is_blocked[xp][tg.y]) { pushed = false; break; }\n                    } else {\n                        for (const auto& p : pets) if ((p.y == 3 * tg.corridor_idx - 2 || p.y == 3 * tg.corridor_idx - 1) && p.x >= tg.x) { pushed = false; break; }\n                        if (pushed) for (int xp = 30; xp > tg.x; xp--) if (!is_blocked[xp][tg.y]) { pushed = false; break; }\n                    }\n                    if (!pushed) continue;\n                }\n                int d = abs(humans[i].x - tg.x) + abs(humans[i].y - tg.y);\n                if (d < min_d) { min_d = d; best_t = ti; }\n            }\n            if (best_t != -1) {\n                target_taken[best_t] = true;\n                int tx = all_targets[best_t].x, ty = all_targets[best_t].y;\n                if (abs(humans[i].x - tx) + abs(humans[i].y - ty) == 1) {\n                    if (!is_pet_adjacent(tx, ty) && !is_human_at(tx, ty)) {\n                        if (tx < humans[i].x) actions += 'u'; else if (tx > humans[i].x) actions += 'd';\n                        else if (ty < humans[i].y) actions += 'l'; else actions += 'r';\n                        is_blocked[tx][ty] = true;\n                    } else { actions += \".\"; target_taken[best_t] = false; }\n                } else actions += move_to_adjacent(humans[i].x, humans[i].y, tx, ty);\n            } else actions += bfs_move(humans[i].x, humans[i].y, 1, 15, true);\n        }\n\n        // Apply actions and read pet movements\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--; else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--; else if (actions[i] == 'R') humans[i].y++;\n        }\n        cout << actions << endl;\n        for (int i = 0; i < N; i++) {\n            string pm; cin >> pm;\n            for (char c : pm) {\n                if (c == 'U') pets[i].x--; else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--; else if (c == 'R') pets[i].y++;\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\nusing namespace std;\n\n/**\n * Problem Summary:\n * We want to find a string of movements (U, D, L, R) of length <= 200 that maximizes the \n * expected score E[S], where S = 401 - t if Takahashi reaches the target at time t, \n * and 0 otherwise. Movement fails with probability p.\n * \n * Algorithm:\n * - Use Beam Search to build the string step by step (turn k=1 up to 200).\n * - Keep a probability distribution of Takahashi's current position for each state in the beam.\n * - Evaluation function for Beam Search: \n *      Score = (expected score accumulated so far) + (estimated future expected score).\n * - Estimate future expected score by assuming Takahashi follows a shortest path to the target.\n */\n\nint si, sj, ti, tj;\ndouble p_prob_val;\nvector<string> h_wall(20), v_wall(19);\nint dist_to_target[20][20];\nint di[] = {-1, 1, 0, 0}; // U, D, L, R directions\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (i, j) in a given direction is possible (no walls)\nbool can_move(int i, int j, int dir) {\n    if (dir == 0) { // Up\n        if (i > 0 && v_wall[i - 1][j] == '0') return true;\n    } else if (dir == 1) { // Down\n        if (i < 19 && v_wall[i][j] == '0') return true;\n    } else if (dir == 2) { // Left\n        if (j > 0 && h_wall[i][j - 1] == '0') return true;\n    } else if (dir == 3) { // Right\n        if (j < 19 && h_wall[i][j] == '0') return true;\n    }\n    return false;\n}\n\n// Compute shortest distance from every square to the target (ti, tj) using BFS\nvoid bfs_target_dist() {\n    for (int i = 0; i < 20; ++i)\n        for (int j = 0; j < 20; ++j)\n            dist_to_target[i][j] = 999;\n    dist_to_target[ti][tj] = 0;\n    queue<pair<int, int>> q;\n    q.push({ti, tj});\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = r + di[dir];\n            int nj = c + dj[dir];\n            // Since the grid structure is symmetric, if we can move ni, nj -> r, c,\n            // then r, c -> ni, nj must be walkable (checking direction based on neighbors)\n            int opp_dir = -1;\n            if (dir == 0) opp_dir = 1; \n            else if (dir == 1) opp_dir = 0;\n            else if (dir == 2) opp_dir = 3;\n            else if (dir == 3) opp_dir = 2;\n            \n            if (ni >= 0 && ni < 20 && nj >= 0 && nj < 20 && can_move(ni, nj, opp_dir)) {\n                if (dist_to_target[ni][nj] == 999) {\n                    dist_to_target[ni][nj] = dist_to_target[r][c] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n}\n\n// Precompute probabilities for the heuristic function\ndouble P_mat[401][201];\ndouble W_mat[401][201];\ndouble G_prime_mat[401][201];\ndouble H_precomputed[1000][201];\n\nvoid precompute_scoring() {\n    double lp = log(p_prob_val);\n    double l1p = log(1.0 - p_prob_val);\n    for (int d = 1; d <= 400; ++d) {\n        for (int t = 1; t <= 200; ++t) {\n            if (t < d) {\n                P_mat[d][t] = 0;\n            } else {\n                // Prob(d-th success occurs at turn t) = C(t-1, d-1) * (1-p)^d * p^(t-d)\n                double log_comb = lgamma(t) - lgamma(d) - lgamma(t - d + 1);\n                P_mat[d][t] = exp(log_comb + d * l1p + (t - d) * lp);\n            }\n        }\n        W_mat[d][0] = 0;\n        G_prime_mat[d][0] = 0;\n        for (int rem = 1; rem <= 200; ++rem) {\n            W_mat[d][rem] = W_mat[d][rem - 1] + P_mat[d][rem];\n            G_prime_mat[d][rem] = G_prime_mat[d][rem - 1] + (double)rem * P_mat[d][rem];\n        }\n    }\n    // H_precomputed[d][k] estimates the expected future score for reaching target from distance d starting at turn k\n    for (int d = 1; d <= 400; ++d) {\n        for (int k = 0; k <= 200; ++k) {\n            int rem_len = 200 - k;\n            H_precomputed[d][k] = (401.0 - (double)k) * W_mat[d][rem_len] - G_prime_mat[d][rem_len];\n        }\n    }\n    for (int d = 401; d < 1000; d++) {\n        for (int k = 0; k <= 200; k++) H_precomputed[d][k] = 0;\n    }\n}\n\n// Beam Search state\nstruct State {\n    string s;\n    double P[20][20]; // Probability distribution of Takahashi's location\n    double current_E_S; // Expected score accumulated up to turn k\n    double score; // Evaluate function (current_E_S + future heuristic)\n\n    State() : current_E_S(0), score(0), s(\"\") {\n        for (int i = 0; i < 20; ++i)\n            for (int j = 0; j < 20; ++j)\n                P[i][j] = 0;\n    }\n\n    bool operator<(const State& other) const {\n        return score > other.score; // Higher score ranks first\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input data\n    if (!(cin >> si >> sj >> ti >> tj >> p_prob_val)) return 0;\n    for (int i = 0; i < 20; ++i) cin >> h_wall[i];\n    for (int i = 0; i < 19; ++i) cin >> v_wall[i];\n\n    // Initialize BFS distances and precompute scoring tables\n    bfs_target_dist();\n    precompute_scoring();\n\n    vector<State> current_beam;\n    State initial_state;\n    initial_state.P[si][sj] = 1.0;\n    initial_state.s = \"\";\n    initial_state.current_E_S = 0;\n    initial_state.score = H_precomputed[dist_to_target[si][sj]][0];\n    current_beam.push_back(initial_state);\n\n    const int B = 100; // Beam width\n\n    // Extend the movement string turn by turn\n    for (int k = 1; k <= 200; ++k) {\n        vector<State> next_beam;\n        next_beam.reserve(current_beam.size() * 4);\n        for (const auto& state : current_beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                State next_state;\n                next_state.s = state.s + dc[dir];\n                double prob_reached_this_step = 0;\n                \n                // Transition probability distribution based on movement in 'dir'\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (i == ti && j == tj) continue; // Office is a sink\n                        double p_val = state.P[i][j];\n                        if (p_val < 1e-16) continue;\n\n                        if (can_move(i, j, dir)) {\n                            int ni = i + di[dir];\n                            int nj = j + dj[dir];\n                            // Prob p: stays in square due to forgetfulness\n                            next_state.P[i][j] += p_val * p_prob_val;\n                            // Prob 1-p: moves successfully\n                            if (ni == ti && nj == tj) {\n                                prob_reached_this_step += p_val * (1.0 - p_prob_val);\n                            } else {\n                                next_state.P[ni][nj] += p_val * (1.0 - p_prob_val);\n                            }\n                        } else {\n                            // Hit wall (moves 1-p but hits wall, or stays p)\n                            next_state.P[i][j] += p_val;\n                        }\n                    }\n                }\n                \n                next_state.current_E_S = state.current_E_S + (401.0 - (double)k) * prob_reached_this_step;\n                \n                // Calculate evaluation score using the heuristic of expected future reach\n                double heuristic_future = 0;\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (next_state.P[i][j] > 1e-16) {\n                            heuristic_future += next_state.P[i][j] * H_precomputed[dist_to_target[i][j]][k];\n                        }\n                    }\n                }\n                next_state.score = next_state.current_E_S + heuristic_future;\n                next_beam.push_back(next_state);\n            }\n        }\n        \n        // Pruning: keep only the best B states\n        sort(next_beam.begin(), next_beam.end());\n        if (next_beam.size() > (size_t)B) next_beam.resize(B);\n        current_beam = next_beam;\n    }\n\n    // Output the best sequence found\n    cout << current_beam[0].s << endl;\n\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 30;\nconst double TIME_LIMIT = 1950.0; // In milliseconds\n\n// Grid data\nint initial_grid[N][N];\nint current_tiles[N][N];\nint rot[N][N];\nint visited[N][N][4];\nint timer = 0;\n\n// Tile port connection table based on the problem hint\n// Directions: 0: Left, 1: Up, 2: Right, 3: Down\nint to_tbl[8][4] = {\n    {1, 0, -1, -1}, // Tile 0: Left <-> Top\n    {3, -1, -1, 0}, // Tile 1: Left <-> Bottom\n    {-1, -1, 3, 2}, // Tile 2: Right <-> Bottom\n    {-1, 2, 1, -1}, // Tile 3: Right <-> Top\n    {1, 0, 3, 2},   // Tile 4: Left <-> Top, Right <-> Bottom\n    {3, 2, 1, 0},   // Tile 5: Left <-> Bottom, Top <-> Right\n    {2, -1, 0, -1}, // Tile 6: Left <-> Right\n    {-1, 3, -1, 1}  // Tile 7: Top <-> Bottom\n};\n\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Rotation mapping for tile types based on 90\u00b0 CCW increments\ninline int get_tile_type(int initial_type, int rotation) {\n    if (initial_type <= 3) return (initial_type + rotation) % 4;\n    if (initial_type <= 5) return 4 + (initial_type - 4 + rotation) % 2;\n    if (initial_type <= 7) return 6 + (initial_type - 6 + rotation) % 2;\n    return initial_type;\n}\n\n// Evaluate function to find loop lengths and calculate a score for SA\nlong long evaluate(int& max1, int& max2) {\n    timer++;\n    max1 = 0; max2 = 0;\n    int num_loops = 0;\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) continue;\n                if (to_tbl[current_tiles[i][j]][d] == -1) continue;\n\n                int length = 0;\n                int ci = i, cj = j, cd = d;\n                bool loop = false;\n                while (true) {\n                    visited[ci][cj][cd] = timer;\n                    int d_out = to_tbl[current_tiles[ci][cj]][cd];\n                    if (d_out == -1) break;\n                    visited[ci][cj][d_out] = timer;\n\n                    int ni = ci + di[d_out];\n                    int nj = cj + dj[d_out];\n                    int nd = d_out ^ 2; // XOR with 2 switches between 0<->2 and 1<->3 (opposite directions)\n                    length++;\n\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    if (ni == i && nj == j && nd == d) {\n                        loop = true;\n                        break;\n                    }\n                    if (visited[ni][nj][nd] == timer) break;\n                    ci = ni; cj = nj; cd = nd;\n                }\n                if (loop) {\n                    num_loops++;\n                    if (length > max1) {\n                        max2 = max1;\n                        max1 = length;\n                    } else if (length > max2) {\n                        max2 = length;\n                    }\n                }\n            }\n        }\n    }\n    // Strategic scoring: prioritize having at least 2 loops\n    if (num_loops >= 2) return 1000000LL + (long long)max1 * max2;\n    if (num_loops == 1) return (long long)max1;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Reading grid input\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            initial_grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // RNG for Simulated Annealing\n    mt19937 rng(42);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rot[i][j] = rng() % 4;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    int m1, m2;\n    long long current_score = evaluate(m1, m2);\n    long long best_score = current_score;\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] = rot[i][j];\n\n    // SA Parameters\n    double T_start = 1000.0;\n    double T_end = 1.0;\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        // Periodic time check\n        if ((iter & 127) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n\n        // Randomly pick a tile and a new rotation\n        int i = rng() % N;\n        int j = rng() % N;\n        int old_r = rot[i][j];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        rot[i][j] = new_r;\n        current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n\n        int nm1, nm2;\n        long long next_score = evaluate(nm1, nm2);\n\n        bool accept = false;\n        if (next_score >= current_score) {\n            accept = true;\n        } else {\n            auto current_time = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            double t = elapsed / TIME_LIMIT;\n            double T = T_start * pow(T_end / T_start, t);\n            if (exp((double)(next_score - current_score) / T) > (double)rng() / rng.max()) {\n                accept = true;\n            }\n        }\n\n        if (accept) {\n            current_score = next_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int r = 0; r < N; ++r) {\n                    for (int c = 0; c < N; ++c) {\n                        best_rot[r][c] = rot[r][c];\n                    }\n                }\n            }\n        } else {\n            // Revert changes\n            rot[i][j] = old_r;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n\n    // Output result\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}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint N, T_max;\nint initial_empty_r, initial_empty_c;\nint empty_tile_id;\nint id_to_type[100];\n\nint get_type(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    if (c >= 'a' && c <= 'f') return c - 'a' + 10;\n    return 0;\n}\n\nstruct DSU {\n    vector<int> parent;\n    vector<int> sz;\n    vector<int> edges;\n    DSU(int n) : parent(n), sz(n, 1), edges(n, 0) {\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    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            parent[root_i] = root_j;\n            sz[root_j] += sz[root_i];\n            edges[root_j] += edges[root_i] + 1;\n        } else {\n            edges[root_i]++;\n        }\n    }\n};\n\nint get_tree_score(const vector<int>& p) {\n    DSU dsu(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int u = r * N + c;\n            int type_u = id_to_type[p[u]];\n            if (type_u == 0) continue;\n            if (c + 1 < N) {\n                int v = u + 1;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 4) && (type_v & 1)) dsu.unite(u, v);\n            }\n            if (r + 1 < N) {\n                int v = u + N;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 8) && (type_v & 2)) dsu.unite(u, v);\n            }\n        }\n    }\n    int max_s = 0;\n    for (int i = 0; i < N * N; ++i) {\n        if (dsu.parent[i] == i && id_to_type[p[i]] != 0) {\n            if (dsu.edges[i] == dsu.sz[i] - 1) max_s = max(max_s, dsu.sz[i]);\n        }\n    }\n    return max_s;\n}\n\nint get_manhattan(const vector<int>& p) {\n    int dist = 0;\n    for (int i = 0; i < N * N; ++i) {\n        int id = p[i];\n        int r0 = id / N, c0 = id % N;\n        int r1 = i / N, c1 = i % N;\n        dist += abs(r0 - r1) + abs(c0 - c1);\n    }\n    return dist;\n}\n\nbool is_reachable(const vector<int>& p) {\n    int inv = 0;\n    int er = -1, ec = -1;\n    for (int i = 0; i < N * N; ++i) {\n        if (p[i] == empty_tile_id) { er = i / N; ec = i % N; }\n        for (int j = i + 1; j < N * N; ++j) {\n            if (p[i] > p[j]) inv++;\n        }\n    }\n    return (inv % 2) == (abs(er - initial_empty_r) + abs(ec - initial_empty_c)) % 2;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    if (!(cin >> N >> T_max)) return 0;\n    vector<int> current_p(N * N);\n    for (int i = 0; i < N; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            id_to_type[id] = get_type(row[j]);\n            if (id_to_type[id] == 0) { initial_empty_r = i; initial_empty_c = j; empty_tile_id = id; }\n            current_p[id] = id;\n        }\n    }\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    vector<int> target_p = current_p;\n    long long current_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n    vector<int> best_p = target_p; long long best_score = current_score;\n    double initial_temp = 5000.0, final_temp = 1.0;\n    for (int iter = 0; ; ++iter) {\n        if (iter % 256 == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > 2.0) break;\n            double temp = initial_temp + (final_temp - initial_temp) * (elapsed / 2.0);\n            int p1 = rng() % (N * N), p2 = rng() % (N * N);\n            if (p1 == p2) continue;\n            swap(target_p[p1], target_p[p2]);\n            long long next_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n            if (next_score > current_score || exp((double)(next_score - current_score) / temp) > (double)rng() / rng.max()) {\n                current_score = next_score;\n                if (current_score > best_score) { best_score = current_score; best_p = target_p; }\n            } else swap(target_p[p1], target_p[p2]);\n        } else {\n            int p1 = rng() % (N * N), p2 = rng() % (N * N);\n            if (p1 == p2) continue;\n            swap(target_p[p1], target_p[p2]);\n            long long next_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n            if (next_score > current_score) {\n                current_score = next_score;\n                if (current_score > best_score) { best_score = current_score; best_p = target_p; }\n            } else swap(target_p[p1], target_p[p2]);\n        }\n    }\n    target_p = best_p;\n    if (!is_reachable(target_p)) {\n        bool flipped = false;\n        for (int i = 0; i < N * N; ++i) {\n            for (int j = i + 1; j < N * N; ++j)\n                if (target_p[i] != empty_tile_id && target_p[j] != empty_tile_id && id_to_type[target_p[i]] == id_to_type[target_p[j]]) {\n                    swap(target_p[i], target_p[j]); flipped = true; break;\n                }\n            if (flipped) break;\n        }\n    }\n    string all_moves = \"\"; vector<bool> solved(N * N, false);\n    auto move_to_pos = [&](int target_id, int tr, int tc) {\n        int curr_idx = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == target_id) curr_idx = i;\n        if (curr_idx == tr * N + tc) return;\n        int er = -1, ec = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == empty_tile_id) { er = i / N; ec = i % N; }\n        queue<int> q; q.push(er * N * N * N + ec * N * N + (curr_idx / N) * N + (curr_idx % N));\n        vector<int> dist(N * N * N * N, -1); vector<int> parent(N * N * N * N, -1); vector<char> move_from(N * N * N * N);\n        dist[q.front()] = 0; int end_state = -1;\n        while (!q.empty()) {\n            int s = q.front(); q.pop();\n            int cer = s / (N * N * N), cec = (s / (N * N)) % N, ctr = (s / N) % N, ctc = s % N;\n            if (ctr == tr && ctc == tc) { end_state = s; break; }\n            int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; char dchar[] = {'U', 'D', 'L', 'R'};\n            for (int i = 0; i < 4; ++i) {\n                int ner = cer + dr[i], nec = cec + dc[i];\n                if (ner >= 0 && ner < N && nec >= 0 && nec < N && !solved[ner * N + nec]) {\n                    int ntr = ctr, ntc = ctc; if (ner == ctr && nec == ctc) { ntr = cer; ntc = cec; }\n                    int ns = ner * N * N * N + nec * N * N + ntr * N + ntc;\n                    if (dist[ns] == -1) { dist[ns] = dist[s] + 1; parent[ns] = s; move_from[ns] = dchar[i]; q.push(ns); }\n                }\n            }\n        }\n        if (end_state == -1) return;\n        string moves = \"\"; for (int s = end_state; s != -1 && parent[s] != -1; s = parent[s]) moves += move_from[s];\n        reverse(moves.begin(), moves.end()); all_moves += moves;\n        for (char m : moves) {\n            int cer = -1, cec = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == empty_tile_id) { cer = i / N; cec = i % N; }\n            int ner = cer, nec = cec; if (m == 'U') ner--; else if (m == 'D') ner++; else if (m == 'L') nec--; else if (m == 'R') nec++;\n            swap(current_p[cer * N + cec], current_p[ner * N + nec]);\n        }\n    };\n    for (int r = 0; r < N - 3; ++r) for (int c = 0; c < N; ++c) { move_to_pos(target_p[r * N + c], r, c); solved[r * N + c] = true; }\n    for (int c = 0; c < N - 3; ++c) for (int r = N - 3; r < N; ++r) { move_to_pos(target_p[r * N + c], r, c); solved[r * N + c] = true; }\n    vector<int> p33; for (int r = N - 3; r < N; ++r) for (int c = N - 3; c < N; ++c) p33.push_back(r * N + c);\n    vector<int> target_sub(9); for (int i = 0; i < 9; ++i) target_sub[i] = target_p[p33[i]];\n    vector<int> vals = target_sub; sort(vals.begin(), vals.end());\n    auto get_perm = [&](const vector<int>& p) {\n        vector<int> res(9); for (int i = 0; i < 9; ++i) res[i] = lower_bound(vals.begin(), vals.end(), p[i]) - vals.begin();\n        return res;\n    };\n    vector<int> fact(10, 1); for (int i = 1; i <= 9; ++i) fact[i] = fact[i - 1] * i;\n    auto perm_to_int = [&](const vector<int>& p) {\n        int res = 0; for (int i = 0; i < 9; ++i) {\n            int cnt = 0; for (int j = i + 1; j < 9; ++j) if (p[i] > p[j]) cnt++;\n            res += cnt * fact[8 - i];\n        } return res;\n    };\n    auto int_to_perm = [&](int s) {\n        vector<int> p(9); vector<int> digits(9); vector<bool> used(9, false);\n        for (int i = 0; i < 9; ++i) { digits[i] = s / fact[8 - i]; s %= fact[8 - i]; }\n        for (int i = 0; i < 9; ++i) {\n            int cnt = 0; for (int j = 0; j < 9; ++j) {\n                if (!used[j]) { if (cnt == digits[i]) { p[i] = j; used[j] = true; break; } cnt++; }\n            }\n        } return p;\n    };\n    int target_idx = perm_to_int(get_perm(target_sub));\n    vector<int> start_p(9); for (int i = 0; i < 9; ++i) start_p[i] = current_p[p33[i]];\n    int start_idx = perm_to_int(get_perm(start_p));\n    int er_rel = -1; vector<int> target_rel = get_perm(target_sub);\n    for (int i = 0; i < 9; ++i) if (target_sub[i] == empty_tile_id) er_rel = target_rel[i];\n    queue<int> q; q.push(start_idx); vector<int> dist33(362880, -1); vector<int> parent33(362880, -1); vector<char> move_from33(362880);\n    dist33[start_idx] = 0;\n    while (!q.empty()) {\n        int s = q.front(); q.pop(); if (s == target_idx) break;\n        vector<int> p = int_to_perm(s); int ep = -1; for (int i = 0; i < 9; ++i) if (p[i] == er_rel) ep = i;\n        int er = ep / 3, ec = ep % 3; int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; char dchar[] = {'U', 'D', 'L', 'R'};\n        for (int i = 0; i < 4; ++i) {\n            int ner = er + dr[i], nec = ec + dc[i];\n            if (ner >= 0 && ner < 3 && nec >= 0 && nec < 3) {\n                vector<int> np = p; swap(np[ep], np[ner * 3 + nec]); int ns = perm_to_int(np);\n                if (dist33[ns] == -1) { dist33[ns] = dist33[s] + 1; parent33[ns] = s; move_from33[ns] = dchar[i]; q.push(ns); }\n            }\n        }\n    }\n    string moves33 = \"\"; for (int s = target_idx; s != -1 && parent33[s] != -1; s = parent33[s]) moves33 += move_from33[s];\n    reverse(moves33.begin(), moves33.end()); all_moves += moves33;\n    cout << all_moves << endl;\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Strawberry structure to keep track of its coordinates and current grid cell\nstruct Strawberry {\n    int x, y, sx, sy;\n};\n\nint main() {\n    // Fast I/O for competitive programming\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K_limit;\n    if (!(cin >> N >> K_limit)) return 0;\n\n    // Number of vertical and horizontal cuts, totaling the limit K\n    int kx = K_limit / 2;\n    int ky = K_limit - kx;\n\n    vector<int> a(11);\n    int total_a = 0;\n    for (int i = 1; i <= 10; ++i) {\n        cin >> a[i];\n        total_a += a[i];\n    }\n\n    vector<Strawberry> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Grid line positions. Initialized as a uniform grid\n    vector<int> X(kx + 2), Y(ky + 2);\n    X[0] = -1000000000; X[kx + 1] = 1000000000;\n    Y[0] = -1000000000; Y[ky + 1] = 1000000000;\n    for (int i = 1; i <= kx; ++i) X[i] = -10000 + 20000 * i / (kx + 1);\n    for (int i = 1; i <= ky; ++i) Y[i] = -10000 + 20000 * i / (ky + 1);\n\n    // Initial grid state and piece strawberry counts\n    vector<vector<int>> count(kx + 1, vector<int>(ky + 1, 0));\n    vector<vector<int>> inSlabX(kx + 1);\n    vector<vector<int>> inSlabY(ky + 1);\n    \n    for (int i = 0; i < N; ++i) {\n        int sx = 0;\n        while (sx < kx && strawberries[i].x > X[sx + 1]) sx++;\n        int sy = 0;\n        while (sy < ky && strawberries[i].y > Y[sy + 1]) sy++;\n        strawberries[i].sx = sx;\n        strawberries[i].sy = sy;\n        count[sx][sy]++;\n        inSlabX[sx].push_back(i);\n        inSlabY[sy].push_back(i);\n    }\n\n    // Total pieces with d strawberries\n    vector<int> b(N + 1, 0);\n    int current_score = 0;\n    \n    // Updates b_d and calculates the objective score sum(min(a_d, b_d))\n    auto update_b = [&](int d, int delta) {\n        if (d >= 1 && d <= 10) current_score -= min(a[d], b[d]);\n        b[d] += delta;\n        if (d >= 1 && d <= 10) current_score += min(a[d], b[d]);\n    };\n\n    for (int i = 0; i <= kx; ++i) {\n        for (int j = 0; j <= ky; ++j) {\n            b[count[i][j]]++;\n        }\n    }\n    for (int d = 1; d <= 10; ++d) current_score += min(a[d], b[d]);\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    long long iterations = 0;\n\n    // Optimization through Hill Climbing\n    while (true) {\n        if ((iterations & 2047) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2800) break;\n            if (current_score == total_a) break;\n        }\n        iterations++;\n\n        if (rng() % 2 == 0) { // vertical cut shift\n            int i = rng() % kx + 1;\n            int oldX = X[i];\n            int range = X[i+1] - X[i-1] - 1;\n            if (range <= 0) continue;\n            int newX = X[i-1] + 1 + rng() % range;\n            if (newX == oldX) continue;\n\n            vector<int> moved;\n            int prev_score = current_score;\n\n            if (newX > oldX) {\n                for (int k : inSlabX[i]) {\n                    if (strawberries[k].x <= newX) {\n                        int sy = strawberries[k].sy;\n                        update_b(count[i][sy], -1); count[i][sy]--; update_b(count[i][sy], 1);\n                        update_b(count[i-1][sy], -1); count[i-1][sy]++; update_b(count[i-1][sy], 1);\n                        moved.push_back(k);\n                    }\n                }\n            } else {\n                for (int k : inSlabX[i-1]) {\n                    if (strawberries[k].x > newX) {\n                        int sy = strawberries[k].sy;\n                        update_b(count[i-1][sy], -1); count[i-1][sy]--; update_b(count[i-1][sy], 1);\n                        update_b(count[i][sy], -1); count[i][sy]++; update_b(count[i][sy], 1);\n                        moved.push_back(k);\n                    }\n                }\n            }\n\n            if (current_score >= prev_score) {\n                X[i] = newX;\n                if (newX > oldX) {\n                    vector<int> nextSlabI;\n                    for (int k : inSlabX[i]) {\n                        if (strawberries[k].x > newX) nextSlabI.push_back(k);\n                        else { strawberries[k].sx = i - 1; inSlabX[i-1].push_back(k); }\n                    }\n                    inSlabX[i] = nextSlabI;\n                } else {\n                    vector<int> nextSlabIMinus1;\n                    for (int k : inSlabX[i-1]) {\n                        if (strawberries[k].x <= newX) nextSlabIMinus1.push_back(k);\n                        else { strawberries[k].sx = i; inSlabX[i].push_back(k); }\n                    }\n                    inSlabX[i-1] = nextSlabIMinus1;\n                }\n            } else { // Undo changes\n                if (newX > oldX) {\n                    for (int k : moved) {\n                        int sy = strawberries[k].sy;\n                        count[i][sy]++; count[i-1][sy]--;\n                    }\n                } else {\n                    for (int k : moved) {\n                        int sy = strawberries[k].sy;\n                        count[i-1][sy]++; count[i][sy]--;\n                    }\n                }\n                // Fast rollback of score metrics\n                for (int d = 1; d <= 10; ++d) {\n                    current_score -= min(a[d], b[d]);\n                    b[d] = 0;\n                }\n                for (int ii = 0; ii <= kx; ++ii) {\n                    for (int jj = 0; jj <= ky; ++jj) {\n                        int c = count[ii][jj];\n                        if (c >= 1 && c <= 10) b[c]++;\n                    }\n                }\n                for (int d = 1; d <= 10; ++d) current_score += min(a[d], b[d]);\n            }\n        } else { // horizontal cut shift (symmetric to vertical)\n            int j = rng() % ky + 1;\n            int oldY = Y[j];\n            int range = Y[j+1] - Y[j-1] - 1;\n            if (range <= 0) continue;\n            int newY = Y[j-1] + 1 + rng() % range;\n            if (newY == oldY) continue;\n\n            vector<int> moved;\n            int prev_score = current_score;\n\n            if (newY > oldY) {\n                for (int k : inSlabY[j]) {\n                    if (strawberries[k].y <= newY) {\n                        int sx = strawberries[k].sx;\n                        update_b(count[sx][j], -1); count[sx][j]--; update_b(count[sx][j], 1);\n                        update_b(count[sx][j-1], -1); count[sx][j-1]++; update_b(count[sx][j-1], 1);\n                        moved.push_back(k);\n                    }\n                }\n            } else {\n                for (int k : inSlabY[j-1]) {\n                    if (strawberries[k].y > newY) {\n                        int sx = strawberries[k].sx;\n                        update_b(count[sx][j-1], -1); count[sx][j-1]--; update_b(count[sx][j-1], 1);\n                        update_b(count[sx][j], -1); count[sx][j]++; update_b(count[sx][j], 1);\n                        moved.push_back(k);\n                    }\n                }\n            }\n\n            if (current_score >= prev_score) {\n                Y[j] = newY;\n                if (newY > oldY) {\n                    vector<int> nextSlabJ;\n                    for (int k : inSlabY[j]) {\n                        if (strawberries[k].y > newY) nextSlabJ.push_back(k);\n                        else { strawberries[k].sy = j - 1; inSlabY[j-1].push_back(k); }\n                    }\n                    inSlabY[j] = nextSlabJ;\n                } else {\n                    vector<int> nextSlabJMinus1;\n                    for (int k : inSlabY[j-1]) {\n                        if (strawberries[k].y <= newY) nextSlabJMinus1.push_back(k);\n                        else { strawberries[k].sy = j; inSlabY[j].push_back(k); }\n                    }\n                    inSlabY[j-1] = nextSlabJMinus1;\n                }\n            } else {\n                if (newY > oldY) {\n                    for (int k : moved) {\n                        int sx = strawberries[k].sx;\n                        count[sx][j]++; count[sx][j-1]--;\n                    }\n                } else {\n                    for (int k : moved) {\n                        int sx = strawberries[k].sx;\n                        count[sx][j-1]++; count[sx][j]--;\n                    }\n                }\n                for (int d = 1; d <= 10; ++d) { current_score -= min(a[d], b[d]); b[d] = 0; }\n                for (int ii = 0; ii <= kx; ++ii) {\n                    for (int jj = 0; jj <= ky; ++jj) {\n                        int c = count[ii][jj]; if (c >= 1 && c <= 10) b[c]++;\n                    }\n                }\n                for (int d = 1; d <= 10; ++d) current_score += min(a[d], b[d]);\n            }\n        }\n    }\n\n    // Output all lines\n    cout << kx + ky << endl;\n    for (int i = 1; i <= kx; ++i) {\n        // Line x ~ X[i] + 0.5 using tilted integer coordinates\n        cout << X[i] << \" -1000000000 \" << X[i] + 1 << \" 1000000000\" << endl;\n    }\n    for (int j = 1; j <= ky; ++j) {\n        // Line y ~ Y[j] + 0.5 using tilted integer coordinates\n        cout << \"-1000000000 \" << Y[j] << \" 1000000000 \" << Y[j] + 1 << endl;\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Point structure to represent grid points\nstruct Point {\n    int x, y;\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Rect structure to represent the chosen rectangle\nstruct Rect {\n    Point p1, p2, p3, p4;\n    int d1, d2;\n};\n\n// Op structure to store the operations for output\nstruct Op {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\n// Movement vectors for the 8 directions (axis-parallel and 45-degree)\nint dx[] = {1, 1, 0, -1, -1, -1, 0, 1};\nint dy[] = {0, 1, 1, 1, 0, -1, -1, -1};\n\n// Directions for orthogonal pairs used to form rectangles\npair<int, int> orthogonal_pairs[] = {\n    {0, 2}, {2, 4}, {4, 6}, {6, 0}, // Axis-parallel: Right-Up, Up-Left, Left-Down, Down-Right\n    {1, 3}, {3, 5}, {5, 7}, {7, 1}  // 45-degree: UR-UL, UL-DL, DL-DR, DR-UR\n};\n\nlong long weights[61][61];\n\n// Function to find the nearest dot in a given direction from a point\nPoint find_nearest_dot(int x, int y, int d, int N, const vector<vector<bool>>& has_dot) {\n    x += dx[d]; y += dy[d];\n    while (x >= 0 && x < N && y >= 0 && y < N) {\n        if (has_dot[x][y]) return {x, y};\n        x += dx[d]; y += dy[d];\n    }\n    return {-1, -1};\n}\n\n// Function to check if any part of a segment has been used by an existing rectangle\nbool is_segment_used(Point a, Point b, int d, const vector<vector<vector<bool>>>& used) {\n    int x = a.x, y = a.y;\n    while (x != b.x || y != b.y) {\n        if (used[x][y][d]) return true;\n        x += dx[d]; y += dy[d];\n    }\n    return false;\n}\n\n// Function to mark all unit segments of a rectangle's perimeter as used\nvoid mark_segment(Point a, Point b, int d, vector<vector<vector<bool>>>& used) {\n    int x = a.x, y = a.y;\n    while (x != b.x || y != b.y) {\n        used[x][y][d] = true;\n        int nx = x + dx[d], ny = y + dy[d];\n        used[nx][ny][(d + 4) % 8] = true;\n        x = nx; y = ny;\n    }\n}\n\n// Chebyshev distance measure for both axis-parallel and 45-degree alignments\nint dist(Point a, Point b) {\n    return max(abs(a.x - b.x), abs(a.y - b.y));\n}\n\n// Validation function to check if a rectangle formation is legal according to the rules\nbool is_valid(const Rect& r, int N, const vector<vector<bool>>& has_dot, const vector<vector<vector<bool>>>& used) {\n    if (has_dot[r.p1.x][r.p1.y]) return false;\n    if (!has_dot[r.p2.x][r.p2.y] || !has_dot[r.p3.x][r.p3.y] || !has_dot[r.p4.x][r.p4.y]) return false;\n    \n    // Nearest dot checks ensure condition 2: no other dots on the perimeter\n    if (find_nearest_dot(r.p1.x, r.p1.y, r.d1, N, has_dot) != r.p2) return false;\n    if (find_nearest_dot(r.p1.x, r.p1.y, r.d2, N, has_dot) != r.p4) return false;\n    if (find_nearest_dot(r.p2.x, r.p2.y, r.d2, N, has_dot) != r.p3) return false;\n    if (find_nearest_dot(r.p4.x, r.p4.y, r.d1, N, has_dot) != r.p3) return false;\n    \n    // Segment checks ensure condition 3: no shared segments with existing rectangles\n    if (is_segment_used(r.p1, r.p2, r.d1, used)) return false;\n    if (is_segment_used(r.p2, r.p3, r.d2, used)) return false;\n    if (is_segment_used(r.p3, r.p4, (r.d1 + 4) % 8, used)) return false;\n    if (is_segment_used(r.p4, r.p1, (r.d2 + 4) % 8, used)) return false;\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    \n    vector<vector<bool>> has_dot_init(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        has_dot_init[x][y] = true;\n    }\n\n    // Precalculate point weights based on their distance from the center (c, c)\n    double c = (N - 1) / 2.0;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y < N; ++y) {\n            weights[x][y] = (long long)((x - c) * (x - c) + (y - c) * (y - c) + 1);\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    long long best_weight_sum = -1;\n    vector<Op> best_ops;\n\n    vector<Point> all_points;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y < N; ++y) {\n            all_points.push_back({x, y});\n        }\n    }\n\n    // Heuristic approach: multi-start greedy search with varying strategies and randomization\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 4750) {\n        vector<vector<bool>> has_dot = has_dot_init;\n        vector<vector<vector<bool>>> used(N, vector<vector<bool>>(N, vector<bool>(8, false)));\n        vector<Op> current_ops;\n        long long current_weight_sum = 0;\n\n        for (int x = 0; x < N; ++x)\n            for (int y = 0; y < N; ++y)\n                if (has_dot[x][y]) current_weight_sum += weights[x][y];\n\n        // Randomize the heuristic parameter to explore different expansion patterns\n        double perimeter_weight = (rng() % 3501) / 1000.0;\n        vector<Point> p1_list = all_points;\n        int strategy = rng() % 10;\n        if (strategy < 3) {\n            // Center-out: prioritize adding dots near the middle to create \"bridges\"\n            sort(p1_list.begin(), p1_list.end(), [&](Point a, Point b) {\n                return weights[a.x][a.y] < weights[b.x][b.y];\n            });\n        } else if (strategy < 6) {\n            // Boundary-in: prioritize adding high-value dots first\n            sort(p1_list.begin(), p1_list.end(), [&](Point a, Point b) {\n                return weights[a.x][a.y] > weights[b.x][b.y];\n            });\n        } else {\n            // Random: ensure variety in dot addition order\n            shuffle(p1_list.begin(), p1_list.end(), rng);\n        }\n\n        while (true) {\n            bool added_any_in_pass = false;\n            for (auto& p1 : p1_list) {\n                if (has_dot[p1.x][p1.y]) continue;\n                \n                Rect best_r;\n                double max_s = -1.0;\n                // Evaluate all 8 possible rectangle orientations for the current empty point p1\n                for (int i = 0; i < 8; ++i) {\n                    int d1 = orthogonal_pairs[i].first, d2 = orthogonal_pairs[i].second;\n                    Point p2 = find_nearest_dot(p1.x, p1.y, d1, N, has_dot);\n                    Point p4 = find_nearest_dot(p1.x, p1.y, d2, N, has_dot);\n                    if (p2.x != -1 && p4.x != -1) {\n                        Point p3 = {p2.x + p4.x - p1.x, p2.y + p4.y - p1.y};\n                        if (p3.x >= 0 && p3.x < N && p3.y >= 0 && p3.y < N && has_dot[p3.x][p3.y]) {\n                            Rect r = {p1, p2, p3, p4, d1, d2};\n                            if (is_valid(r, N, has_dot, used)) {\n                                int p_len = 2 * (dist(p1, p2) + dist(p1, p4));\n                                // Score function balances high-value coordinates and the \"blocking\" effect of large perimeters\n                                double s = (double)weights[p1.x][p1.y] / pow(p_len, perimeter_weight);\n                                if (s > max_s) {\n                                    max_s = s;\n                                    best_r = r;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (max_s != -1.0) {\n                    // Update the state with the selected rectangle\n                    has_dot[best_r.p1.x][best_r.p1.y] = true;\n                    mark_segment(best_r.p1, best_r.p2, best_r.d1, used);\n                    mark_segment(best_r.p2, best_r.p3, best_r.d2, used);\n                    mark_segment(best_r.p3, best_r.p4, (best_r.d1 + 4) % 8, used);\n                    mark_segment(best_r.p4, best_r.p1, (best_r.d2 + 4) % 8, used);\n                    current_ops.push_back({best_r.p1.x, best_r.p1.y, best_r.p2.x, best_r.p2.y, best_r.p3.x, best_r.p3.y, best_r.p4.x, best_r.p4.y});\n                    current_weight_sum += weights[best_r.p1.x][best_r.p1.y];\n                    added_any_in_pass = true;\n                }\n            }\n            if (!added_any_in_pass) break;\n            shuffle(p1_list.begin(), p1_list.end(), rng);\n        }\n\n        if (current_weight_sum > best_weight_sum) {\n            best_weight_sum = current_weight_sum;\n            best_ops = current_ops;\n        }\n    }\n\n    // Output the total number of operations and the specifics for each operation\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.x1 << \" \" << op.y1 << \" \" << op.x2 << \" \" << op.y2 << \" \"\n             << op.x3 << \" \" << op.y3 << \" \" << op.x4 << \" \" << op.y4 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <chrono>\n#include <algorithm>\n#include <cstdint>\n\nusing namespace std;\n\n/**\n * Xorshift algorithm for fast pseudo-random number generation.\n */\nstruct Xorshift {\n    uint32_t x;\n    Xorshift(uint32_t seed = 123456789) : x(seed) {}\n    uint32_t next() {\n        x ^= (x << 13);\n        x ^= (x >> 17);\n        x ^= (x << 5);\n        return x;\n    }\n};\n\n/**\n * Represents the 10x10 candy box grid.\n */\nstruct Board {\n    int grid[10][10];\n    Board() {\n        for (int i = 0; i < 10; ++i)\n            for (int j = 0; j < 10; ++j)\n                grid[i][j] = 0; // 0 represents an empty cell\n    }\n\n    /**\n     * Tilts the box in a given direction (0:F, 1:B, 2:L, 3:R).\n     * Returns true if any candy moved.\n     */\n    bool tilt(int dir) {\n        bool changed = false;\n        if (dir == 0) { // Forward (Up - row index decreases)\n            for (int j = 0; j < 10; ++j) {\n                int last = 0;\n                for (int i = 0; i < 10; ++i) {\n                    if (grid[i][j]) {\n                        if (i != last) {\n                            grid[last][j] = grid[i][j];\n                            grid[i][j] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 1) { // Backward (Down - row index increases)\n            for (int j = 0; j < 10; ++j) {\n                int last = 9;\n                for (int i = 9; i >= 0; --i) {\n                    if (grid[i][j]) {\n                        if (i != last) {\n                            grid[last][j] = grid[i][j];\n                            grid[i][j] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        } else if (dir == 2) { // Left (col index decreases)\n            for (int i = 0; i < 10; ++i) {\n                int last = 0;\n                for (int j = 0; j < 10; ++j) {\n                    if (grid[i][j]) {\n                        if (j != last) {\n                            grid[i][last] = grid[i][j];\n                            grid[i][j] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 3) { // Right (col index increases)\n            for (int i = 0; i < 10; ++i) {\n                int last = 9;\n                for (int j = 9; j >= 0; --j) {\n                    if (grid[i][j]) {\n                        if (j != last) {\n                            grid[i][last] = grid[i][j];\n                            grid[i][j] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * Simple heuristic potential: total number of adjacent same-flavor pairs.\n     */\n    int count_adj() const {\n        int score = 0;\n        for (int i = 0; i < 10; ++i) {\n            for (int j = 0; j < 9; ++j) {\n                if (grid[i][j] && grid[i][j] == grid[i][j+1]) score++;\n                if (grid[j][i] && grid[j][i] == grid[j+1][i]) score++;\n            }\n        }\n        return score;\n    }\n\n    /**\n     * Calculates the objective function: sum of squares of connected component sizes.\n     */\n    int eval_score() const {\n        int sum_sq = 0;\n        uint64_t v0 = 0, v1 = 0; // Bitset to keep track of visited cells\n        for (int i = 0; i < 100; ++i) {\n            int r = i / 10, c = i % 10;\n            if (grid[r][c] == 0) continue;\n            if (i < 64) { if (v0 & (1ULL << i)) continue; }\n            else { if (v1 & (1ULL << (i - 64))) continue; }\n            \n            int count = 0, flavor = grid[r][c];\n            int q[100], head = 0, tail = 0;\n            q[tail++] = i;\n            if (i < 64) v0 |= (1ULL << i); else v1 |= (1ULL << (i - 64));\n            \n            while (head < tail) {\n                int cur = q[head++];\n                count++;\n                int cr = cur / 10, cc = cur % 10;\n                static const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k], nc = cc + dc[k];\n                    if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10 && grid[nr][nc] == flavor) {\n                        int nidx = nr * 10 + nc;\n                        if (nidx < 64) {\n                            if (!(v0 & (1ULL << nidx))) { v0 |= (1ULL << nidx); q[tail++] = nidx; }\n                        } else {\n                            if (!(v1 & (1ULL << (nidx - 64)))) { v1 |= (1ULL << (nidx - 64)); q[tail++] = nidx; }\n                        }\n                    }\n                }\n            }\n            sum_sq += count * count;\n        }\n        return sum_sq;\n    }\n\n    /**\n     * Places the actual candy received based on its index in the list of empty cells.\n     */\n    void place_actual(int p, int flavor) {\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i/10][i%10] == 0) {\n                count++;\n                if (count == p) { grid[i/10][i%10] = flavor; return; }\n            }\n        }\n    }\n\n    /**\n     * Places a candy of the given flavor into a random empty cell.\n     */\n    void place_randomly(int flavor, Xorshift& rng) {\n        int empty_indices[100], num_empty = 0;\n        for (int i = 0; i < 100; ++i) if (grid[i/10][i%10] == 0) empty_indices[num_empty++] = i;\n        if (num_empty > 0) {\n            int idx = empty_indices[rng.next() % num_empty];\n            grid[idx/10][idx%10] = flavor;\n        }\n    }\n};\n\n/**\n * Greedily selects a tilt direction for the simulation.\n */\nint pick_greedy_move(const Board& b) {\n    int best_v = -1, best_d = 0;\n    for (int d = 0; d < 4; ++d) {\n        Board tmp = b;\n        if (tmp.tilt(d)) {\n            int v = tmp.count_adj();\n            if (v > best_v) { best_v = v; best_d = d; }\n        }\n    }\n    return best_d;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> flavors[i])) break;\n    }\n\n    Xorshift rng;\n    Board current_board;\n    char d_chars[] = {'F', 'B', 'L', 'R'};\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        if (!(cin >> p)) break;\n        current_board.place_actual(p, flavors[t]);\n\n        auto start_turn = chrono::high_resolution_clock::now();\n        long long total_scores[4] = {0, 0, 0, 0};\n        int K = 0;\n\n        // Perform Monte Carlo simulations for each of the 4 possible moves.\n        // We limit the simulation time per turn to ensure we stay within the 2.0s limit.\n        while (true) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::microseconds>(now - start_turn).count() > 18500) break;\n            \n            for (int d = 0; d < 4; ++d) {\n                Board sim_board = current_board;\n                sim_board.tilt(d);\n                for (int k = t + 1; k < 100; ++k) {\n                    sim_board.place_randomly(flavors[k], rng);\n                    sim_board.tilt(pick_greedy_move(sim_board));\n                }\n                total_scores[d] += sim_board.eval_score();\n            }\n            K++;\n        }\n\n        // Choose the move with the highest total (average) simulated score.\n        int best_d = 0;\n        long long max_s = -1;\n        for (int d = 0; d < 4; ++d) {\n            if (total_scores[d] > max_s) {\n                max_s = total_scores[d];\n                best_d = d;\n            }\n        }\n\n        cout << d_chars[best_d] << endl;\n        current_board.tilt(best_d);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Normal CDF function: Phi(x) = 0.5 * (1 + erf((x - mean) / (sigma * sqrt(2))))\n * This function calculates the probability that a random variable following a normal \n * distribution with the given mean and sigma is less than x.\n */\ndouble normal_cdf(double x, double mean, double sigma) {\n    if (sigma < 1e-9) {\n        if (x < mean) return 0.0;\n        if (x > mean) return 1.0;\n        return 0.5;\n    }\n    return 0.5 * (1.0 + erf((x - mean) / (sigma * sqrt(2.0))));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double eps;\n    // Read the number of graphs M and the error rate epsilon.\n    if (!(cin >> M >> eps)) return 0;\n\n    int bestN = 4;\n    double bestExpectedScore = -1.0;\n\n    // Iterate through all possible values for N (the number of vertices) to find the one that \n    // maximizes the expected score. The score is calculated based on the expected number of \n    // errors using an edge count encoding/decoding method.\n    for (int N = 4; N <= 100; ++N) {\n        int K = N * (N - 1) / 2; // Maximum number of possible edges.\n        vector<int> Es(M);\n        for (int s = 0; s < M; ++s) {\n            // Encode the number of edges for each graph G_s.\n            Es[s] = (int)round((double)s * K / (M - 1));\n        }\n\n        // Standard deviation of the edge count after noise (Binomial sum approximation).\n        double sigma = sqrt((double)K * eps * (1.0 - eps));\n        double P_avg = 0.0;\n\n        for (int s = 0; s < M; ++s) {\n            // Count how many graphs have the same number of edges as G_s.\n            int c = 0;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] == Es[s]) c++;\n            }\n\n            // The expected mean number of edges in the noisy graph H generated from G_s.\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n\n            // Find the closest different edge counts to identify the decision boundaries.\n            double E_prev = -1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] < Es[s]) {\n                    if (E_prev < -1e17 || Es[j] > E_prev) {\n                        E_prev = (double)Es[j];\n                    }\n                }\n            }\n\n            double E_next = 1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] > Es[s]) {\n                    if (E_next > 1e17 || Es[j] < E_next) {\n                        E_next = (double)Es[j];\n                    }\n                }\n            }\n\n            double low, high;\n            if (E_prev < -1e17) {\n                low = -1e18; // No lower bound for the first category.\n            } else {\n                double mu_prev = E_prev * (1.0 - 2.0 * eps) + (double)K * eps;\n                low = (mu_s + mu_prev) / 2.0;\n            }\n\n            if (E_next > 1e17) {\n                high = 1e18; // No upper bound for the last category.\n            } else {\n                double mu_next = E_next * (1.0 - 2.0 * eps) + (double)K * eps;\n                high = (mu_s + mu_next) / 2.0;\n            }\n\n            // Estimate the probability of correct decoding for the s-th graph.\n            double prob_correct_in_range;\n            if (sigma < 1e-9) {\n                prob_correct_in_range = 1.0;\n            } else {\n                prob_correct_in_range = normal_cdf(high, mu_s, sigma) - normal_cdf(low, mu_s, sigma);\n            }\n            // If multiple graphs have the same edge count, they are indistinguishable.\n            P_avg += prob_correct_in_range / (double)c;\n        }\n\n        // Calculate the overall expected probability of a correct prediction.\n        P_avg /= (double)M;\n        double p_error = 1.0 - P_avg;\n        // Expected absolute score formula: (1 - 0.1 * p_error)^100 / N.\n        double expectedScore = pow(1.0 - 0.1 * p_error, 100) / (double)N;\n\n        if (expectedScore > bestExpectedScore) {\n            bestExpectedScore = expectedScore;\n            bestN = N;\n        }\n    }\n\n    // Set up the selected N and the corresponding graphs G_0, ..., G_{M-1}.\n    int N = bestN;\n    int K = N * (N - 1) / 2;\n    vector<int> Es(M);\n    for (int s = 0; s < M; ++s) {\n        Es[s] = (int)round((double)s * K / (M - 1));\n    }\n\n    // Output the chosen number of vertices N.\n    cout << N << endl;\n    // Output the string representations for the M graphs.\n    for (int s = 0; s < M; ++s) {\n        string g(K, '0');\n        for (int i = 0; i < Es[s]; ++i) {\n            g[i] = '1';\n        }\n        cout << g << endl;\n    }\n    cout.flush();\n\n    // Process 100 noisy graph queries.\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        if (!(cin >> H)) break;\n        // Count the number of edges in the received graph H.\n        int EH = 0;\n        for (char c : H) {\n            if (c == '1') EH++;\n        }\n\n        // Find the graph s whose expected noisy edge count mean is closest to EH.\n        int best_s = 0;\n        double min_diff = 1e18;\n        for (int s = 0; s < M; ++s) {\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n            double diff = abs((double)EH - mu_s);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        // Output the prediction for the current query.\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Takahashi City Road Repair Problem\n * Objective: Plan which edges to repair on which day to minimize the total frustration.\n * Constraints: N (500-1000), M (500-3000), D (5-30), K (ceil(M/D)+1 to 2*ceil(M/D)).\n * Methodology:\n * 1. Initial assignment based on spatial sorting (midpoint angles) and round-robin distribution to spread\n *    concurrent repairs as far apart as possible.\n * 2. Local optimization (Hill Climbing) using a sampled frustration proxy (shortest path distance sums from 40 sources).\n */\n\n// Maximum possible path distance considered as \"unreachable frustration level\" for Scoring.\nconst long long INF = 1000000000LL;\n\n// Standard adjacency edge for the city graph.\nstruct Edge {\n    int to, weight, id;\n};\n\n// Metadata for edges used during initialization and sorting.\nstruct EdgeInfo {\n    int id, u, v, w;\n    double angle;\n};\n\n// Problem data.\nint N, M, D, K;\nvector<Edge> adj[1005];\nlong long dist_buffer[1005];\nint x_coord[1005], y_coord[1005];\n\n// Executes Dijkstra's algorithm from a starting vertex, ignoring edges scheduled for repair on 'repair_day'.\nvoid dijkstra(int start, int repair_day, const vector<int>& edge_day, int num_vertices) {\n    // Large distance initialization. Path sums can be up to N * INF.\n    fill(dist_buffer, dist_buffer + num_vertices + 1, 2000000000000000LL);\n    dist_buffer[start] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, start});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d > dist_buffer[u]) continue;\n        for (const auto& e : adj[u]) {\n            // Check if the road is closed for repair on the specific day.\n            if (edge_day[e.id] == repair_day) continue;\n            long long next_d = d + e.weight;\n            if (next_d < dist_buffer[e.to]) {\n                dist_buffer[e.to] = next_d;\n                pq.push({next_d, e.to});\n            }\n        }\n    }\n}\n\n// Precomputed base distances in the original graph for proxy source points.\nvector<long long> base_dists[40];\n\n// Computes a proxy for frustration: the total increase in path lengths from selected source vertices.\nlong long compute_day_frustration(int day, const vector<int>& sources, const vector<int>& edge_day, int num_vertices) {\n    long long total_increase = 0;\n    for (int i = 0; i < (int)sources.size(); ++i) {\n        dijkstra(sources[i], day, edge_day, num_vertices);\n        for (int j = 1; j <= num_vertices; ++j) {\n            // Apply the problem-specified reachability threshold.\n            long long d_k = min(dist_buffer[j], INF);\n            total_increase += (d_k - base_dists[i][j - 1]);\n        }\n    }\n    return total_increase;\n}\n\nint main() {\n    // Fast I/O for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<EdgeInfo> all_edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        all_edges[i] = {i + 1, u, v, w, 0.0};\n        adj[u].push_back({v, w, i + 1});\n        adj[v].push_back({u, w, i + 1});\n    }\n\n    // Coordinates are used for initial spatial heuristic.\n    for (int i = 1; i <= N; ++i) {\n        cin >> x_coord[i] >> y_coord[i];\n    }\n\n    // Determine the centroid of vertices to compute radial angles.\n    double cx = 0, cy = 0;\n    for (int i = 1; i <= N; ++i) {\n        cx += (double)x_coord[i];\n        cy += (double)y_coord[i];\n    }\n    cx /= (double)N;\n    cy /= (double)N;\n\n    // Calculate angle of edge midpoints from the centroid.\n    for (int i = 0; i < M; ++i) {\n        double mx = (x_coord[all_edges[i].u] + x_coord[all_edges[i].v]) / 2.0;\n        double my = (y_coord[all_edges[i].u] + y_coord[all_edges[i].v]) / 2.0;\n        all_edges[i].angle = atan2(my - cy, mx - cx);\n    }\n\n    // Sort edges by angle. Spreading repairs from the same angle across different days minimizes regional impact.\n    sort(all_edges.begin(), all_edges.end(), [](const EdgeInfo& a, const EdgeInfo& b) {\n        return a.angle < b.angle;\n    });\n\n    // Initial Repair Schedule: Round-robin placement on spatially sorted list.\n    vector<int> edge_day(M + 1);\n    vector<vector<int>> day_edge_lists(D + 1);\n    for (int i = 0; i < M; ++i) {\n        int d = (i % D) + 1;\n        edge_day[all_edges[i].id] = d;\n        day_edge_lists[d].push_back(all_edges[i].id);\n    }\n\n    // Select 40 source vertices distributed spatially to use as path-finding probes.\n    int s_count = min(N, 40);\n    vector<int> sources;\n    sources.push_back(1);\n    while ((int)sources.size() < s_count) {\n        int best_v = -1;\n        double max_dist_sq = -1;\n        for (int v = 1; v <= N; ++v) {\n            double min_dist_sq = 1e18;\n            for (int s : sources) {\n                double dx = (double)x_coord[v] - (double)x_coord[s];\n                double dy = (double)y_coord[v] - (double)y_coord[s];\n                min_dist_sq = min(min_dist_sq, dx * dx + dy * dy);\n            }\n            if (min_dist_sq > max_dist_sq) {\n                max_dist_sq = min_dist_sq;\n                best_v = v;\n            }\n        }\n        sources.push_back(best_v);\n    }\n\n    // Precompute the shortest path distances in the original (full) graph for selected sources.\n    vector<int> dummy_none(M + 1, 0);\n    for (int i = 0; i < s_count; ++i) {\n        dijkstra(sources[i], -1, dummy_none, N);\n        for (int j = 1; j <= N; ++j) {\n            base_dists[i].push_back(min(dist_buffer[j], INF));\n        }\n    }\n\n    // Compute proxy frustration for each day under the initial schedule.\n    vector<long long> day_frustrations(D + 1);\n    for (int k = 1; k <= D; ++k) {\n        day_frustrations[k] = compute_day_frustration(k, sources, edge_day, N);\n    }\n\n    // Heuristic Optimization: Iteratively swap repairs between days to reduce the frustration proxy.\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    while (true) {\n        iterations++;\n        // Periodic check for execution time limit (6s).\n        if (iterations % 5 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 5700) break;\n        }\n\n        // Randomly pick two distinct days for swapping edges.\n        int k1 = uniform_int_distribution<int>(1, D)(rng);\n        int k2 = uniform_int_distribution<int>(1, D)(rng);\n        if (k1 == k2) continue;\n\n        // Targeted selection: Half the time, pick the day currently causing the most frustration.\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            int max_k = 1;\n            for (int k = 2; k <= D; ++k) if (day_frustrations[k] > day_frustrations[max_k]) max_k = k;\n            k1 = max_k;\n        }\n\n        if (day_edge_lists[k1].empty() || day_edge_lists[k2].empty()) continue;\n\n        // Select a random edge from each day.\n        int idx1 = uniform_int_distribution<int>(0, day_edge_lists[k1].size() - 1)(rng);\n        int idx2 = uniform_int_distribution<int>(0, day_edge_lists[k2].size() - 1)(rng);\n        int e1 = day_edge_lists[k1][idx1];\n        int e2 = day_edge_lists[k2][idx2];\n\n        // Tentative swap of scheduled repair days.\n        edge_day[e1] = k2;\n        edge_day[e2] = k1;\n\n        long long new_f1 = compute_day_frustration(k1, sources, edge_day, N);\n        long long new_f2 = compute_day_frustration(k2, sources, edge_day, N);\n\n        // Evaluation: Only keep the swap if it yields an overall improvement.\n        if (new_f1 + new_f2 < day_frustrations[k1] + day_frustrations[k2]) {\n            day_frustrations[k1] = new_f1;\n            day_frustrations[k2] = new_f2;\n            day_edge_lists[k1][idx1] = e2;\n            day_edge_lists[k2][idx2] = e1;\n        } else {\n            // Revert changes.\n            edge_day[e1] = k1;\n            edge_day[e2] = k2;\n        }\n    }\n\n    // Output final results in the format requested by the problem.\n    for (int i = 1; i <= M; ++i) {\n        cout << edge_day[i] << (i == M ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n// Coordinate structure for voxels\nstruct Voxel {\n    int x, y, z;\n    bool operator<(const Voxel& o) const {\n        if (x != o.x) return x < o.x;\n        if (y != o.y) return y < o.y;\n        return z < o.z;\n    }\n};\n\n// Standard rotations for 90-degree axis changes\nVoxel rotX(Voxel v) { return {v.x, -v.z, v.y}; }\nVoxel rotY(Voxel v) { return {v.z, v.y, -v.x}; }\nVoxel rotZ(Voxel v) { return {-v.y, v.x, v.z}; }\n\n// Pre-calculate all 24 possible 90-degree rotations\nvector<vector<Voxel>> get_rotations() {\n    set<vector<Voxel>> unique_rots;\n    vector<Voxel> unit_cube = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};\n    for (int i = 0; i < 4; ++i) {\n        for (int j = 0; j < 4; ++j) {\n            for (int k = 0; k < 4; ++k) {\n                vector<Voxel> current = unit_cube;\n                for (int ii = 0; ii < i; ++ii) for (auto& v : current) v = rotX(v);\n                for (int jj = 0; jj < j; ++jj) for (auto& v : current) v = rotY(v);\n                for (int kk = 0; kk < k; ++kk) for (auto& v : current) v = rotZ(v);\n                unique_rots.insert(current);\n            }\n        }\n    }\n    vector<vector<Voxel>> res;\n    for (auto& rot : unique_rots) res.push_back(rot);\n    return res;\n}\n\nint D;\nstring f1[14], r1[14], f2[14], r2[14];\n\nstruct State {\n    int r_idx;\n    int dx, dy, dz;\n    double score = 1e18;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> D)) return 0;\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    // Q1 and Q2 are the maximal sets of voxels satisfying the silhouette requirements\n    vector<Voxel> Q1, Q2;\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 (f1[z][x] == '1' && r1[z][y] == '1') Q1.push_back({x, y, z});\n                if (f2[z][x] == '1' && r2[z][y] == '1') Q2.push_back({x, y, z});\n            }\n        }\n    }\n\n    auto rots = get_rotations();\n    vector<vector<Voxel>> Q2_rots(rots.size());\n    for (int i = 0; i < rots.size(); ++i) {\n        for (auto& v : Q2) {\n            Voxel rv;\n            rv.x = v.x * rots[i][0].x + v.y * rots[i][1].x + v.z * rots[i][2].x;\n            rv.y = v.x * rots[i][0].y + v.y * rots[i][1].y + v.z * rots[i][2].y;\n            rv.z = v.x * rots[i][0].z + v.y * rots[i][1].z + v.z * rots[i][2].z;\n            Q2_rots[i].push_back(rv);\n        }\n    }\n\n    State best_state;\n    static bool q2_rot_grid[60][60][60];\n\n    for (int ri = 0; ri < (int)rots.size(); ++ri) {\n        int min_x = 100, max_x = -100, min_y = 100, max_y = -100, min_z = 100, max_z = -100;\n        for (auto& v : Q2_rots[ri]) {\n            min_x = min(min_x, v.x); max_x = max(max_x, v.x);\n            min_y = min(min_y, v.y); max_y = max(max_y, v.y);\n            min_z = min(min_z, v.z); max_z = max(max_z, v.z);\n        }\n        \n        for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid[i][j][k] = false;\n        for (auto& v : Q2_rots[ri]) q2_rot_grid[v.x + 30][v.y + 30][v.z + 30] = true;\n\n        for (int dx = -(max_x + 1); dx <= D - min_x; ++dx) {\n            for (int dy = -(max_y + 1); dy <= D - min_y; ++dy) {\n                for (int dz = -(max_z + 1); dz <= D - min_z; ++dz) {\n                    vector<Voxel> S;\n                    bool s_f1[14][14] = {false}, s_r1[14][14] = {false};\n                    bool s_f2[14][14] = {false}, s_r2[14][14] = {false};\n                    \n                    for (auto& v : Q1) {\n                        if (q2_rot_grid[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) {\n                            S.push_back(v);\n                            s_f1[v.z][v.x] = true;\n                            s_r1[v.z][v.y] = true;\n                            \n                            int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n                            int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n                            int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n                            s_f2[oz][ox] = true;\n                            s_r2[oz][oy] = true;\n                        }\n                    }\n                    if (S.empty()) continue;\n\n                    int n1 = 0, n2 = 0;\n                    for (int z = 0; z < D; ++z) {\n                        int uf1 = 0, ur1 = 0, uf2 = 0, ur2 = 0;\n                        for (int x = 0; x < D; ++x) if (f1[z][x] == '1' && !s_f1[z][x]) uf1++;\n                        for (int y = 0; y < D; ++y) if (r1[z][y] == '1' && !s_r1[z][y]) ur1++;\n                        n1 += max(uf1, ur1);\n                        for (int x = 0; x < D; ++x) if (f2[z][x] == '1' && !s_f2[z][x]) uf2++;\n                        for (int y = 0; y < D; ++y) if (r2[z][y] == '1' && !s_r2[z][y]) ur2++;\n                        n2 += max(uf2, ur2);\n                    }\n\n                    if (max(n1, n2) > best_state.score) continue;\n\n                    double sum1v = 0;\n                    vector<bool> visited(S.size(), false);\n                    for (int i = 0; i < (int)S.size(); ++i) {\n                        if (!visited[i]) {\n                            int count = 0;\n                            queue<int> q; q.push(i); visited[i] = true;\n                            while (!q.empty()) {\n                                int u = q.front(); q.pop();\n                                count++;\n                                for (int v = 0; v < (int)S.size(); ++v) {\n                                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                                        visited[v] = true; q.push(v);\n                                    }\n                                }\n                            }\n                            sum1v += 1.0 / count;\n                        }\n                    }\n\n                    if (max(n1, n2) + sum1v < best_state.score) {\n                        best_state = {ri, dx, dy, dz, max(n1, n2) + sum1v};\n                    }\n                }\n            }\n        }\n    }\n\n    // Finalize output with the best rotation and translation found\n    int ri = best_state.r_idx;\n    int dx = best_state.dx, dy = best_state.dy, dz = best_state.dz;\n    vector<Voxel> S;\n    static bool q2_rot_grid_final[60][60][60];\n    for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid_final[i][j][k] = false;\n    for (auto& v : Q2_rots[ri]) q2_rot_grid_final[v.x + 30][v.y + 30][v.z + 30] = true;\n    for (auto& v : Q1) if (q2_rot_grid_final[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) S.push_back(v);\n\n    static int b1[14][14][14], b2[14][14][14];\n    for (int i = 0; i < 14; ++i) for (int j = 0; j < 14; ++j) for (int k = 0; k < 14; ++k) b1[i][j][k] = b2[i][j][k] = 0;\n    int block_id = 1;\n\n    vector<bool> visited(S.size(), false);\n    for (int i = 0; i < (int)S.size(); ++i) {\n        if (!visited[i]) {\n            queue<int> q; q.push(i); visited[i] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                b1[S[u].x][S[u].y][S[u].z] = block_id;\n                int ox = (S[u].x - dx) * rots[ri][0].x + (S[u].y - dy) * rots[ri][0].y + (S[u].z - dz) * rots[ri][0].z;\n                int oy = (S[u].x - dx) * rots[ri][1].x + (S[u].y - dy) * rots[ri][1].y + (S[u].z - dz) * rots[ri][1].z;\n                int oz = (S[u].x - dx) * rots[ri][2].x + (S[u].y - dy) * rots[ri][2].y + (S[u].z - dz) * rots[ri][2].z;\n                b2[ox][oy][oz] = block_id;\n                for (int v = 0; v < (int)S.size(); ++v) {\n                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                        visited[v] = true; q.push(v);\n                    }\n                }\n            }\n            block_id++;\n        }\n    }\n\n    auto get_extra_voxels = [&](const vector<Voxel>& s, const string* f, const string* r) {\n        vector<Voxel> extra_voxels;\n        bool s_f[14][14] = {false}, s_r[14][14] = {false};\n        for (auto& v : s) { s_f[v.z][v.x] = true; s_r[v.z][v.y] = true; }\n        for (int z = 0; z < D; ++z) {\n            vector<int> uf, ur;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1' && !s_f[z][x]) uf.push_back(x);\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1' && !s_r[z][y]) ur.push_back(y);\n            if (uf.empty() && ur.empty()) continue;\n            int any_x = -1, any_y = -1;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1') { any_x = x; break; }\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1') { any_y = y; break; }\n            int m = max((int)uf.size(), (int)ur.size());\n            for (int i = 0; i < m; ++i) {\n                extra_voxels.push_back({(i < (int)uf.size()) ? uf[i] : any_x, (i < (int)ur.size()) ? ur[i] : any_y, z});\n            }\n        }\n        return extra_voxels;\n    };\n\n    vector<Voxel> S_in_Q2_orig;\n    for (auto& v : S) {\n        int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n        int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n        int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n        S_in_Q2_orig.push_back({ox, oy, oz});\n    }\n\n    auto extra1 = get_extra_voxels(S, f1, r1);\n    auto extra2 = get_extra_voxels(S_in_Q2_orig, f2, r2);\n\n    int k = min((int)extra1.size(), (int)extra2.size());\n    for (int i = 0; i < k; ++i) {\n        b1[extra1[i].x][extra1[i].y][extra1[i].z] = b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n    }\n    for (int i = k; i < (int)extra1.size(); ++i) b1[extra1[i].x][extra1[i].y][extra1[i].z] = block_id++;\n    for (int i = k; i < (int)extra2.size(); ++i) b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n\n    cout << block_id - 1 << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b1[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b2[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct MetricEdge {\n    int u, v;\n    long long dist;\n};\n\nstruct Vertex {\n    int x, y;\n};\n\nstruct Resident {\n    int a, b;\n};\n\nstruct VertexDist {\n    int id;\n    long long d2;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n + 1);\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    void reset(int n) {\n        for (int i = 0; i <= n; ++i) parent[i] = i;\n    }\n};\n\nlong long dist2_pts(int x1, int y1, int x2, int y2) {\n    return (long long)(x1 - x2) * (x1 - x2) + (long long)(y1 - y2) * (y1 - y2);\n}\n\nconst long long PENALTY = 1000000000000000LL;\n\nint main() {\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Vertex> vertices(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> vertices[i].x >> vertices[i].y;\n\n    vector<Edge> edges(M);\n    vector<vector<int>> adj(N + 1);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n\n    vector<Resident> residents(K);\n    for (int k = 0; k < K; ++k) cin >> residents[k].a >> residents[k].b;\n\n    // Precompute distances and shortest paths\n    vector<vector<long long>> dist(N + 1, vector<long long>(N + 1, 1e18));\n    for (int i = 1; i <= N; ++i) dist[i][i] = 0;\n    for (int j = 0; j < M; ++j) {\n        dist[edges[j].u][edges[j].v] = min(dist[edges[j].u][edges[j].v], (long long)edges[j].w);\n        dist[edges[j].v][edges[j].u] = min(dist[edges[j].v][edges[j].u], (long long)edges[j].w);\n    }\n\n    for (int k = 1; k <= N; ++k)\n        for (int i = 1; i <= N; ++i)\n            for (int j = 1; j <= N; ++j)\n                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n\n    vector<int> path_edges[101][101];\n    for (int i = 1; i <= N; ++i) {\n        for (int j = 1; j <= N; ++j) {\n            if (i == j) continue;\n            int curr = i;\n            while (curr != j) {\n                bool found = false;\n                for (int e_idx : adj[curr]) {\n                    int next = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);\n                    if ((long long)edges[e_idx].w + dist[next][j] == dist[curr][j]) {\n                        path_edges[i][j].push_back(e_idx);\n                        curr = next;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n    }\n\n    vector<vector<VertexDist>> sorted_v(K, vector<VertexDist>(N));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 1; i <= N; ++i) {\n            sorted_v[k][i - 1] = {i, dist2_pts(residents[k].a, residents[k].b, vertices[i].x, vertices[i].y)};\n        }\n        sort(sorted_v[k].begin(), sorted_v[k].end(), [](const VertexDist& a, const VertexDist& b) {\n            return a.d2 < b.d2;\n        });\n    }\n\n    vector<MetricEdge> all_metric_edges;\n    for (int i = 1; i <= N; ++i) {\n        for (int j = i + 1; j <= N; ++j) {\n            all_metric_edges.push_back({i, j, dist[i][j]});\n        }\n    }\n    sort(all_metric_edges.begin(), all_metric_edges.end(), [](const MetricEdge& a, const MetricEdge& b) {\n        return a.dist < b.dist;\n    });\n\n    // Simulated Annealing\n    vector<bool> is_active(N + 1, true);\n    vector<int> nearest_v(K);\n    vector<long long> best_d2(K);\n    for (int k = 0; k < K; ++k) {\n        nearest_v[k] = sorted_v[k][0].id;\n        best_d2[k] = sorted_v[k][0].d2;\n    }\n\n    auto get_cost = [&](const vector<bool>& active_flag, const vector<int>& near_v, const vector<long long>& b_d2, DSU& dsu) {\n        vector<long long> max_best_d2(N + 1, 0);\n        vector<bool> actually_active(N + 1, false);\n        actually_active[1] = true;\n        int actually_active_count = 1;\n        for (int k = 0; k < K; ++k) {\n            if (b_d2[k] > max_best_d2[near_v[k]]) max_best_d2[near_v[k]] = b_d2[k];\n            if (!actually_active[near_v[k]]) {\n                actually_active[near_v[k]] = true;\n                actually_active_count++;\n            }\n        }\n\n        long long tree_cost = 0;\n        if (actually_active_count > 1) {\n            static int used_step[305] = {0};\n            static int global_step = 0;\n            global_step++;\n            dsu.reset(N);\n            int components = actually_active_count;\n            for (auto& me : all_metric_edges) {\n                if (actually_active[me.u] && actually_active[me.v]) {\n                    if (dsu.unite(me.u, me.v)) {\n                        for (int e_idx : path_edges[me.u][me.v]) {\n                            if (used_step[e_idx] != global_step) {\n                                used_step[e_idx] = global_step;\n                                tree_cost += edges[e_idx].w;\n                            }\n                        }\n                        components--;\n                        if (components == 1) break;\n                    }\n                }\n            }\n        }\n\n        long long coverage_cost = 0;\n        for (int i = 1; i <= N; ++i) {\n            if (max_best_d2[i] > 0) {\n                int p = (int)sqrt(max_best_d2[i]);\n                while ((long long)p * p < max_best_d2[i]) p++;\n                if (p > 5000) coverage_cost += PENALTY;\n                else coverage_cost += (long long)p * p;\n            }\n        }\n        return coverage_cost + tree_cost;\n    };\n\n    DSU dsu(N);\n    long long cur_cost = get_cost(is_active, nearest_v, best_d2, dsu);\n    long long best_cost = cur_cost;\n    vector<bool> best_is_active = is_active;\n\n    mt19937 rng(42);\n    uniform_real_distribution<double> dist_unif(0, 1);\n    uniform_int_distribution<int> dist_v(2, N);\n\n    auto start_time = chrono::steady_clock::now();\n    double total_time_mu = 1850000.0;\n    double T_start = 1e7;\n    double T_end = 1e4;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::microseconds>(current_time - start_time).count();\n            if (elapsed > total_time_mu) break;\n            double progress = elapsed / total_time_mu;\n            double T = T_start * pow(T_end / T_start, progress);\n            \n            // Periodically accept best state to refine\n            // This is simple SA, so it's not needed, but can help\n        }\n        iter++;\n\n        int v = dist_v(rng);\n        vector<int> changed_k;\n        vector<int> old_near_v_val;\n        vector<long long> old_best_d2_val;\n\n        if (is_active[v]) {\n            is_active[v] = false;\n            for (int k = 0; k < K; ++k) {\n                if (nearest_v[k] == v) {\n                    changed_k.push_back(k);\n                    old_near_v_val.push_back(nearest_v[k]);\n                    old_best_d2_val.push_back(best_d2[k]);\n                    for (auto& p : sorted_v[k]) {\n                        if (is_active[p.id]) {\n                            nearest_v[k] = p.id;\n                            best_d2[k] = p.d2;\n                            break;\n                        }\n                    }\n                }\n            }\n        } else {\n            is_active[v] = true;\n            for (int k = 0; k < K; ++k) {\n                long long d2_new = dist2_pts(residents[k].a, residents[k].b, vertices[v].x, vertices[v].y);\n                if (d2_new < best_d2[k]) {\n                    changed_k.push_back(k);\n                    old_near_v_val.push_back(nearest_v[k]);\n                    old_best_d2_val.push_back(best_d2[k]);\n                    nearest_v[k] = v;\n                    best_d2[k] = d2_new;\n                }\n            }\n        }\n\n        long long new_cost = get_cost(is_active, nearest_v, best_d2, dsu);\n        double T = T_start * pow(T_end / T_start, (double)chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now() - start_time).count() / total_time_mu);\n        \n        if (new_cost < cur_cost || dist_unif(rng) < exp((double)(cur_cost - new_cost) / T)) {\n            cur_cost = new_cost;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_is_active = is_active;\n            }\n        } else {\n            // Rollback\n            is_active[v] = !is_active[v];\n            for (int i = 0; i < (int)changed_k.size(); ++i) {\n                nearest_v[changed_k[i]] = old_near_v_val[i];\n                best_d2[changed_k[i]] = old_best_d2_val[i];\n            }\n        }\n    }\n\n    // Final Tree generation from best state\n    is_active = best_is_active;\n    vector<long long> max_best_d2(N + 1, 0);\n    vector<int> near_v(K);\n    vector<long long> b_d2(K);\n    for (int k = 0; k < K; ++k) {\n        for (auto& p : sorted_v[k]) {\n            if (is_active[p.id]) {\n                near_v[k] = p.id;\n                b_d2[k] = p.d2;\n                break;\n            }\n        }\n        max_best_d2[near_v[k]] = max(max_best_d2[near_v[k]], b_d2[k]);\n    }\n\n    vector<bool> actually_active(N + 1, false);\n    actually_active[1] = true;\n    int actually_active_count = 1;\n    for (int i = 2; i <= N; ++i) {\n        if (is_active[i] && max_best_d2[i] > 0) {\n            actually_active[i] = true;\n            actually_active_count++;\n        }\n    }\n\n    vector<int> B(M, 0);\n    if (actually_active_count > 1) {\n        dsu.reset(N);\n        int components = actually_active_count;\n        for (auto& me : all_metric_edges) {\n            if (actually_active[me.u] && actually_active[me.v]) {\n                if (dsu.unite(me.u, me.v)) {\n                    for (int e_idx : path_edges[me.u][me.v]) B[e_idx] = 1;\n                    components--;\n                    if (components == 1) break;\n                }\n            }\n        }\n    }\n\n    // Cycle removal and refining reachable set\n    vector<Edge> tree_edges;\n    for (int j = 0; j < M; ++j) if (B[j]) tree_edges.push_back(edges[j]);\n    sort(tree_edges.begin(), tree_edges.end(), [](const Edge& a, const Edge& b) { return a.w < b.w; });\n    dsu.reset(N);\n    vector<int> final_B(M, 0);\n    for (auto& te : tree_edges) {\n        if (dsu.unite(te.u, te.v)) final_B[te.id] = 1;\n    }\n\n    vector<int> tree_v;\n    vector<int> q;\n    q.push_back(1);\n    vector<bool> visited(N + 1, false);\n    visited[1] = true;\n    int head = 0;\n    while(head < (int)q.size()){\n        int u = q[head++];\n        tree_v.push_back(u);\n        for(int e_idx : adj[u]){\n            if(final_B[e_idx]){\n                int v = (edges[e_idx].u == u ? edges[e_idx].v : edges[e_idx].u);\n                if(!visited[v]){\n                    visited[v] = true;\n                    q.push_back(v);\n                }\n            }\n        }\n    }\n\n    vector<int> final_P(N + 1, 0);\n    vector<long long> final_max_d2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        long long min_d2 = 1e18;\n        int best_v = -1;\n        for (int v : tree_v) {\n            long long d2_kv = dist2_pts(residents[k].a, residents[k].b, vertices[v].x, vertices[v].y);\n            if (d2_kv < min_d2) {\n                min_d2 = d2_kv;\n                best_v = v;\n            }\n        }\n        final_max_d2[best_v] = max(final_max_d2[best_v], min_d2);\n    }\n\n    for (int i = 1; i <= N; ++i) {\n        if (final_max_d2[i] > 0) {\n            int p = (int)sqrt(final_max_d2[i]);\n            while ((long long)p * p < final_max_d2[i]) p++;\n            final_P[i] = p;\n        }\n    }\n\n    // Leaf pruning\n    while (true) {\n        bool changed = false;\n        vector<int> degree(N + 1, 0);\n        for (int j = 0; j < M; ++j) if (final_B[j]) { degree[edges[j].u]++; degree[edges[j].v]++; }\n        for (int i = 2; i <= N; ++i) {\n            if (degree[i] == 1 && final_P[i] == 0) {\n                for (int j = 0; j < M; ++j) {\n                    if (final_B[j] && (edges[j].u == i || edges[j].v == i)) {\n                        final_B[j] = 0;\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    // Final Output\n    for (int i = 1; i <= N; ++i) {\n        cout << min(final_P[i], 5000) << (i == N ? \"\" : \" \");\n    }\n    cout << endl;\n    for (int j = 0; j < M; ++j) {\n        cout << final_B[j] << (j == M - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// The pyramid has N tiers, where N=30 for all inputs.\n// The total number of balls is num_balls = N*(N+1)/2 = 465.\nconst int N = 30;\nconst int num_balls = N * (N + 1) / 2;\n\nstruct Pos {\n    int x, y;\n};\n\nstruct Move {\n    int x1, y1, x2, y2;\n};\n\n// Global pyramid data to store the initial configuration.\nint initial_pyramid[N][N];\n\n// Check if a coordinate (x, y) is within the pyramid's triangular boundaries.\nbool isValid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y <= x;\n}\n\n// 6-directional adjacencies as defined in the problem.\nint dx[] = {-1, -1, 0, 0, 1, 1};\nint dy[] = {-1, 0, -1, 1, 0, 1};\n\n/**\n * A target position (x, y) for value v is an unsettled position whose ancestors\n * have all been settled with values from {0, ..., v-1}.\n * Settling values 0, 1, ..., v-1 first ensures the final pyramid satisfies\n * the required heap-like property.\n */\nbool is_target(int x, int y, const bool current_settled[N][N]) {\n    if (current_settled[x][y]) return false;\n    if (x == 0 && y == 0) return true;\n    if (y == 0) return current_settled[x - 1][0];\n    if (y == x) return current_settled[x - 1][x - 1];\n    return current_settled[x - 1][y - 1] && current_settled[x - 1][y];\n}\n\n// Global random engine to vary target and path selection across simulations.\nmt19937 rng(42);\n\nstruct SimulationResult {\n    int K;\n    vector<Move> moves;\n};\n\n/**\n * Runs a greedy simulation that settles values 0, 1, ..., 464 sequentially.\n * For each value v, it finds the nearest available target position using BFS\n * through unsettled positions and moves v there.\n */\nSimulationResult run_simulation() {\n    static int pyramid[N][N];\n    static Pos current_pos[num_balls];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            pyramid[i][j] = initial_pyramid[i][j];\n            current_pos[pyramid[i][j]] = {i, j};\n        }\n    }\n\n    static bool current_settled[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            current_settled[i][j] = false;\n        }\n    }\n\n    vector<Move> moves;\n    int total_K = 0;\n\n    for (int v = 0; v < num_balls; ++v) {\n        Pos start = current_pos[v];\n        // If the value is already at a target position, just settle it.\n        if (is_target(start.x, start.y, current_settled)) {\n            current_settled[start.x][start.y] = true;\n            continue;\n        }\n\n        // BFS to find all reachable target positions with minimum distance.\n        queue<Pos> q;\n        q.push(start);\n        static int d[N][N];\n        static Pos parent[N][N];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j <= i; ++j) {\n                d[i][j] = -1;\n            }\n        }\n        d[start.x][start.y] = 0;\n\n        int min_target_dist = 1e9;\n        vector<Pos> best_targets;\n\n        int indices[] = {0, 1, 2, 3, 4, 5};\n        while (!q.empty()) {\n            Pos curr = q.front();\n            q.pop();\n\n            // Once we have explored all nodes at min_target_dist, we can stop.\n            if (d[curr.x][curr.y] >= min_target_dist) break;\n\n            shuffle(indices, indices + 6, rng);\n            for (int i : indices) {\n                int nx = curr.x + dx[i];\n                int ny = curr.y + dy[i];\n                // Only move through unsettled positions.\n                if (isValid(nx, ny) && !current_settled[nx][ny] && d[nx][ny] == -1) {\n                    d[nx][ny] = d[curr.x][curr.y] + 1;\n                    parent[nx][ny] = curr;\n                    if (is_target(nx, ny, current_settled)) {\n                        if (d[nx][ny] < min_target_dist) {\n                            min_target_dist = d[nx][ny];\n                            best_targets = {{nx, ny}};\n                        } else if (d[nx][ny] == min_target_dist) {\n                            best_targets.push_back({nx, ny});\n                        }\n                    }\n                    // Continue BFS until we find at least one target.\n                    if (min_target_dist == 1e9) {\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n\n        if (best_targets.empty()) continue;\n\n        // Choose one of the closest target positions randomly.\n        Pos target = best_targets[rng() % best_targets.size()];\n        vector<Pos> path;\n        Pos temp = target;\n        while (temp.x != start.x || temp.y != start.y) {\n            path.push_back(temp);\n            temp = parent[temp.x][temp.y];\n        }\n        reverse(path.begin(), path.end());\n\n        // Perform the swaps along the shortest path.\n        for (Pos p : path) {\n            int v_other = pyramid[p.x][p.y];\n            moves.push_back({start.x, start.y, p.x, p.y});\n            swap(pyramid[start.x][start.y], pyramid[p.x][p.y]);\n            current_pos[v] = p;\n            current_pos[v_other] = start;\n            start = p;\n            total_K++;\n        }\n        current_settled[target.x][target.y] = true;\n    }\n\n    return {total_K, moves};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial pyramid configuration.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> initial_pyramid[i][j])) break;\n        }\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    SimulationResult best_res = {1000000, {}};\n\n    // Run as many simulations as possible within the 2.0s time limit.\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n        if (elapsed > 1.85) break;\n\n        SimulationResult res = run_simulation();\n        // Priority is to satisfy E=0 (satisfied by the algorithm) with minimal K.\n        if (res.K < best_res.K) {\n            best_res = res;\n        }\n    }\n\n    // Output the results of the best simulation found.\n    if (best_res.K <= 10000) {\n        cout << best_res.moves.size() << \"\\n\";\n        for (const auto& m : best_res.moves) {\n            cout << m.x1 << \" \" << m.y1 << \" \" << m.x2 << \" \" << m.y2 << \"\\n\";\n        }\n    } else {\n        // Fallback for safety (should not happen with given constraints).\n        cout << 0 << \"\\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// Warehouse dimensions and entrance position\nconst int D = 9;\nconst int ENTRANCE_I = 0;\nconst int ENTRANCE_J = (D - 1) / 2;\n\n// Structure to represent a square in the DxD warehouse\nstruct Square {\n    int i, j;\n    // Comparisons for use in std::set and algorithms\n    bool operator<(const Square& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Square& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint dist_bfs[D][D]; // Initial distances from the entrance\nint V[D][D];        // Computed importance rank for each square\nbool obstacle[D][D]; // Obstacle map\nint grid[D][D];      // Grid contents: -1 empty storage, -2 obstacle, -3 entrance, >=0 container ID\n\n// Function to precompute the \"importance rank\" V for each square\n// We simulate a removal process where we prioritize removing squares furthest from the entrance\n// that do not block other empty squares. This mirrors the ideal storage order (deep-to-shallow).\nvoid precalculate_V(int M) {\n    // 1. Initial BFS to calculate reachability distances from the entrance\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j)\n            dist_bfs[i][j] = -1;\n\n    queue<Square> q;\n    q.push({ENTRANCE_I, ENTRANCE_J});\n    dist_bfs[ENTRANCE_I][ENTRANCE_J] = 0;\n\n    int di[] = {-1, 1, 0, 0};\n    int dj[] = {0, 0, -1, 1};\n\n    while (!q.empty()) {\n        Square curr = q.front();\n        q.pop();\n        for (int k = 0; k < 4; ++k) {\n            int ni = curr.i + di[k];\n            int nj = curr.j + dj[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && dist_bfs[ni][nj] == -1) {\n                dist_bfs[ni][nj] = dist_bfs[curr.i][curr.j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // 2. Assign ranks V by simulating the storage process in reverse (as a removal process)\n    set<Square> E_v;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !(i == ENTRANCE_I && j == ENTRANCE_J)) {\n                E_v.insert({i, j});\n            }\n        }\n    }\n\n    // Assign rank from M-1 down to 0\n    for (int k = M - 1; k >= 0; --k) {\n        Square best_s = {-1, -1};\n        int max_dist = -1;\n\n        for (auto const& s : E_v) {\n            // Check if removing s keeps the remaining empty squares E_v \\ {s} connected to the entrance\n            int count = 0;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            \n            while (!q_safe.empty()) {\n                Square curr = q_safe.front();\n                q_safe.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int ni = curr.i + di[d];\n                    int nj = curr.j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && \n                        E_v.count({ni, nj}) && !visited[ni][nj] && !(ni == s.i && nj == s.j)) {\n                        visited[ni][nj] = true;\n                        q_safe.push({ni, nj});\n                        count++;\n                    }\n                }\n            }\n            \n            // If all other squares in E_v are reached, s is \"safe\" to pick as a leaf square\n            if (count == (int)E_v.size() - 1) {\n                if (dist_bfs[s.i][s.j] > max_dist) {\n                    max_dist = dist_bfs[s.i][s.j];\n                    best_s = s;\n                } else if (dist_bfs[s.i][s.j] == max_dist) {\n                    if (s.i * D + s.j > best_s.i * D + best_s.j) {\n                        best_s = s;\n                    }\n                }\n            }\n        }\n        \n        V[best_s.i][best_s.j] = k; // Rank in the \"ideal\" removal order\n        E_v.erase(best_s);\n    }\n}\n\nint main() {\n    // Faster I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) obstacle[i][j] = false;\n    }\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n\n    int M = D * D - 1 - N; // Total number of containers\n    precalculate_V(M);\n\n    vector<int> remaining_t;\n    for (int i = 0; i < M; ++i) remaining_t.push_back(i);\n\n    set<Square> E; // Currently empty storage squares\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == ENTRANCE_I && j == ENTRANCE_J) grid[i][j] = -3;\n            else if (obstacle[i][j]) grid[i][j] = -2;\n            else {\n                grid[i][j] = -1;\n                E.insert({i, j});\n            }\n        }\n    }\n\n    // Online Storage Phase\n    for (int d = 0; d < M; ++d) {\n        int t_d;\n        cin >> t_d;\n\n        // Calculate the percentile rank of the current container value among all remaining ones\n        int t_rank = 0;\n        for (int t : remaining_t) if (t < t_d) t_rank++;\n\n        // Identify reachable empty squares that are also \"safe\" (don't block other empty squares)\n        vector<Square> safe_reachable;\n        for (auto const& s : E) {\n            int count = 0;\n            bool s_reachable = false;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            \n            int di[] = {-1, 1, 0, 0};\n            int dj[] = {0, 0, -1, 1};\n\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front();\n                q_safe.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int ni = curr.i + di[k];\n                    int nj = curr.j + dj[k];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] != -2 && !visited[ni][nj]) {\n                        if (E.count({ni, nj})) {\n                            if (ni == s.i && nj == s.j) {\n                                s_reachable = true;\n                            } else {\n                                visited[ni][nj] = true;\n                                q_safe.push({ni, nj});\n                                count++;\n                            }\n                        } else if (grid[ni][nj] == -3) { // Through entrance\n                            visited[ni][nj] = true;\n                            q_safe.push({ni, nj});\n                        }\n                    }\n                }\n            }\n            if (s_reachable && count == (int)E.size() - 1) safe_reachable.push_back(s);\n        }\n\n        // Pick the safe reachable square whose V rank best matches the container value's t rank\n        Square best_s = {-1, -1};\n        int min_diff = 1e9;\n        for (auto const& s : safe_reachable) {\n            int v_rank = 0;\n            for (auto const& other : E) if (V[other.i][other.j] < V[s.i][s.j]) v_rank++;\n            if (abs(v_rank - t_rank) < min_diff) {\n                min_diff = abs(v_rank - t_rank);\n                best_s = s;\n            } else if (abs(v_rank - t_rank) == min_diff) {\n                if (V[s.i][s.j] > V[best_s.i][best_s.j]) best_s = s;\n            }\n        }\n        \n        if (best_s.i == -1) best_s = *E.begin(); // Fallback (should not occur)\n\n        // Store the container and update state\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = t_d;\n        E.erase(best_s);\n        remaining_t.erase(remove(remaining_t.begin(), remaining_t.end(), t_d), remaining_t.end());\n    }\n\n    // Offline Removal Phase\n    for (int d = 0; d < M; ++d) {\n        vector<Square> reachable_containers;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<Square> q;\n        q.push({ENTRANCE_I, ENTRANCE_J});\n        visited[ENTRANCE_I][ENTRANCE_J] = true;\n        int di[] = {-1, 1, 0, 0};\n        int dj[] = {0, 0, -1, 1};\n\n        // Determine which containers are currently reachable from the entrance\n        while (!q.empty()) {\n            Square curr = q.front();\n            q.pop();\n            for (int k = 0; k < 4; ++k) {\n                int ni = curr.i + di[k];\n                int nj = curr.j + dj[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] != -2) {\n                    if (grid[ni][nj] >= 0) {\n                        reachable_containers.push_back({ni, nj});\n                        visited[ni][nj] = true; // Cannot pass through another container\n                    } else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Pick and remove the reachable container with the smallest value to minimize inversions\n        Square best_s = {-1, -1};\n        int min_t = 1e9;\n        for (auto const& s : reachable_containers) {\n            if (grid[s.i][s.j] < min_t) {\n                min_t = grid[s.i][s.j];\n                best_s = s;\n            }\n        }\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = -1; // Square is now empty storage\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// The grid size is 50x50 and number of wards is 100 according to problem description.\nconst int N_MAX = 50;\nconst int M_MAX = 100;\n\nint grid[N_MAX][N_MAX];\nbool adj[M_MAX + 1][M_MAX + 1];\nint count_adj[M_MAX + 1][M_MAX + 1];\nint dx[] = {0, 0, 1, -1};\nint dy[] = {1, -1, 0, 0};\n\nint visit_token = 0;\nint visited[N_MAX][N_MAX];\n\n// Check if a grid cell is on the boundary.\nbool is_on_boundary(int i, int j, int n) {\n    return i == 0 || i == n - 1 || j == 0 || j == n - 1;\n}\n\n// Check if a square can be safely changed to color 0 without violating the constraints.\nbool can_remove(int r, int c_col, int n, int m) {\n    int color = grid[r][c_col];\n    if (color == 0) return false;\n\n    int n_adj_c_square[M_MAX + 1] = {0};\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n            int d = grid[ni][nj];\n            // If any neighbor d is not adjacent to 0 originally, it cannot become adjacent now.\n            if (d > 0 && !adj[d][0]) return false;\n            n_adj_c_square[d]++;\n        } else {\n            // Outside the grid is considered color 0.\n            n_adj_c_square[0]++;\n        }\n    }\n\n    // Color 0 must remain connected. To ensure this, every component of color 0 squares\n    // must touch the boundary. Changing (r, c_col) to 0 only maintains this if it already \n    // touches the boundary or an existing 0-square.\n    if (n_adj_c_square[0] == 0) return false;\n\n    // Adjacency relationships between all pairs of colors (including color 0) must be identical.\n    for (int d = 0; d <= m; d++) {\n        if (d == color) continue;\n        if (adj[color][d]) {\n            int new_count_adj_color_d = count_adj[color][d] - n_adj_c_square[d];\n            // Adjacency between ward 'color' and color 0 is maintained if there's either \n            // another existing edge to 0, or if one of the ward's squares becomes adjacent\n            // to the new 0 at (r, c_col).\n            if (d == 0) new_count_adj_color_d += n_adj_c_square[color];\n            if (new_count_adj_color_d <= 0) return false;\n        }\n    }\n\n    // Ward 'color' must remain a single connected set of squares.\n    static vector<pair<int, int>> neighbors;\n    neighbors.clear();\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == color) {\n            neighbors.push_back({ni, nj});\n        }\n    }\n\n    if (neighbors.size() > 1) {\n        visit_token++;\n        static vector<pair<int, int>> q;\n        q.clear();\n        q.push_back(neighbors[0]);\n        visited[neighbors[0].first][neighbors[0].second] = visit_token;\n        visited[r][c_col] = visit_token; // Act as a barrier during BFS\n        int head = 0;\n        while(head < q.size()){\n            pair<int, int> curr = q[head++];\n            for(int k=0; k<4; k++){\n                int ni = curr.first + dx[k], nj = curr.second + dy[k];\n                if(ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == color && visited[ni][nj] != visit_token){\n                    visited[ni][nj] = visit_token;\n                    q.push_back({ni, nj});\n                }\n            }\n        }\n        // If not all same-color neighbors are reachable from one another, connectivity is broken.\n        for (size_t i = 1; i < neighbors.size(); i++) {\n            if (visited[neighbors[i].first][neighbors[i].second] != visit_token) return false;\n        }\n    }\n\n    return true;\n}\n\n// Perform the change and update the adjacency edge counts.\nvoid change_to_0(int r, int c_col, int n, int m) {\n    int color = grid[r][c_col];\n    int n_adj_c_square[M_MAX + 1] = {0};\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n            n_adj_c_square[grid[ni][nj]]++;\n        } else {\n            n_adj_c_square[0]++;\n        }\n    }\n\n    for (int d = 0; d <= m; d++) {\n        if (n_adj_c_square[d] > 0) {\n            count_adj[color][d] -= n_adj_c_square[d];\n            count_adj[d][color] -= n_adj_c_square[d];\n            count_adj[0][d] += n_adj_c_square[d];\n            count_adj[d][0] += n_adj_c_square[d];\n        }\n    }\n    grid[r][c_col] = 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Record original adjacencies between colors.\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (is_on_boundary(i, j, n)) {\n                adj[grid[i][j]][0] = true;\n                adj[0][grid[i][j]] = true;\n            }\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k], nj = j + dy[k];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    if (grid[i][j] != grid[ni][nj]) {\n                        adj[grid[i][j]][grid[ni][nj]] = true;\n                        adj[grid[ni][nj]][grid[i][j]] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Pre-calculate the number of adjacent edges between color pairs.\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k], nj = j + dy[k];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    count_adj[grid[i][j]][grid[ni][nj]]++;\n                } else {\n                    count_adj[grid[i][j]][0]++;\n                    count_adj[0][grid[i][j]]++;\n                }\n            }\n        }\n    }\n\n    // Iteratively try to replace squares with color 0.\n    vector<int> square_indices(n * n);\n    iota(square_indices.begin(), square_indices.end(), 0);\n    mt19937 rng(42);\n\n    auto start_time = chrono::steady_clock::now();\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) break;\n\n        shuffle(square_indices.begin(), square_indices.end(), rng);\n        bool changed_in_this_pass = false;\n        for (int idx : square_indices) {\n            int r = idx / n;\n            int c = idx % n;\n            if (grid[r][c] > 0 && can_remove(r, c, n, m)) {\n                change_to_0(r, c, n, m);\n                changed_in_this_pass = true;\n            }\n        }\n        if (!changed_in_this_pass) break;\n    }\n\n    // Output final grid.\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 <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// This heuristic algorithm solves a weight-partitioning problem with unknown weights.\n// It proceeds in three phases:\n// 1. Estimate weights by sorting items using as many queries as feasible (MergeSort).\n// 2. Perform an initial multi-way number partitioning using the estimated weights (LPT algorithm).\n// 3. Refine the partition through Hill Climbing, leveraging the remaining balance queries \n//    to compare and improve the sets iteratively.\n\nint N, D, Q;\nint q_count = 0;\n\n// Standard balance query function. Increments the global query count.\n// Must be followed by exactly Q queries.\nchar query(const vector<int>& L, const vector<int>& R) {\n    if (q_count >= Q) return '=';\n    if (L.empty() || R.empty()) {\n        q_count++;\n        // Should not happen under regular circumstances; used for robustness.\n        cout << \"1 1 0 1\" << endl;\n        char res;\n        cin >> res;\n        return '=';\n    }\n    q_count++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res;\n    cin >> res;\n    return res;\n}\n\n// Custom Merge helper for MergeSort, utilizing weight-comparison queries.\nvoid merge(vector<int>& arr, int l, int m, int r, int Q_limit) {\n    vector<int> left(arr.begin() + l, arr.begin() + m);\n    vector<int> right(arr.begin() + m, arr.begin() + r);\n    int i = 0, j = 0, k = l;\n    while (i < (int)left.size() && j < (int)right.size()) {\n        if (q_count < Q_limit) {\n            char res = query({left[i]}, {right[j]});\n            if (res == '<') arr[k++] = left[i++];\n            else arr[k++] = right[j++];\n        } else {\n            // If queries are exhausted, use index as a fallback to keep sorting deterministic.\n            if (left[i] < right[j]) arr[k++] = left[i++];\n            else arr[k++] = right[j++];\n        }\n    }\n    while (i < (int)left.size()) arr[k++] = left[i++];\n    while (j < (int)right.size()) arr[k++] = right[j++];\n}\n\n// Divide-and-conquer MergeSort implementation.\nvoid merge_sort(vector<int>& arr, int l, int r, int Q_limit) {\n    if (r - l <= 1) return;\n    int m = l + (r - l) / 2;\n    merge_sort(arr, l, m, Q_limit);\n    merge_sort(arr, m, r, Q_limit);\n    merge(arr, l, m, r, Q_limit);\n}\n\nint main() {\n    // Read input parameters. Standard input is used.\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n\n    // Limit sorting queries to leave room for partition refinement.\n    int Q_sort = Q - D;\n    if (Q > 10 * N) Q_sort = min(Q - 2 * D, 1000); \n    if (Q_sort < 0) Q_sort = 0;\n\n    // Sorting phase.\n    merge_sort(items, 0, N, Q_sort);\n\n    vector<double> hat_w(N);\n    double cur_h = 0;\n    // Estimate weights based on Order Statistics of an Exponential Distribution.\n    // E[w_(k)] = sum_{j=0}^{k} 1/(N-j).\n    for (int i = 0; i < N; ++i) {\n        cur_h += 1.0 / (N - i);\n        hat_w[items[i]] = cur_h;\n    }\n\n    vector<vector<int>> sets(D);\n    vector<double> set_w(D, 0);\n    vector<int> sorted_indices(N);\n    iota(sorted_indices.begin(), sorted_indices.end(), 0);\n    // Sort items by descending estimated weight for LPT.\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return hat_w[a] > hat_w[b];\n    });\n\n    // LPT (Longest Processing Time) greedy initial partition.\n    for (int i : sorted_indices) {\n        int best_set = 0;\n        for (int j = 1; j < D; ++j) {\n            if (set_w[j] < set_w[best_set]) best_set = j;\n        }\n        sets[best_set].push_back(i);\n        set_w[best_set] += hat_w[i];\n    }\n\n    mt19937 rng(42);\n    // Hill Climbing Refinement Phase.\n    while (q_count < Q) {\n        int a, b;\n        // Strategies to pick sets to compare: prioritized unbalanced sets (70%) or random (30%).\n        if (rng() % 10 < 7) {\n            a = 0; b = 0;\n            for (int i = 0; i < D; ++i) {\n                if (set_w[i] > set_w[a]) a = i;\n                if (set_w[i] < set_w[b]) b = i;\n            }\n            if (a == b) { \n                a = rng() % D; \n                b = (a + 1 + rng() % (D - 1)) % D; \n            }\n        } else {\n            a = rng() % D;\n            b = (a + 1 + rng() % (D - 1)) % D;\n        }\n\n        if (sets[a].empty() || sets[b].empty()) {\n            query({items[0]}, {items[1]});\n            continue;\n        }\n\n        // Query which set is heavier.\n        char res = query(sets[a], sets[b]);\n        if (res == '=') continue;\n        int heavy = (res == '>') ? a : b;\n        int light = (res == '>') ? b : a;\n\n        // Dynamic update of estimated weights if the query results contradict current estimates.\n        if (set_w[heavy] < set_w[light]) {\n            double factor = 1.1;\n            for (int idx : sets[heavy]) hat_w[idx] *= factor;\n            for (int idx : sets[light]) hat_w[idx] /= factor;\n            for (int i = 0; i < D; ++i) {\n                double sw = 0;\n                for (int idx : sets[i]) sw += hat_w[idx];\n                set_w[i] = sw;\n            }\n        }\n\n        double current_diff = set_w[heavy] - set_w[light];\n        double best_new_diff = current_diff;\n        int move_item = -1;\n        int swap_heavy = -1, swap_light = -1;\n\n        // Search for an item move from the heavy set to the light set that improves balance.\n        if (sets[heavy].size() > 1) {\n            for (int i = 0; i < (int)sets[heavy].size(); ++i) {\n                int x = sets[heavy][i];\n                double new_diff = abs((set_w[heavy] - hat_w[x]) - (set_w[light] + hat_w[x]));\n                if (new_diff < best_new_diff) {\n                    best_new_diff = new_diff;\n                    move_item = i;\n                    swap_heavy = -1;\n                }\n            }\n        }\n        // Search for a swap between sets that improves balance.\n        for (int i = 0; i < (int)sets[heavy].size(); ++i) {\n            for (int j = 0; j < (int)sets[light].size(); ++j) {\n                int x = sets[heavy][i];\n                int y = sets[light][j];\n                double new_diff = abs((set_w[heavy] - hat_w[x] + hat_w[y]) - (set_w[light] - hat_w[y] + hat_w[x]));\n                if (new_diff < best_new_diff) {\n                    best_new_diff = new_diff;\n                    move_item = -1;\n                    swap_heavy = i;\n                    swap_light = j;\n                }\n            }\n        }\n\n        // Apply the move or swap if a better balance is estimated.\n        if (move_item != -1) {\n            int x = sets[heavy][move_item];\n            sets[light].push_back(x);\n            sets[heavy].erase(sets[heavy].begin() + move_item);\n            set_w[heavy] -= hat_w[x];\n            set_w[light] += hat_w[x];\n        } else if (swap_heavy != -1) {\n            int x = sets[heavy][swap_heavy];\n            int y = sets[light][swap_light];\n            sets[heavy][swap_heavy] = y;\n            sets[light][swap_light] = x;\n            set_w[heavy] = set_w[heavy] - hat_w[x] + hat_w[y];\n            set_w[light] = set_w[light] - hat_w[y] + hat_w[x];\n        }\n    }\n\n    // Prepare and output final item-to-set assignment.\n    vector<int> d(N);\n    for (int i = 0; i < D; ++i) {\n        for (int x : sets[i]) d[x] = i;\n    }\n    for (int i = 0; i < N; ++i) {\n        cout << d[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\n/**\n * The problem involves moving cardboard boxes divided into several stacks to carry them out in \n * ascending order (1, 2, ..., n). Each move of k boxes costs k+1 energy. The objective is to\n * minimize the total energy expended within 5000 operations.\n * \n * Our strategy is a greedy approach that simulates the extraction process multiple times\n * with varying heuristic parameters (thresholds for splitting blocks and empty-stack penalties) \n * to find the sequence of operations with the minimum energy expenditure.\n * \n * For each box v from 1 to n:\n * 1. Locate the stack containing box v.\n * 2. If v is not at the top, we must move all boxes above it.\n * 3. We divide the block of boxes above v into \"well-ordered\" sub-blocks. A sub-block is considered\n *    well-ordered if its boxes are in descending order from bottom to top, as this avoids \n *    future internal moves.\n * 4. We move each sub-block (from top to bottom) to another stack using a penalty-based \n *    heuristic that considers potential blocking of existing boxes and current stack height.\n * 5. Finally, we carry out box v.\n */\n\n// Move represents either a relocation of a block of boxes to another stack (i > 0)\n// or carrying out a box (i = 0).\nstruct Move {\n    int v, i;\n};\n\n// State stores the current configuration of boxes in stacks and handles simulation of operations.\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<int> box_to_stack;\n    vector<Move> moves;\n    long long energy;\n\n    State(int n, int m, const vector<vector<int>>& initial_stacks) \n        : n(n), m(m), stacks(initial_stacks), energy(0) {\n        box_to_stack.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            for (int v : stacks[i]) {\n                box_to_stack[v] = i;\n            }\n        }\n    }\n\n    // Moves box v and all boxes currently above it to the specified destination stack.\n    void move_block(int v, int dest_stack_idx) {\n        int src_stack_idx = box_to_stack[v];\n        if (src_stack_idx == dest_stack_idx) return;\n\n        auto& src_stack = stacks[src_stack_idx];\n        auto& dest_stack = stacks[dest_stack_idx];\n\n        int pos = -1;\n        for (int i = 0; i < (int)src_stack.size(); ++i) {\n            if (src_stack[i] == v) {\n                pos = i;\n                break;\n            }\n        }\n\n        int k = (int)src_stack.size() - pos;\n        energy += (k + 1);\n        moves.push_back({v, dest_stack_idx + 1});\n\n        for (int i = pos; i < (int)src_stack.size(); ++i) {\n            box_to_stack[src_stack[i]] = dest_stack_idx;\n            dest_stack.push_back(src_stack[i]);\n        }\n        src_stack.resize(pos);\n    }\n\n    // Carries out the smallest remaining box from the top of its stack.\n    void carry_out(int v) {\n        int s_idx = box_to_stack[v];\n        stacks[s_idx].pop_back();\n        moves.push_back({v, 0});\n    }\n};\n\n/**\n * Simulates carrying out all boxes for a given splitting threshold and empty-stack penalty value.\n * threshold: Controls how blocks are split. A block [u_i-1, u_i] splits if u_i-1 - u_i < threshold.\n * empty_val: A heuristic value used as a virtual 'top box' for empty stacks.\n */\nlong long simulate(int n, int m, const vector<vector<int>>& initial_stacks, int threshold, int empty_val, vector<Move>& out_moves) {\n    State state(n, m, initial_stacks);\n    for (int v = 1; v <= n; ++v) {\n        int s_idx = state.box_to_stack[v];\n        \n        // If the target box v is not at the top, clear boxes above it.\n        if (state.stacks[s_idx].back() != v) {\n            vector<int> B;\n            auto& s = state.stacks[s_idx];\n            int pos = -1;\n            for (int i = 0; i < (int)s.size(); ++i) {\n                if (s[i] == v) {\n                    pos = i;\n                    break;\n                }\n            }\n            for (int i = pos + 1; i < (int)s.size(); ++i) {\n                B.push_back(s[i]);\n            }\n\n            // Split the block of boxes B above v into several sub-blocks based on the threshold.\n            vector<vector<int>> blocks;\n            if (!B.empty()) {\n                vector<int> current_block = {B[0]};\n                for (int i = 1; i < (int)B.size(); ++i) {\n                    if (B[i-1] - B[i] < threshold) {\n                        blocks.push_back(current_block);\n                        current_block = {B[i]};\n                    } else {\n                        current_block.push_back(B[i]);\n                    }\n                }\n                blocks.push_back(current_block);\n            }\n\n            // Move each sub-block (from top to bottom) to its best destination stack.\n            for (int i = (int)blocks.size() - 1; i >= 0; --i) {\n                int bottom_v = blocks[i][0];\n                int best_dest = -1;\n                long long min_penalty = LLONG_MAX;\n                \n                for (int d = 0; d < m; ++d) {\n                    if (d == s_idx) continue;\n                    long long penalty = 0;\n                    int count_smaller = 0;\n                    for (int x : state.stacks[d]) {\n                        if (x < bottom_v) count_smaller++;\n                    }\n                    \n                    if (count_smaller == 0) {\n                        // Ideal case: placing on boxes larger than everything in the current block.\n                        int top_val = state.stacks[d].empty() ? empty_val : state.stacks[d].back();\n                        penalty = (long long)top_val - bottom_v;\n                    } else {\n                        // Sub-optimal case: blocks an existing smaller box, requiring a future move.\n                        penalty = 1000000LL * count_smaller + state.stacks[d].size();\n                    }\n                    \n                    if (penalty < min_penalty) {\n                        min_penalty = penalty;\n                        best_dest = d;\n                    }\n                }\n                state.move_block(bottom_v, best_dest);\n            }\n        }\n        state.carry_out(v);\n    }\n    out_moves = state.moves;\n    return state.energy;\n}\n\nint main() {\n    // Standard I/O optimization.\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    // Read the initial stack configurations.\n    vector<vector<int>> initial_stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int b; cin >> b;\n            initial_stacks[i].push_back(b);\n        }\n    }\n\n    long long min_energy = LLONG_MAX;\n    vector<Move> best_moves;\n\n    // Explore a range of threshold and empty_val values to find the best heuristic result.\n    // The number of boxes n is fixed at 200, so a simulation of ~200 simulations is efficient.\n    for (int threshold = -20; threshold <= 30; threshold++) {\n        for (int empty_val : {201, 300, 400}) {\n            vector<Move> current_moves;\n            long long energy = simulate(n, m, initial_stacks, threshold, empty_val, current_moves);\n            \n            // Track the best operation sequence found.\n            if (energy < min_energy) {\n                min_energy = energy;\n                best_moves = current_moves;\n            }\n        }\n    }\n\n    // Output the final operation sequence.\n    for (const auto& move : best_moves) {\n        cout << move.v << \" \" << move.i << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n// Maximum size of the board as per problem description\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\n\nstruct Edge {\n    int u, v;\n};\n\n// Global structures to store the adjacency list and edges of the graph\nvector<Edge> all_edges;\nbool is_in_tree[MAXN * MAXN][MAXN * MAXN];\nint parent_in_tree[MAXN * MAXN];\nint subtree_size[MAXN * MAXN];\nvector<int> tree_adj[MAXN * MAXN];\n\n// Perform DFS to compute subtree sizes for each node in the spanning tree\nvoid dfs_size(int u, int p) {\n    parent_in_tree[u] = p;\n    subtree_size[u] = 1;\n    for (int next_u : tree_adj[u]) {\n        if (next_u != p) {\n            dfs_size(next_u, u);\n            subtree_size[u] += subtree_size[next_u];\n        }\n    }\n}\n\n// Calculate the quality score of the current spanning tree based on dirtiness and subtree distribution.\n// The average dirtiness S is related to the sum of squares of the gaps between visits to each square.\n// For a DFS tour on a spanning tree, the gaps between visits to node u are twice the sizes of the \n// components formed by removing u from the tree.\nlong long compute_total_score() {\n    long long total = 0;\n    int total_nodes = N * N;\n    for (int u = 0; u < total_nodes; ++u) {\n        long long node_sum_s2 = 0;\n        for (int next_u : tree_adj[u]) {\n            if (next_u == parent_in_tree[u]) {\n                // The size of the component \"above\" node u\n                int s = total_nodes - subtree_size[u];\n                node_sum_s2 += (long long)s * s;\n            } else {\n                // The size of the subtree rooted at node u\n                int s = subtree_size[next_u];\n                node_sum_s2 += (long long)s * s;\n            }\n        }\n        total += (long long)d[u / N][u % N] * node_sum_s2;\n    }\n    return total;\n}\n\n// Helper to find the path from a given node to the root (0,0) in the tree\nvector<int> get_path_to_root(int u) {\n    vector<int> path;\n    while (u != -1) {\n        path.push_back(u);\n        u = parent_in_tree[u];\n    }\n    return path;\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read problem input\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\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    // Identify all possible edges between grid squares not separated by a wall\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = (i + 1) * N + j;\n                all_edges.push_back({u, vv});\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = i * N + (j + 1);\n                all_edges.push_back({u, vv});\n            }\n        }\n    }\n\n    // Generate an initial random spanning tree using Kruskal's algorithm\n    mt19937 rng(42);\n    vector<Edge> edges = all_edges;\n    shuffle(edges.begin(), edges.end(), rng);\n    vector<int> dsu(N * N);\n    for (int i = 0; i < N * N; ++i) dsu[i] = i;\n    auto dsu_find = [&](auto self, int i) -> int {\n        return dsu[i] == i ? i : dsu[i] = self(self, dsu[i]);\n    };\n    for (auto& e : edges) {\n        int root_u = dsu_find(dsu_find, e.u);\n        int root_v = dsu_find(dsu_find, e.v);\n        if (root_u != root_v) {\n            dsu[root_u] = root_v;\n            is_in_tree[e.u][e.v] = is_in_tree[e.v][e.u] = true;\n            tree_adj[e.u].push_back(e.v);\n            tree_adj[e.v].push_back(e.u);\n        }\n    }\n\n    // Initial score of the spanning tree\n    dfs_size(0, -1);\n    long long current_score = compute_total_score();\n\n    // Simulated Annealing parameters\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    const double TIME_LIMIT = 1.9; // Target time limit for SA process\n    double start_temp = 1e7;\n    double end_temp = 1e3;\n\n    // Run Simulated Annealing to optimize the spanning tree structure\n    while (true) {\n        // Occasionally check elapsed time\n        if (iterations % 256 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n        }\n        iterations++;\n\n        // Select a non-tree edge and add it to form a cycle\n        int e_idx = uniform_int_distribution<int>(0, all_edges.size() - 1)(rng);\n        Edge e_in = all_edges[e_idx];\n        if (is_in_tree[e_in.u][e_in.v]) continue;\n\n        // Trace paths to find the cycle formed by adding e_in\n        vector<int> path_u = get_path_to_root(e_in.u);\n        vector<int> path_v = get_path_to_root(e_in.v);\n        int iu = path_u.size() - 1, iv = path_v.size() - 1;\n        while (iu >= 0 && iv >= 0 && path_u[iu] == path_v[iv]) {\n            iu--; iv--;\n        }\n        vector<Edge> cycle;\n        for (int i = 0; i <= iu; ++i) cycle.push_back({path_u[i], parent_in_tree[path_u[i]]});\n        for (int i = 0; i <= iv; ++i) cycle.push_back({path_v[i], parent_in_tree[path_v[i]]});\n        cycle.push_back({e_in.u, e_in.v});\n\n        // Select a random edge from the cycle to remove, maintaining a spanning tree\n        int e_out_idx = uniform_int_distribution<int>(0, cycle.size() - 2)(rng);\n        Edge e_out = cycle[e_out_idx];\n\n        // Perform the edge swap (Remove e_out, Add e_in)\n        is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = false;\n        tree_adj[e_out.u].erase(remove(tree_adj[e_out.u].begin(), tree_adj[e_out.u].end(), e_out.v), tree_adj[e_out.u].end());\n        tree_adj[e_out.v].erase(remove(tree_adj[e_out.v].begin(), tree_adj[e_out.v].end(), e_out.u), tree_adj[e_out.v].end());\n        is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = true;\n        tree_adj[e_in.u].push_back(e_in.v);\n        tree_adj[e_in.v].push_back(e_in.u);\n\n        // Recompute sizes and the new tree's score\n        dfs_size(0, -1);\n        long long next_score = compute_total_score();\n\n        // SA Acceptance Criteria\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n        double progress = min(1.0, elapsed / TIME_LIMIT);\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        if (next_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - next_score) / T)) {\n            current_score = next_score;\n        } else {\n            // Revert swap if not accepted\n            is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = false;\n            tree_adj[e_in.u].erase(remove(tree_adj[e_in.u].begin(), tree_adj[e_in.u].end(), e_in.v), tree_adj[e_in.u].end());\n            tree_adj[e_in.v].erase(remove(tree_adj[e_in.v].begin(), tree_adj[e_in.v].end(), e_in.u), tree_adj[e_in.v].end());\n            is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = true;\n            tree_adj[e_out.u].push_back(e_out.v);\n            tree_adj[e_out.v].push_back(e_out.u);\n            dfs_size(0, -1);\n        }\n    }\n\n    // Generate the final cleaning tour by performing a DFS on the optimized spanning tree.\n    string tour = \"\";\n    auto get_dir = [&](int u, int v) {\n        int r1 = u / N, c1 = u % N;\n        int r2 = v / N, c2 = v % N;\n        if (r1 < r2) return 'D';\n        if (r1 > r2) return 'U';\n        if (c1 < c2) return 'R';\n        return 'L';\n    };\n    auto dfs_tour_gen = [&](auto self, int u, int p) -> void {\n        for (int next_u : tree_adj[u]) {\n            if (next_u != p) {\n                tour += get_dir(u, next_u);\n                self(self, next_u, u);\n                tour += get_dir(next_u, u);\n            }\n        }\n    };\n    dfs_tour_gen(dfs_tour_gen, 0, -1);\n\n    // Output the resulting cleaning route\n    cout << tour << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We are typing on a 15x15 keyboard to form a superstring containing all 200 lucky words.\n * - Each operation (typing a key) costs Manhattan distance + 1.\n * - The number of operations is limited to 5000, and we want to minimize the total cost.\n * - This is essentially a variation of the Shortest Superstring Problem combined with a TSP-like distance cost.\n *\n * Algorithm Strategy:\n * 1. Precompute the maximum possible overlap between every pair of lucky strings.\n * 2. Precompute the minimum typing cost for suffixes of strings given starting key positions.\n * 3. Use these precomputed costs to define a TSP distance matrix that prioritizes string overlaps.\n * 4. Solve the TSP using a combination of a Greedy Initial Path and Simulated Annealing (2-opt).\n * 5. Construct the resulting superstring from the TSP order.\n * 6. Use dynamic programming to choose the optimal grid position for each character in the superstring to minimize total distance.\n */\n\nint N = 15, M = 200;\nint si, sj;\nvector<string> A;\nvector<string> T_str;\nvector<int> pos_of_char[26];\n\n// Distance function: Manhattan distance + 1\ninline int dist(int p1, int p2) {\n    return abs(p1 / 15 - p2 / 15) + abs(p1 % 15 - p2 % 15) + 1;\n}\n\n// Function to calculate the maximum overlap between string a and string b\nint get_overlap(const string& a, const string& b) {\n    for (int o = 4; o >= 1; --o) {\n        bool match = true;\n        for (int i = 0; i < o; ++i) {\n            if (a[5 - o + i] != b[i]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return o;\n    }\n    return 0;\n}\n\nint min_cost_table[6][200][225];\ndouble d[200][200];\ndouble d_start[200];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read Input\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    A.resize(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    T_str.resize(M);\n    for (int i = 0; i < M; ++i) cin >> T_str[i];\n\n    // Map each character to its positions on the 15x15 grid\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            pos_of_char[A[i][j] - 'A'].push_back(i * 15 + j);\n        }\n    }\n\n    // Precompute minimum typing cost for all possible suffixes starting from any grid position\n    for (int j = 0; j < M; ++j) {\n        for (int pos = 0; pos < 225; ++pos) min_cost_table[5][j][pos] = 0;\n        for (int k = 4; k >= 0; --k) {\n            int char_idx = T_str[j][k] - 'A';\n            for (int pos = 0; pos < 225; ++pos) {\n                int best = 1e9;\n                for (int next_pos : pos_of_char[char_idx]) {\n                    best = min(best, dist(pos, next_pos) + min_cost_table[k + 1][j][next_pos]);\n                }\n                min_cost_table[k][j][pos] = best;\n            }\n        }\n    }\n\n    // Precompute TSP distance matrix d[i][j] for transitions between strings\n    // d[i][j] prioritizes overlaps (using a large weight) and adds average Manhattan cost\n    for (int i = 0; i < M; ++i) {\n        int last_char_idx = T_str[i][4] - 'A';\n        for (int j = 0; j < M; ++j) {\n            int o = get_overlap(T_str[i], T_str[j]);\n            double avg = 0;\n            for (int pos : pos_of_char[last_char_idx]) {\n                avg += min_cost_table[o][j][pos];\n            }\n            avg /= pos_of_char[last_char_idx].size();\n            d[i][j] = (double)(5 - o) * 1000.0 + avg;\n        }\n        d_start[i] = min_cost_table[0][i][si * 15 + sj];\n    }\n\n    // Generate Greedy initial path for TSP\n    vector<int> p(M);\n    vector<bool> used(M, false);\n    int curr = -1;\n    double min_d_start = 1e18;\n    for (int i = 0; i < M; ++i) {\n        if (d_start[i] < min_d_start) {\n            min_d_start = d_start[i];\n            curr = i;\n        }\n    }\n    p[0] = curr;\n    used[curr] = true;\n    for (int i = 1; i < M; ++i) {\n        int next_v = -1;\n        double best_v = 1e18;\n        for (int j = 0; j < M; ++j) {\n            if (!used[j] && d[p[i - 1]][j] < best_v) {\n                best_v = d[p[i - 1]][j];\n                next_v = j;\n            }\n        }\n        p[i] = next_v;\n        used[next_v] = true;\n    }\n\n    // Scoring function for the current path\n    auto get_total_cost = [&](const vector<int>& path) {\n        double cost = d_start[path[0]];\n        for (int i = 0; i < M - 1; ++i) cost += d[path[i]][path[i + 1]];\n        return cost;\n    };\n\n    double current_cost = get_total_cost(p);\n    double best_ever_cost = current_cost;\n    vector<int> best_p = p;\n\n    // Simulated Annealing to optimize the TSP order\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    for (int iter = 0; ; ++iter) {\n        // Run until near the time limit (1.85 seconds)\n        if (iter % 1000 == 0) {\n            auto now = chrono::steady_clock::now();\n            long long elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > 1850) break;\n        }\n\n        int i = uniform_int_distribution<int>(0, M - 1)(rng);\n        int j = uniform_int_distribution<int>(0, M - 1)(rng);\n        if (i == j) continue;\n        if (i > j) swap(i, j);\n\n        // Calculate the new cost if segment p[i...j] is reversed\n        double new_cost = current_cost;\n        if (i == 0) {\n            new_cost -= d_start[p[0]];\n            new_cost += d_start[p[j]];\n        } else {\n            new_cost -= d[p[i - 1]][p[i]];\n            new_cost += d[p[i - 1]][p[j]];\n        }\n        if (j < M - 1) {\n            new_cost -= d[p[j]][p[j + 1]];\n            new_cost += d[p[i]][p[j + 1]];\n        }\n        // Transitions within the reversed segment\n        for (int k = i; k < j; ++k) {\n            new_cost -= d[p[k]][p[k + 1]];\n            new_cost += d[p[k + 1]][p[k]];\n        }\n\n        // Accept move if better, or with probability based on SA temperature\n        if (new_cost < current_cost) {\n            current_cost = new_cost;\n            reverse(p.begin() + i, p.begin() + j + 1);\n            if (current_cost < best_ever_cost) {\n                best_ever_cost = current_cost;\n                best_p = p;\n            }\n        } else {\n            auto now = chrono::steady_clock::now();\n            long long elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            double temp = 30.0 * (1.0 - (double)elapsed / 1850.0);\n            if (temp > 0 && uniform_real_distribution<double>(0, 1)(rng) < exp((current_cost - new_cost) / temp)) {\n                current_cost = new_cost;\n                reverse(p.begin() + i, p.begin() + j + 1);\n            }\n        }\n    }\n    p = best_p;\n\n    // Construct the superstring S using the optimized TSP order\n    string S = T_str[p[0]];\n    for (int i = 1; i < M; ++i) {\n        int o = get_overlap(T_str[p[i - 1]], T_str[p[i]]);\n        S += T_str[p[i]].substr(o);\n    }\n\n    // Map each character of S to its possible positions on the keyboard\n    vector<vector<int>> pos_list;\n    for (char c : S) pos_list.push_back(pos_of_char[c - 'A']);\n\n    // Dynamic Programming to find the path of grid coordinates that minimizes cost\n    int L = S.size();\n    vector<vector<int>> dp_vals(L);\n    vector<vector<int>> parent(L);\n    for (int k = 0; k < L; ++k) {\n        dp_vals[k].assign(pos_list[k].size(), 2000000000);\n        parent[k].assign(pos_list[k].size(), -1);\n    }\n\n    int start_pos_val = si * 15 + sj;\n    for (int i = 0; i < (int)pos_list[0].size(); ++i) {\n        dp_vals[0][i] = dist(start_pos_val, pos_list[0][i]);\n    }\n\n    for (int k = 1; k < L; ++k) {\n        for (int i = 0; i < (int)pos_list[k].size(); ++i) {\n            int curr_pos = pos_list[k][i];\n            for (int j = 0; j < (int)pos_list[k - 1].size(); ++j) {\n                int prev_pos = pos_list[k - 1][j];\n                int cost_val = dp_vals[k - 1][j] + dist(prev_pos, curr_pos);\n                if (cost_val < dp_vals[k][i]) {\n                    dp_vals[k][i] = cost_val;\n                    parent[k][i] = j;\n                }\n            }\n        }\n    }\n\n    // Reconstruct the optimal path from DP table\n    int best_idx = 0;\n    int min_total_cost = 2000000000;\n    for (int i = 0; i < (int)pos_list[L - 1].size(); ++i) {\n        if (dp_vals[L - 1][i] < min_total_cost) {\n            min_total_cost = dp_vals[L - 1][i];\n            best_idx = i;\n        }\n    }\n\n    vector<int> final_path(L);\n    for (int k = L - 1; k >= 0; --k) {\n        final_path[k] = pos_list[k][best_idx];\n        best_idx = parent[k][best_idx];\n    }\n\n    // Output the sequence of coordinates\n    for (int pos : final_path) {\n        cout << pos / 15 << \" \" << pos % 15 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int r, c;\n};\n\nstruct Polyomino {\n    int id;\n    int d;\n    vector<Point> ps;\n    vector<vector<Point>> positions;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<pair<vector<int>, int>> queries;\nvector<pair<Point, int>> drills;\nvector<vector<vector<int>>> W; // W[field_idx][pos_idx][query_idx]\n\ndouble normal_cdf(double x) {\n    return 0.5 * erfc(-x * M_SQRT1_2);\n}\n\ndouble get_prob(int k, int v_sum, int v_obs) {\n    if (k == 1) return (v_sum == v_obs) ? 1.0 : 1e-18;\n    double mu = (k - v_sum) * eps + v_sum * (1.0 - eps);\n    double sigma = sqrt((double)k * eps * (1.0 - eps));\n    if (v_obs == 0) {\n        return max(1e-18, normal_cdf((0.5 - mu) / sigma));\n    } else {\n        return max(1e-18, normal_cdf((v_obs + 0.5 - mu) / sigma) - normal_cdf((v_obs - 0.5 - mu) / sigma));\n    }\n}\n\ndouble get_log_prob(int k, int v_sum, int v_obs) {\n    return log(get_prob(k, v_sum, v_obs));\n}\n\nstruct Config {\n    vector<int> pos_idx;\n    vector<int> v_sums;\n    vector<vector<int>> grid_v;\n    double log_prob;\n\n    Config() : pos_idx(M), v_sums(), grid_v(N, vector<int>(N, 0)), log_prob(0) {}\n\n    void compute_all() {\n        for (int i = 0; i < N; ++i) fill(grid_v[i].begin(), grid_v[i].end(), 0);\n        for (int i = 0; i < M; ++i) {\n            for (const auto& p : oil_fields[i].positions[pos_idx[i]]) {\n                grid_v[p.r][p.c]++;\n            }\n        }\n        v_sums.assign(queries.size(), 0);\n        log_prob = 0;\n        for (size_t q = 0; q < queries.size(); ++q) {\n            for (int k = 0; k < M; ++k) {\n                v_sums[q] += W[k][pos_idx[k]][q];\n            }\n            log_prob += get_log_prob(queries[q].first.size(), v_sums[q], queries[q].second);\n        }\n        for (const auto& d : drills) {\n            if (grid_v[d.first.r][d.first.c] != d.second) log_prob -= 1e6;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> eps)) return 0;\n    oil_fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int d; cin >> d; oil_fields[i].d = d;\n        vector<Point> ps(d);\n        int max_r = 0, max_c = 0;\n        for (int j = 0; j < d; ++j) {\n            cin >> ps[j].r >> ps[j].c;\n            max_r = max(max_r, ps[j].r);\n            max_c = max(max_c, ps[j].c);\n        }\n        oil_fields[i].ps = ps;\n        for (int r = 0; r <= N - 1 - max_r; ++r) {\n            for (int c = 0; c <= N - 1 - max_c; ++c) {\n                vector<Point> pos;\n                for (const auto& p : ps) pos.push_back({p.r + r, p.c + c});\n                oil_fields[i].positions.push_back(pos);\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    for (int i = 0; i < 2 * N; ++i) {\n        vector<int> S;\n        for (int j = 0; j < N * N; ++j) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < 0.5) S.push_back(j);\n        }\n        if (S.size() < 2) { S.push_back(0); S.push_back(1); }\n        cout << \"q \" << S.size();\n        for (int idx : S) cout << \" \" << idx / N << \" \" << idx % N;\n        cout << endl;\n        int resp; cin >> resp;\n        queries.push_back({S, resp});\n    }\n\n    W.assign(M, vector<vector<int>>());\n    for (int i = 0; i < M; ++i) {\n        W[i].assign(oil_fields[i].positions.size(), vector<int>(queries.size(), 0));\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            vector<vector<bool>> is_in_pos(N, vector<bool>(N, false));\n            for (const auto& pt : oil_fields[i].positions[p]) is_in_pos[pt.r][pt.c] = true;\n            for (size_t q = 0; q < queries.size(); ++q) {\n                for (int idx : queries[q].first) {\n                    if (is_in_pos[idx / N][idx % N]) W[i][p][q]++;\n                }\n            }\n        }\n    }\n\n    const int num_samples = 400;\n    vector<Config> samples(num_samples);\n    for (int i = 0; i < num_samples; ++i) {\n        for (int j = 0; j < M; ++j) {\n            samples[i].pos_idx[j] = uniform_int_distribution<int>(0, (int)oil_fields[j].positions.size() - 1)(rng);\n        }\n        samples[i].compute_all();\n    }\n\n    for (int iter = 0; iter < 2 * N * N; ++iter) {\n        for (int i = 0; i < num_samples; ++i) {\n            for (int step = 0; step < 30; ++step) {\n                int m = uniform_int_distribution<int>(0, M - 1)(rng);\n                int old_pos = samples[i].pos_idx[m];\n                int new_pos = uniform_int_distribution<int>(0, (int)oil_fields[m].positions.size() - 1)(rng);\n                if (old_pos == new_pos) continue;\n\n                double old_lp = samples[i].log_prob;\n                for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]--;\n                for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]++;\n                \n                double new_lp = 0;\n                vector<int> old_v_sums = samples[i].v_sums;\n                for (size_t q = 0; q < queries.size(); ++q) {\n                    samples[i].v_sums[q] = samples[i].v_sums[q] - W[m][old_pos][q] + W[m][new_pos][q];\n                    new_lp += get_log_prob(queries[q].first.size(), samples[i].v_sums[q], queries[q].second);\n                }\n                for (const auto& d : drills) {\n                    if (samples[i].grid_v[d.first.r][d.first.c] != d.second) new_lp -= 1e6;\n                }\n                \n                if (new_lp > old_lp || uniform_real_distribution<double>(0, 1)(rng) < exp(new_lp - old_lp)) {\n                    samples[i].log_prob = new_lp;\n                    samples[i].pos_idx[m] = new_pos;\n                } else {\n                    for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]--;\n                    for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]++;\n                    samples[i].v_sums = old_v_sums;\n                }\n            }\n        }\n\n        vector<vector<double>> p(N, vector<double>(N, 0));\n        for (int i = 0; i < num_samples; ++i) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) if (samples[i].grid_v[r][c] > 0) p[r][c] += 1.0;\n            }\n        }\n\n        bool confident = true;\n        vector<Point> guess_set;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p[r][c] /= num_samples;\n                if (p[r][c] > 0.5) guess_set.push_back({r, c});\n                if (p[r][c] > 0.01 && p[r][c] < 0.99) confident = false;\n            }\n        }\n\n        if (confident || iter > N * N) {\n            cout << \"a \" << guess_set.size();\n            for (const auto& pt : guess_set) cout << \" \" << pt.r << \" \" << pt.c;\n            cout << endl;\n            int resp; if (!(cin >> resp)) break;\n            if (resp == 1) break;\n        }\n\n        double max_var = -1; Point best_p = {0, 0};\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                double var = p[r][c] * (1.0 - p[r][c]);\n                if (var > max_var) { max_var = var; best_p = {r, c}; }\n            }\n        }\n\n        cout << \"q 1 \" << best_p.r << \" \" << best_p.c << endl;\n        int resp; if (!(cin >> resp)) break;\n        drills.push_back({best_p, resp});\n        for (int i = 0; i < num_samples; ++i) samples[i].compute_all();\n    }\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n\nusing namespace std;\n\n// The size of the event hall grid.\nconst int MAXW = 1000;\n\n// Struct to hold rectangle coordinates: top-left (r1, c1) and bottom-right (r2, c2).\nstruct Rectangle {\n    int r1, c1, r2, c2;\n};\n\nint W, D, N;\nlong long a[50][50];\n\n// Bitset representing a line of segments to efficiently calculate changes in partitions.\ntypedef bitset<MAXW> BitLine;\n\nstruct DayConfig {\n    BitLine H[MAXW + 1]; // Horizontal partition segments\n    BitLine V[MAXW + 1]; // Vertical partition segments\n};\n\n// Calculates the length of partitions installed/removed between day d-1 and day d.\nlong long calculate_Ld(const DayConfig& prev, const DayConfig& curr) {\n    long long Ld = 0;\n    for (int i = 1; i < W; ++i) {\n        Ld += (prev.H[i] ^ curr.H[i]).count();\n    }\n    for (int i = 0; i < W; ++i) {\n        Ld += (prev.V[i] ^ curr.V[i]).count();\n    }\n    return Ld;\n}\n\n// Generates the partition configuration based on the rectangles assigned for the day.\nDayConfig get_config(const vector<Rectangle>& rects) {\n    DayConfig config;\n    for (const auto& rect : rects) {\n        // Only include horizontal segments that are not on the perimeter of the hall.\n        if (rect.r1 > 0) {\n            for (int j = rect.c1; j < rect.c2; ++j) config.H[rect.r1].set(j);\n        }\n        if (rect.r2 < W) {\n            for (int j = rect.c1; j < rect.c2; ++j) config.H[rect.r2].set(j);\n        }\n        // Only include vertical segments that are not on the perimeter of the hall.\n        if (rect.c1 > 0) {\n            for (int i = rect.r1; i < rect.r2; ++i) config.V[i].set(rect.c1);\n        }\n        if (rect.c2 < W) {\n            for (int i = rect.r1; i < rect.r2; ++i) config.V[i].set(rect.c2);\n        }\n    }\n    return config;\n}\n\n// Computes the total area deficit penalty for a given day.\nlong long calculate_penalty(int d, const vector<Rectangle>& rects) {\n    long long penalty = 0;\n    for (int k = 0; k < N; ++k) {\n        long long area = (long long)(rects[k].r2 - rects[k].r1) * (rects[k].c2 - rects[k].c1);\n        if (a[d][k] > area) {\n            penalty += 100 * (a[d][k] - area);\n        }\n    }\n    return penalty;\n}\n\nint main() {\n    // Standard I/O optimization.\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> W >> D >> N)) return 0;\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a[d][k];\n        }\n    }\n\n    // Precalculate the maximum height needed across all days for a range of consecutive reservations.\n    // This assumes we are dividing reservations into horizontal strips.\n    static int max_A_needed[51][51];\n    for (int p = 0; p < N; ++p) {\n        for (int i = p + 1; i <= N; ++i) {\n            long long max_sum = 0;\n            for (int d = 0; d < D; ++d) {\n                long long s = 0;\n                for (int k = p; k < i; ++k) s += a[d][k];\n                max_sum = max(max_sum, s);\n            }\n            max_A_needed[p][i] = (max_sum + W - 1) / W;\n        }\n    }\n\n    long long best_total_cost = -1;\n    vector<vector<Rectangle>> best_all_rects;\n\n    // Explore several values for the number of horizontal strips R.\n    vector<int> R_to_try;\n    for (int R = 1; R <= N; ++R) {\n        if (R <= 10 || R % 5 == 0 || R == N) R_to_try.push_back(R);\n    }\n\n    for (int R : R_to_try) {\n        // Dynamic programming to determine the best assignment of N reservations into R horizontal strips.\n        // We aim to minimize the sum of heights needed across all strips to handle peak area demand.\n        vector<vector<int>> dp(N + 1, vector<int>(R + 1, 1e9));\n        vector<vector<int>> best_p(N + 1, vector<int>(R + 1, -1));\n        dp[0][0] = 0;\n        for (int j = 1; j <= R; ++j) {\n            for (int i = 1; i <= N; ++i) {\n                for (int p = j - 1; p < i; ++p) {\n                    int h = max_A_needed[p][i];\n                    if (dp[p][j - 1] + h < dp[i][j]) {\n                        dp[i][j] = dp[p][j - 1] + h;\n                        best_p[i][j] = p;\n                    }\n                }\n            }\n        }\n\n        if (dp[N][R] > 1e8) continue;\n\n        // Reconstruct the strip assignments.\n        vector<vector<int>> strips(R);\n        int curr_i = N;\n        for (int j = R; j >= 1; --j) {\n            int p = best_p[curr_i][j];\n            for (int k = p; k < curr_i; ++k) strips[j - 1].push_back(k);\n            curr_i = p;\n        }\n\n        // Secondary DP to determine the actual height Hr for each strip, summing to exactly W,\n        // to minimize the total penalty incurred across all days for this strip configuration.\n        vector<vector<long long>> cost_h(R, vector<long long>(W + 1));\n        for (int r = 0; r < R; ++r) {\n            for (int h = 1; h <= W; ++h) {\n                long long penalty = 0;\n                for (int d = 0; d < D; ++d) {\n                    long long sum_a = 0;\n                    for (int k : strips[r]) sum_a += a[d][k];\n                    if (sum_a > (long long)h * W) {\n                        penalty += 100 * (sum_a - (long long)h * W);\n                    }\n                }\n                cost_h[r][h] = penalty;\n            }\n        }\n\n        vector<vector<long long>> dp2(R + 1, vector<long long>(W + 1, 1e18));\n        vector<vector<int>> best_h(R + 1, vector<int>(W + 1, -1));\n        dp2[0][0] = 0;\n        for (int r = 1; r <= R; ++r) {\n            for (int h = r; h <= W - (R - r); ++h) {\n                for (int hr = 1; h - hr >= r - 1; ++hr) {\n                    long long new_cost = dp2[r - 1][h - hr] + cost_h[r - 1][hr];\n                    if (new_cost < dp2[r][h]) {\n                        dp2[r][h] = new_cost;\n                        best_h[r][h] = hr;\n                    }\n                }\n            }\n        }\n\n        vector<int> Hr(R);\n        int curr_h = W;\n        for (int r = R; r >= 1; --r) {\n            Hr[r - 1] = best_h[r][curr_h];\n            curr_h -= Hr[r - 1];\n        }\n\n        // For the chosen strip height distribution, calculate optimal rectangle widths for each reservation.\n        vector<vector<Rectangle>> all_rects(D, vector<Rectangle>(N));\n        vector<int> y_coords(R + 1, 0);\n        for (int r = 0; r < R; ++r) y_coords[r + 1] = y_coords[r] + Hr[r];\n\n        for (int d = 0; d < D; ++d) {\n            for (int r = 0; r < R; ++r) {\n                int nr = strips[r].size();\n                vector<int> w(nr);\n                for (int k = 0; k < nr; ++k) {\n                    w[k] = max(1LL, (a[d][strips[r][k]] + Hr[r] - 1) / Hr[r]);\n                }\n                int current_sum_w = 0;\n                for (int val : w) current_sum_w += val;\n\n                // Greedy adjustment of widths to fit theHall's width exactly while minimizing penalty.\n                if (current_sum_w > W) {\n                    while (current_sum_w > W) {\n                        int best_k = -1;\n                        long long min_penalty_increase = 1e18;\n                        for (int k = 0; k < nr; ++k) {\n                            if (w[k] > 1) {\n                                long long increase = (long long)a[d][strips[r][k]] - (long long)Hr[r] * (w[k] - 1);\n                                if (increase < 0) increase = 0;\n                                long long current_p = (long long)a[d][strips[r][k]] - (long long)Hr[r] * w[k];\n                                if (current_p < 0) current_p = 0;\n                                long long diff = (increase - current_p) * 100;\n                                if (diff < min_penalty_increase) {\n                                    min_penalty_increase = diff;\n                                    best_k = k;\n                                }\n                            }\n                        }\n                        if (best_k == -1) break;\n                        w[best_k]--;\n                        current_sum_w--;\n                    }\n                } else if (current_sum_w < W) {\n                    while (current_sum_w < W) {\n                        int best_k = -1;\n                        long long max_penalty_reduction = -1;\n                        for (int k = 0; k < nr; ++k) {\n                            long long reduction = min((long long)Hr[r], max(0LL, (long long)a[d][strips[r][k]] - (long long)Hr[r] * w[k]));\n                            if (reduction > max_penalty_reduction) {\n                                max_penalty_reduction = reduction;\n                                best_k = k;\n                            }\n                        }\n                        if (max_penalty_reduction > 0) {\n                            w[best_k]++;\n                            current_sum_w++;\n                        } else {\n                            w[nr - 1] += (W - current_sum_w);\n                            current_sum_w = W;\n                        }\n                    }\n                }\n\n                int curr_x = 0;\n                for (int k = 0; k < nr; ++k) {\n                    all_rects[d][strips[r][k]] = {y_coords[r], curr_x, y_coords[r + 1], curr_x + w[k]};\n                    curr_x += w[k];\n                }\n            }\n        }\n\n        // Calculate the total cost (Penalty + Ld) for this R and Option.\n        long long total_cost = 0;\n        vector<DayConfig> configs(D);\n        for (int d = 0; d < D; ++d) {\n            configs[d] = get_config(all_rects[d]);\n            total_cost += calculate_penalty(d, all_rects[d]);\n            if (d > 0) total_cost += calculate_Ld(configs[d - 1], configs[d]);\n        }\n\n        if (best_total_cost == -1 || total_cost < best_total_cost) {\n            best_total_cost = total_cost;\n            best_all_rects = all_rects;\n        }\n    }\n\n    // Final output of determined rectangles for all days.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_all_rects[d][k].r1 << \" \" << best_all_rects[d][k].c1 << \" \" << best_all_rects[d][k].r2 << \" \" << best_all_rects[d][k].c2 << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <stdint.h>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\n// Struct to represent a combination of 0 to 3 stamps\nstruct Combination {\n    int k;                   // Number of stamps in the combination\n    vector<int> ms;          // Indices of the stamps\n    long long s00;           // Sum of values at position (0,0) modulo P\n    uint32_t s[3][3];        // 3x3 array of sums of stamp values modulo P\n};\n\n// State of the board and current search progress\nstruct State {\n    uint32_t board[N][N];\n    int total_k;             // Total number of operations (stamps) used\n    vector<tuple<int, int, int>> ops; // List of operations performed\n    long long current_score; // Sum of the board values modulo P\n\n    // Comparer to sort states by their scores (descending)\n    bool operator>(const State& other) const {\n        return current_score > other.current_score;\n    }\n};\n\n// Struct to store a potential next step for the beam search\nstruct Candidate {\n    int state_idx;           // Index of the parent state in the beam\n    int combi_idx;           // Index of the combination being applied\n    long long score;         // New score after applying the combination\n\n    // Comparer to sort candidates by their scores (descending)\n    bool operator>(const Candidate& other) const {\n        return score > other.score;\n    }\n};\n\n// Inline function to calculate the score of a new state without copying the board\ninline long long calculate_next_score(const State& state, const Combination& combi, int p, int q) {\n    long long next_score = state.current_score;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            uint32_t old_val = state.board[p + i][q + j];\n            uint32_t new_val = old_val + combi.s[i][j];\n            if (new_val >= P) new_val -= P;\n            next_score = next_score - (long long)old_val + (long long)new_val;\n        }\n    }\n    return next_score;\n}\n\nint main() {\n    // Speed up 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    uint32_t a[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    uint32_t s[M][3][3];\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    // Precompute combinations of 0 to 3 stamps\n    vector<Combination> all_combi;\n    \n    // k = 0\n    Combination c0;\n    c0.k = 0; c0.ms = {}; c0.s00 = 0;\n    for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c0.s[i][j] = 0;\n    all_combi.push_back(c0);\n\n    // k = 1\n    for (int m = 0; m < M; ++m) {\n        Combination c;\n        c.k = 1; c.ms = {m}; c.s00 = s[m][0][0];\n        for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c.s[i][j] = s[m][i][j];\n        all_combi.push_back(c);\n    }\n\n    // k = 2\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            Combination c;\n            c.k = 2; c.ms = {m1, m2};\n            c.s00 = (s[m1][0][0] + s[m2][0][0]) % P;\n            for (int i = 0; i < 3; ++i)\n                for (int j = 0; j < 3; ++j)\n                    c.s[i][j] = (s[m1][i][j] + s[m2][i][j]) % P;\n            all_combi.push_back(c);\n        }\n    }\n\n    // k = 3\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            for (int m3 = m2; m3 < M; ++m3) {\n                Combination c;\n                c.k = 3; c.ms = {m1, m2, m3};\n                c.s00 = ( (long long)s[m1][0][0] + s[m2][0][0] + s[m3][0][0] ) % P;\n                for (int i = 0; i < 3; ++i)\n                    for (int j = 0; j < 3; ++j)\n                        c.s[i][j] = ( (long long)s[m1][i][j] + s[m2][i][j] + s[m3][i][j] ) % P;\n                all_combi.push_back(c);\n            }\n        }\n    }\n\n    // Sort combinations by their (0,0) value to efficiently pick best ones\n    sort(all_combi.begin(), all_combi.end(), [](const Combination& a, const Combination& b) {\n        return a.s00 < b.s00;\n    });\n\n    // Beam search initialization\n    State initial_state;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.board[i][j] = a[i][j];\n    initial_state.total_k = 0;\n    initial_state.current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.current_score += a[i][j];\n    initial_state.ops = {};\n\n    vector<State> beam;\n    beam.push_back(initial_state);\n\n    int B = 1000; // Beam size\n    int T = 100;  // Number of top combinations to consider per square per state\n\n    // Row-major iteration through all potential top-left stamp positions\n    for (int p = 0; p <= N - 3; ++p) {\n        for (int q = 0; q <= N - 3; ++q) {\n            vector<Candidate> candidates;\n            candidates.reserve(beam.size() * T);\n\n            for (int state_idx = 0; state_idx < (int)beam.size(); ++state_idx) {\n                const State& current_s = beam[state_idx];\n                uint32_t V = current_s.board[p][q];\n                long long target = P - 1 - V;\n\n                // Use binary search on pre-sorted combinations to find best candidates for the current board square\n                int it_idx = lower_bound(all_combi.begin(), all_combi.end(), target, [](const Combination& c, long long val) {\n                    return c.s00 < val;\n                }) - all_combi.begin();\n\n                int start = it_idx;\n                if (start == (int)all_combi.size() || all_combi[start].s00 > target) {\n                    start--;\n                }\n\n                int found = 0;\n                // Check combinations with s00 <= target in descending order\n                for (int i = start; i >= 0 && found < T; --i) {\n                    if (current_s.total_k + all_combi[i].k <= K) {\n                        candidates.push_back({state_idx, i, calculate_next_score(current_s, all_combi[i], p, q)});\n                        found++;\n                    }\n                }\n                // Check remaining best combinations from the end of the list (where V+s00-P is large)\n                for (int i = (int)all_combi.size() - 1; i > start && found < T; --i) {\n                    if (current_s.total_k + all_combi[i].k <= K) {\n                        candidates.push_back({state_idx, i, calculate_next_score(current_s, all_combi[i], p, q)});\n                        found++;\n                    }\n                }\n            }\n\n            // Keep top B candidates\n            int next_B = min((int)candidates.size(), B);\n            nth_element(candidates.begin(), candidates.begin() + next_B, candidates.end(), greater<Candidate>());\n            candidates.resize(next_B);\n\n            // Construct next beam from selected candidates\n            vector<State> next_beam;\n            next_beam.reserve(next_B);\n            for (const auto& cand : candidates) {\n                State ns = beam[cand.state_idx];\n                const Combination& combi = all_combi[cand.combi_idx];\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        uint32_t val = ns.board[p + i][q + j] + combi.s[i][j];\n                        if (val >= P) val -= P;\n                        ns.board[p + i][q + j] = val;\n                    }\n                }\n                ns.total_k += combi.k;\n                for (int m_idx : combi.ms) {\n                    ns.ops.emplace_back(m_idx, p, q);\n                }\n                ns.current_score = cand.score;\n                next_beam.push_back(std::move(ns));\n            }\n            beam = std::move(next_beam);\n        }\n    }\n\n    // Find and output the best solution found\n    long long best_final_score = -1;\n    int best_state_idx = -1;\n    for (int i = 0; i < (int)beam.size(); ++i) {\n        if (beam[i].current_score > best_final_score) {\n            best_final_score = beam[i].current_score;\n            best_state_idx = i;\n        }\n    }\n\n    const State& best_state = beam[best_state_idx];\n    cout << best_state.ops.size() << \"\\n\";\n    for (const auto& op : best_state.ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer's solution for the container terminal problem.\n *\n * Strategy:\n * 1. Bomb all small cranes (cranes 1-4) in Turn 0 to clear the grid.\n * 2. Use the large crane (crane 0) to handle all containers one by one.\n * 3. Crane 0 strategy:\n *    - Priority 1: If a container that is next in order for its dispatch gate is already on the grid,\n *                  pick it up and move it to its dispatch gate.\n *    - Priority 2: If no such container is on the grid, find the most urgent container (smallest index\n *                  that hasn't been dispatched) still in a receiving queue. Move the top container of\n *                  that queue to a buffer square to clear the way.\n * 4. This strategy ensures M1=0 (no inversions), M2=0 (all to correct gates), and M3=0 (all dispatched).\n *    The turns count M0 will be minimized by only moving what's necessary and using shortest paths.\n */\n\nvoid add_move_to_queue(vector<char>& q, int tr, int tc, int& r, int& c) {\n    while (r < tr) { q.push_back('D'); r++; }\n    while (r > tr) { q.push_back('U'); r--; }\n    while (c < tc) { q.push_back('R'); c++; }\n    while (c > tc) { q.push_back('L'); c--; }\n}\n\nint main() {\n    int N_in;\n    if (!(cin >> N_in)) return 0;\n    int N = 5;\n    vector<vector<int>> arrival_queue(5, vector<int>(5));\n    vector<int> gate_of(25);\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            cin >> arrival_queue[i][j];\n            gate_of[arrival_queue[i][j]] = i;\n        }\n    }\n\n    vector<int> current_gate_idx(5, 0);\n    vector<vector<int>> grid(5, vector<int>(5, -1));\n    vector<int> next_needed(5);\n    for (int i = 0; i < 5; i++) next_needed[i] = 5 * i;\n    vector<bool> is_dispatched(25, false);\n    int dispatched_count = 0;\n\n    int crane_r = 0, crane_c = 0;\n    int held = -1;\n    vector<string> actions(5, \"\");\n    vector<char> action_queue;\n\n    for (int t = 0; t < 10000; ++t) {\n        // Step 1: Arrival of containers\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][0] == -1 && current_gate_idx[i] < 5) {\n                // Containers arrive only if square is empty and no crane is holding there\n                if (!(crane_r == i && crane_c == 0 && held != -1)) {\n                    grid[i][0] = arrival_queue[i][current_gate_idx[i]];\n                    current_gate_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        char act0 = '.';\n        if (t == 0) {\n            // Initial moves: move Crane 0 out of (0,0) and bomb others\n            act0 = 'R';\n            for (int i = 1; i < 5; i++) actions[i] += 'B';\n        } else {\n            if (action_queue.empty()) {\n                // Determine next task for Crane 0\n                if (held == -1) {\n                    int target_r = -1, target_c = -1;\n                    // Check if a needed container is already on the grid (arrival gates or buffer)\n                    for (int r = 0; r < 5; ++r) {\n                        for (int c = 0; c < 4; ++c) {\n                            if (grid[r][c] != -1) {\n                                int val = grid[r][c];\n                                if (val == next_needed[val / 5]) {\n                                    target_r = r; target_c = c; break;\n                                }\n                            }\n                        }\n                        if (target_r != -1) break;\n                    }\n\n                    if (target_r != -1) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, target_r, target_c, r, c);\n                        action_queue.push_back('P');\n                    } else {\n                        // Find most urgent container still in a queue and clear its path\n                        int urgent_v = 100;\n                        int clear_gate = -1;\n                        for (int i = 0; i < 5; ++i) {\n                            if (next_needed[i] < 5 * (i + 1)) {\n                                int v = next_needed[i];\n                                bool is_av = !is_dispatched[v];\n                                if (is_av) {\n                                    for (int r1 = 0; r1 < 5; r1++)\n                                        for (int c1 = 0; c1 < 4; c1++)\n                                            if (grid[r1][c1] == v) is_av = false;\n                                }\n                                if (is_av && v < urgent_v) {\n                                    urgent_v = v;\n                                    clear_gate = gate_of[v];\n                                }\n                            }\n                        }\n                        if (clear_gate != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, clear_gate, 0, r, c);\n                            if (grid[clear_gate][0] != -1) action_queue.push_back('P');\n                            else action_queue.push_back('.'); // Wait for container arrival\n                        }\n                    }\n                } else {\n                    // Holding a container: either dispatch it or move it to a buffer\n                    if (held == next_needed[held / 5]) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, held / 5, 4, r, c);\n                        action_queue.push_back('Q');\n                    } else {\n                        int br = -1, bc = -1;\n                        for (int c = 1; c <= 3; ++c) {\n                            for (int r = 0; r < 5; ++r) {\n                                if (grid[r][c] == -1) { br = r; bc = c; break; }\n                            }\n                            if (br != -1) break;\n                        }\n                        if (br != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, br, bc, r, c);\n                            action_queue.push_back('Q');\n                        } else {\n                            action_queue.push_back('.');\n                        }\n                    }\n                }\n            }\n\n            if (!action_queue.empty()) {\n                act0 = action_queue.front();\n                action_queue.erase(action_queue.begin());\n            }\n            for (int i = 1; i < 5; i++) actions[i] += '.';\n        }\n\n        actions[0] += act0;\n        if (act0 == 'P') { held = grid[crane_r][crane_c]; grid[crane_r][crane_c] = -1; }\n        else if (act0 == 'Q') {\n            int val = held;\n            grid[crane_r][crane_c] = val;\n            if (crane_c == 4) next_needed[val / 5]++;\n            held = -1;\n        } else if (act0 == 'U') crane_r--;\n        else if (act0 == 'D') crane_r++;\n        else if (act0 == 'L') crane_c--;\n        else if (act0 == 'R') crane_c++;\n\n        // Step 3: Container dispatch\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][4] != -1) {\n                is_dispatched[grid[i][4]] = true;\n                grid[i][4] = -1;\n                dispatched_count++;\n            }\n        }\n\n        if (dispatched_count == 25) break;\n    }\n\n    // Output all actions, padding with '.' as necessary\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) max_len = max(max_len, (int)actions[i].length());\n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) actions[i] += '.';\n        cout << actions[i] << endl;\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n// Grid size is fixed at 20x20\nconst int N = 20;\n\n/**\n * State struct maintains the current status of the grid, the dump truck, \n * the total operations, and the cost incurred so far.\n */\nstruct State {\n    int h[N][N];\n    int r, c;\n    long long L;\n    long long cost;\n    vector<string> ops;\n\n    State(const int initial_h[N][N]) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                h[i][j] = initial_h[i][j];\n            }\n        }\n        r = 0;\n        c = 0;\n        L = 0;\n        cost = 0;\n    }\n\n    // Load d units of soil from the current square\n    void load(int d) {\n        if (d <= 0) return;\n        h[r][c] -= d;\n        L += d;\n        cost += d;\n        ops.push_back(\"+\" + to_string(d));\n    }\n\n    // Unload d units of soil from the dump truck to the current square\n    void unload(int d) {\n        if (d <= 0) return;\n        h[r][c] += d;\n        L -= d;\n        cost += d;\n        ops.push_back(\"-\" + to_string(d));\n    }\n\n    // Move the dump truck in a given direction\n    void move(char dir) {\n        if (dir == 'U') r--;\n        else if (dir == 'D') r++;\n        else if (dir == 'L') c--;\n        else if (dir == 'R') c++;\n        cost += (100 + L);\n        ops.push_back(string(1, dir));\n    }\n};\n\n// Global best score variable to track the overall best solution\nlong long best_score_overall = 8e18;\n\n/**\n * solve function implements a greedy strategy with a parameterized heuristic.\n * The heuristic score for selecting the next square (i,j) depends on:\n *   - Manhattan distance to (i,j)\n *   - Current load L\n *   - Amount of soil at (i,j)\n *   - A hyperparameter K representing the weight of soil volume in decision making.\n */\nvoid solve(const int initial_h[N][N], double K, vector<string>& best_ops, mt19937& rng) {\n    State s(initial_h);\n    \n    // Limits the turns to 100,000 as per problem constraints\n    while (s.ops.size() < 99990) {\n        // First handle loading/unloading at the current square if necessary\n        if (s.h[s.r][s.c] > 0) {\n            int amount = s.h[s.r][s.c];\n            s.load(amount);\n        } else if (s.h[s.r][s.c] < 0 && s.L > 0) {\n            int amount = (int)min((long long)abs(s.h[s.r][s.c]), s.L);\n            s.unload(amount);\n        }\n\n        // Check if the goal (all heights 0 and truck empty) is reached\n        bool all_zero = true;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (s.h[i][j] != 0) {\n                    all_zero = false;\n                    break;\n                }\n            }\n            if (!all_zero) break;\n        }\n        if (all_zero && s.L == 0) break;\n\n        // Greedy search for the next target square with h[i,j] != 0\n        int tr = -1, tc = -1;\n        double best_score = 1e18;\n        \n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (s.h[i][j] == 0) continue;\n                // Cannot visit negative squares if truck is empty\n                if (s.h[i][j] < 0 && s.L == 0) continue;\n\n                int dist = abs(s.r - i) + abs(s.c - j);\n                double score = (double)dist * (100 + s.L);\n                \n                // K estimates the impact of the load change on all future moves\n                if (s.h[i][j] > 0) {\n                    // Loading soil: increases future move costs\n                    score += (double)s.h[i][j] * K;\n                } else {\n                    // Unloading soil: decreases future move costs\n                    int amount = (int)min((long long)abs(s.h[i][j]), s.L);\n                    score -= (double)amount * K;\n                }\n\n                if (score < best_score) {\n                    best_score = score;\n                    tr = i;\n                    tc = j;\n                }\n            }\n        }\n\n        if (tr == -1) break;\n\n        // Move one step towards the chosen target square\n        int dr = (tr > s.r) ? 1 : (tr < s.r ? -1 : 0);\n        int dc = (tc > s.c) ? 1 : (tc < s.c ? -1 : 0);\n        \n        if (dr != 0 && dc != 0) {\n            // If diagonal move is needed, randomly choose vertical or horizontal step\n            if (rng() % 2 == 0) {\n                if (dr > 0) s.move('D'); else s.move('U');\n            } else {\n                if (dc > 0) s.move('R'); else s.move('L');\n            }\n        } else if (dr != 0) {\n            if (dr > 0) s.move('D'); else s.move('U');\n        } else if (dc != 0) {\n            if (dc > 0) s.move('R'); else s.move('L');\n        }\n    }\n\n    // Calculate score for the result, including penalties for remaining non-zero squares\n    long long diff = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s.h[i][j] != 0) {\n                diff += 100LL * abs(s.h[i][j]) + 10000LL;\n            }\n        }\n    }\n    if (s.L > 0) diff += 10000LL;\n\n    // Update the best global solution if the current one is superior\n    if (s.cost + diff < best_score_overall) {\n        best_score_overall = s.cost + diff;\n        best_ops = s.ops;\n    }\n}\n\nint main() {\n    // Fast IO\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n;\n    if (!(cin >> n)) return 0;\n    int initial_h[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> initial_h[i][j];\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    vector<string> best_ops;\n    mt19937 rng(42);\n    \n    // Initial parameter set for K based on reasonable estimations\n    // K represents approximately how many future moves the truck will make\n    vector<double> initial_ks = {0, 10, 25, 50, 75, 100, 150, 200, 300, 500};\n    for (double k : initial_ks) {\n        solve(initial_h, k, best_ops, rng);\n    }\n\n    // Randomize K to explore more potential solutions within the time limit\n    uniform_real_distribution<double> dist_k(0.0, 1000.0);\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        // Leave a safety margin before the 2-second time limit\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) {\n            break;\n        }\n        solve(initial_h, dist_k(rng), best_ops, rng);\n    }\n\n    // Output the operation sequence of the best solution found\n    for (const string& op : best_ops) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#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 N x N grid (N=6). Initially 60 seeds, each with an M=15 vector of values.\n * T=10 turns. Each turn:\n * 1. Plant 36 seeds in the grid.\n * 2. 60 new seeds are generated from grid edges.\n * 3. Each criterion in the new seed is randomly inherited from its two parent seeds.\n * \n * Objective: Maximize the maximum total value of any seed after T turns.\n */\n\nconst int N = 6;\nconst int M = 15;\nconst int T_MAX = 10;\nconst int SEED_COUNT = 60;\nconst int PLANT_COUNT = 36;\n\nstruct Seed {\n    int x[M];\n    int v;\n};\n\n// Potential matrix: P2[i][j] stores the square of the potential offspring's maximum possible value.\nlong long P2[SEED_COUNT][SEED_COUNT];\n\n/**\n * Precompute the potential of offspring from any pair of available seeds.\n * Using a simple \"potential\" as the sum of max values for each criterion.\n */\nvoid precompute_potentials(const vector<Seed>& seeds) {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = 0; j < SEED_COUNT; ++j) {\n            if (i == j) {\n                P2[i][j] = 0;\n                continue;\n            }\n            long long potential = 0;\n            for (int l = 0; l < M; ++l) {\n                potential += max(seeds[i].x[l], seeds[j].x[l]);\n            }\n            P2[i][j] = potential * potential;\n        }\n    }\n}\n\nint main() {\n    // Standard IO optimization\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, m_in, t_in;\n    if (!(cin >> n_in >> m_in >> t_in)) return 0;\n\n    vector<Seed> seeds(SEED_COUNT);\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    mt19937 rng(42);\n\n    for (int t = 0; t < T_MAX; ++t) {\n        precompute_potentials(seeds);\n\n        // Initial planting selection: take seeds with highest total value.\n        vector<int> current_planting(SEED_COUNT);\n        for (int i = 0; i < SEED_COUNT; ++i) current_planting[i] = i;\n        \n        sort(current_planting.begin(), current_planting.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n\n        int grid[N][N];\n        int off_grid[SEED_COUNT - PLANT_COUNT];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                grid[i][j] = current_planting[i * N + j];\n            }\n        }\n        for (int i = 0; i < SEED_COUNT - PLANT_COUNT; ++i) {\n            off_grid[i] = current_planting[PLANT_COUNT + i];\n        }\n\n        // Calculate initial total potential score.\n        auto get_total_score = [&]() {\n            long long score = 0;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (i + 1 < N) score += P2[grid[i][j]][grid[i + 1][j]];\n                    if (j + 1 < N) score += P2[grid[i][j]][grid[i][j + 1]];\n                }\n            }\n            return score;\n        };\n\n        long long current_score = get_total_score();\n        long long best_score = current_score;\n        int best_grid[N][N];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                best_grid[i][j] = grid[i][j];\n            }\n        }\n\n        // Hill-climbing optimization to improve planting arrangement.\n        auto start_turn_time = chrono::steady_clock::now();\n        int iter = 0;\n        while (true) {\n            // Periodically check elapsed time to respect turn limits.\n            if ((iter & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_turn_time).count();\n                if (elapsed > 185) break;\n            }\n            iter++;\n\n            int type = rng() % 2;\n            if (type == 0) {\n                // Type 0 Move: Swap two seeds already in the grid.\n                int r1 = rng() % N, c1 = rng() % N;\n                int r2 = rng() % N, c2 = rng() % N;\n                if (r1 == r2 && c1 == c2) continue;\n\n                long long old_local = 0;\n                if (r1 > 0) old_local += P2[grid[r1][c1]][grid[r1 - 1][c1]];\n                if (r1 < N - 1) old_local += P2[grid[r1][c1]][grid[r1 + 1][c1]];\n                if (c1 > 0) old_local += P2[grid[r1][c1]][grid[r1][c1 - 1]];\n                if (c1 < N - 1) old_local += P2[grid[r1][c1]][grid[r1][c1 + 1]];\n                \n                if (r2 > 0) old_local += P2[grid[r2][c2]][grid[r2 - 1][c2]];\n                if (r2 < N - 1) old_local += P2[grid[r2][c2]][grid[r2 + 1][c2]];\n                if (c2 > 0) old_local += P2[grid[r2][c2]][grid[r2][c2 - 1]];\n                if (c2 < N - 1) old_local += P2[grid[r2][c2]][grid[r2][c2 + 1]];\n                \n                // Account for the edge between r1,c1 and r2,c2 if they are adjacent.\n                if (abs(r1 - r2) + abs(c1 - c2) == 1) {\n                    old_local -= P2[grid[r1][c1]][grid[r2][c2]];\n                }\n\n                swap(grid[r1][c1], grid[r2][c2]);\n\n                long long new_local = 0;\n                if (r1 > 0) new_local += P2[grid[r1][c1]][grid[r1 - 1][c1]];\n                if (r1 < N - 1) new_local += P2[grid[r1][c1]][grid[r1 + 1][c1]];\n                if (c1 > 0) new_local += P2[grid[r1][c1]][grid[r1][c1 - 1]];\n                if (c1 < N - 1) new_local += P2[grid[r1][c1]][grid[r1][c1 + 1]];\n                \n                if (r2 > 0) new_local += P2[grid[r2][c2]][grid[r2 - 1][c2]];\n                if (r2 < N - 1) new_local += P2[grid[r2][c2]][grid[r2 + 1][c2]];\n                if (c2 > 0) new_local += P2[grid[r2][c2]][grid[r2][c2 - 1]];\n                if (c2 < N - 1) new_local += P2[grid[r2][c2]][grid[r2][c2 + 1]];\n                \n                if (abs(r1 - r2) + abs(c1 - c2) == 1) {\n                    new_local -= P2[grid[r1][c1]][grid[r2][c2]];\n                }\n\n                if (new_local >= old_local) {\n                    current_score += (new_local - old_local);\n                    if (current_score > best_score) {\n                        best_score = current_score;\n                        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) best_grid[i][j] = grid[i][j];\n                    }\n                } else {\n                    swap(grid[r1][c1], grid[r2][c2]); // Undo swap\n                }\n            } else {\n                // Type 1 Move: Replace a grid seed with one of the unused seeds.\n                int r1 = rng() % N, c1 = rng() % N;\n                int idx = rng() % (SEED_COUNT - PLANT_COUNT);\n\n                long long old_local = 0;\n                if (r1 > 0) old_local += P2[grid[r1][c1]][grid[r1 - 1][c1]];\n                if (r1 < N - 1) old_local += P2[grid[r1][c1]][grid[r1 + 1][c1]];\n                if (c1 > 0) old_local += P2[grid[r1][c1]][grid[r1][c1 - 1]];\n                if (c1 < N - 1) old_local += P2[grid[r1][c1]][grid[r1][c1 + 1]];\n\n                swap(grid[r1][c1], off_grid[idx]);\n\n                long long new_local = 0;\n                if (r1 > 0) new_local += P2[grid[r1][c1]][grid[r1 - 1][c1]];\n                if (r1 < N - 1) new_local += P2[grid[r1][c1]][grid[r1 + 1][c1]];\n                if (c1 > 0) new_local += P2[grid[r1][c1]][grid[r1][c1 - 1]];\n                if (c1 < N - 1) new_local += P2[grid[r1][c1]][grid[r1][c1 + 1]];\n\n                if (new_local >= old_local) {\n                    current_score += (new_local - old_local);\n                    if (current_score > best_score) {\n                        best_score = current_score;\n                        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) best_grid[i][j] = grid[i][j];\n                    }\n                } else {\n                    swap(grid[r1][c1], off_grid[idx]); // Undo swap\n                }\n            }\n        }\n\n        // Output chosen planting arrangement for this turn.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << best_grid[i][j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read newly generated seeds for the next turn.\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                if (!(cin >> seeds[i].x[j])) return 0;\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 <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Takoyaki movement simulation using a robotic arm with multiple fingertips.\n * The arm is structured as a star with several fingers attached to a central root (vertex 0).\n * Each finger is an edge of fixed length. The root can move one square at a time,\n * and each finger can rotate independently.\n */\n\nstruct Takoyaki {\n    int id;\n    int sx, sy, tx, ty;\n    int state; // 0: unpicked, 1: holding, 2: delivered\n    int finger_id;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n\n    // Read the grid configurations\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Identify start and target squares for takoyakis\n    vector<pair<int, int>> S_positions, T_positions;\n    vector<vector<bool>> grid_has_takoyaki(N, vector<bool>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') S_positions.push_back({i, j});\n            if (t_grid[i][j] == '1') T_positions.push_back({i, j});\n            grid_has_takoyaki[i][j] = (s_grid[i][j] == '1');\n        }\n    }\n\n    // Match each initial takoyaki to a target square greedily\n    vector<Takoyaki> takoyakis(M);\n    vector<bool> target_assigned(M, false);\n    for (int i = 0; i < M; ++i) {\n        int best_j = -1, best_dist = 1e9;\n        for (int j = 0; j < M; ++j) {\n            if (!target_assigned[j]) {\n                int dist = abs(S_positions[i].first - T_positions[j].first) + abs(S_positions[i].second - T_positions[j].second);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_j = j;\n                }\n            }\n        }\n        takoyakis[i] = {i, S_positions[i].first, S_positions[i].second, T_positions[best_j].first, T_positions[best_j].second, 0, -1};\n        target_assigned[best_j] = true;\n    }\n\n    // Design the robotic arm: a star with V-1 fingers of various lengths\n    cout << V << \"\\n\";\n    vector<int> finger_lengths(V);\n    vector<int> finger_dirs(V, 0); // Absolute direction: 0:R, 1:D, 2:L, 3:U\n    vector<int> finger_holding(V, -1);\n    for (int i = 1; i < V; ++i) {\n        finger_lengths[i] = min(i, N - 1); // Length between 1 and N-1\n        cout << 0 << \" \" << finger_lengths[i] << \"\\n\";\n    }\n    int rx = 0, ry = 0; // Root current position\n    cout << rx << \" \" << ry << \"\\n\";\n\n    // Row and column changes for the 4 absolute directions\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n\n    // Helper function to update direction via rotation\n    auto get_rot_char = [&](int& cur_d, int target_d) {\n        if (cur_d == target_d) return '.';\n        if ((cur_d + 1) % 4 == target_d) { cur_d = (cur_d + 1) % 4; return 'R'; }\n        if ((cur_d + 3) % 4 == target_d) { cur_d = (cur_d + 3) % 4; return 'L'; }\n        cur_d = (cur_d + 1) % 4; return 'R'; // Requires two steps, start with one\n    };\n\n    int delivered_count = 0;\n    int turns = 0;\n    while (delivered_count < M && turns < 100000) {\n        // Find a focal takoyaki and finger to move\n        int focus_j = -1, focus_f = -1;\n        // Check if any finger is already holding a takoyaki\n        for (int j = 0; j < M; ++j) {\n            if (takoyakis[j].state == 1) { // HOLDING\n                focus_j = j; focus_f = takoyakis[j].finger_id; break;\n            }\n        }\n        // If no finger is busy, find an unpicked takoyaki and a free finger\n        if (focus_j == -1) {\n            for (int j = 0; j < M; ++j) {\n                if (takoyakis[j].state == 0) { focus_j = j; break; }\n            }\n            if (focus_j == -1) break; // Everything moved\n            for (int f = 1; f < V; ++f) {\n                if (finger_holding[f] == -1) { focus_f = f; break; }\n            }\n        }\n        // If still no focus finger (all fingers busy), focus on any held takoyaki\n        if (focus_f == -1) {\n            for (int j = 0; j < M; ++j) {\n                if (takoyakis[j].state == 1) {\n                    focus_j = j; focus_f = takoyakis[j].finger_id; break;\n                }\n            }\n        }\n        if (focus_f == -1) break; // Should not happen in this logic\n\n        // Target coordinates for the focus fingertip\n        int tx = (takoyakis[focus_j].state == 0) ? takoyakis[focus_j].sx : takoyakis[focus_j].tx;\n        int ty = (takoyakis[focus_j].state == 0) ? takoyakis[focus_j].sy : takoyakis[focus_j].ty;\n\n        // Choose root target position and finger direction that minimizes root movement\n        int best_path_dist = 1e9, target_rx = -1, target_ry = -1, target_d = -1;\n        for (int d = 0; d < 4; ++d) {\n            int trx = tx - dr[d] * finger_lengths[focus_f];\n            int try_ = ty - dc[d] * finger_lengths[focus_f];\n            if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                int dist = abs(trx - rx) + abs(try_ - ry);\n                if (dist < best_path_dist) {\n                    best_path_dist = dist; target_rx = trx; target_ry = try_; target_d = d;\n                }\n            }\n        }\n\n        // Move the arm and operate fingers until focus takoyaki changes state\n        int focus_initial_state = takoyakis[focus_j].state;\n        while (takoyakis[focus_j].state == focus_initial_state && turns < 100000) {\n            string turn_op = \"\";\n            // 1. Determine root movement\n            if (rx < target_rx) { rx++; turn_op += 'D'; }\n            else if (rx > target_rx) { rx--; turn_op += 'U'; }\n            else if (ry < target_ry) { ry++; turn_op += 'R'; }\n            else if (ry > target_ry) { ry--; turn_op += 'L'; }\n            else turn_op += '.';\n\n            // 2. Determine rotations (rotate focus finger towards target direction)\n            for (int f = 1; f < V; ++f) {\n                if (f == focus_f && (rx != target_rx || ry != target_ry || finger_dirs[f] != target_d)) {\n                    turn_op += get_rot_char(finger_dirs[f], target_d);\n                } else turn_op += '.';\n            }\n\n            // 3. Perform actions (Pick or Drop) for all fingertips\n            string act_part = \".\"; // Action for vertex 0 (never a fingertip)\n            for (int f = 1; f < V; ++f) {\n                int fr = rx + dr[finger_dirs[f]] * finger_lengths[f];\n                int fc = ry + dc[finger_dirs[f]] * finger_lengths[f];\n                bool acted = false;\n                if (fr >= 0 && fr < N && fc >= 0 && fc < N) {\n                    if (finger_holding[f] == -1) {\n                        // Check if current fingertip position has an unpicked takoyaki\n                        for (int j = 0; j < M; ++j) {\n                            if (takoyakis[j].state == 0 && takoyakis[j].sx == fr && takoyakis[j].sy == fc) {\n                                takoyakis[j].state = 1; takoyakis[j].finger_id = f;\n                                finger_holding[f] = j; grid_has_takoyaki[fr][fc] = false;\n                                act_part += 'P'; acted = true; break;\n                            }\n                        }\n                    } else {\n                        // Check if current fingertip position matches the target square for its takoyaki\n                        int j = finger_holding[f];\n                        if (takoyakis[j].tx == fr && takoyakis[j].ty == fc && !grid_has_takoyaki[fr][fc]) {\n                            takoyakis[j].state = 2; finger_holding[f] = -1;\n                            grid_has_takoyaki[fr][fc] = true; delivered_count++;\n                            act_part += 'P'; acted = true;\n                        }\n                    }\n                }\n                if (!acted) act_part += '.';\n            }\n            cout << turn_op << act_part << \"\\n\";\n            turns++;\n            if (delivered_count == M) break;\n            \n            // Re-evaluate if focus is stuck (e.g., target square is occupied)\n            if (rx == target_rx && ry == target_ry && finger_dirs[focus_f] == target_d && takoyakis[focus_j].state == focus_initial_state) {\n                if (takoyakis[focus_j].state == 1 && grid_has_takoyaki[takoyakis[focus_j].tx][takoyakis[focus_j].ty]) break;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n// Coordinate range and grid size\nconst int W = 100000;\nconst int G = 200;\nconst int CELL = W / G;\n\nstruct Point {\n    int x, y;\n};\n\nstruct Result {\n    long long score;\n    vector<pair<int, int>> path;\n    int i_start;\n    bool swapped;\n};\n\n// Global tables to avoid stack overflow and reuse memory efficiently\n// Using static memory in a world-class algorithm engineering context for speed and capacity.\nstatic int cell_score[G][G];\nstatic int row_sum[G][G + 1];\nstatic long long dp[G][G][G];\nstatic pair<short, short> p_table[G][G][G];\nstatic long long S[G][G];\nstatic pair<short, short> best_LR_S[G][G];\n\n// The core algorithm finds an x-monotone rectilinear polygon.\n// It uses dynamic programming over a grid of columns to find the optimal sequence of y-intervals.\nResult solve(int N, const vector<Point>& macks, const vector<Point>& sards, bool swap_xy) {\n    vector<Point> m = macks, s = sards;\n    if (swap_xy) {\n        for (int i = 0; i < N; ++i) {\n            swap(m[i].x, m[i].y);\n            swap(s[i].x, s[i].y);\n        }\n    }\n\n    // Reset grid counts for each call\n    for (int i = 0; i < G; ++i)\n        for (int j = 0; j < G; ++j)\n            cell_score[i][j] = 0;\n\n    // Distribute fish into grid cells\n    for (int i = 0; i < N; ++i) {\n        int gx = min(G - 1, m[i].x / CELL);\n        int gy = min(G - 1, m[i].y / CELL);\n        cell_score[gx][gy]++;\n    }\n    for (int i = 0; i < N; ++i) {\n        int gx = min(G - 1, s[i].x / CELL);\n        int gy = min(G - 1, s[i].y / CELL);\n        cell_score[gx][gy]--;\n    }\n\n    // Prepare row sums for fast O(1) interval score lookup\n    for (int i = 0; i < G; ++i) {\n        row_sum[i][0] = 0;\n        for (int j = 0; j < G; ++j) {\n            row_sum[i][j + 1] = row_sum[i][j] + cell_score[i][j];\n        }\n    }\n\n    // O(G^3) DP to find the best connected x-monotone rectilinear shape\n    for (int i = 0; i < G; ++i) {\n        if (i > 0) {\n            // Compute prefix maximum over the previous column's DP results\n            // This ensures overlapping intervals between adjacent columns (connectivity).\n            for (int x = 0; x < G; ++x) {\n                for (int y = 0; y < G; ++y) {\n                    if (x <= y) {\n                        S[x][y] = dp[i - 1][x][y];\n                        best_LR_S[x][y] = { (short)x, (short)y };\n                    } else {\n                        S[x][y] = -1e18;\n                    }\n                }\n            }\n            // 2D prefix max in O(G^2)\n            for (int x = 0; x < G; ++x) {\n                for (int y = G - 1; y >= 0; --y) {\n                    if (x > 0 && S[x - 1][y] > S[x][y]) {\n                        S[x][y] = S[x - 1][y];\n                        best_LR_S[x][y] = best_LR_S[x - 1][y];\n                    }\n                    if (y < G - 1 && S[x][y + 1] > S[x][y]) {\n                        S[x][y] = S[x][y + 1];\n                        best_LR_S[x][y] = best_LR_S[x][y + 1];\n                    }\n                }\n            }\n        }\n\n        // DP transition: extend existing shape or start a new one\n        for (int L = 0; L < G; ++L) {\n            for (int R = L; R < G; ++R) {\n                long long cur_score = (long long)row_sum[i][R + 1] - row_sum[i][L];\n                if (i > 0 && S[R][L] > 0) {\n                    dp[i][L][R] = cur_score + S[R][L];\n                    p_table[i][L][R] = best_LR_S[R][L];\n                } else {\n                    dp[i][L][R] = cur_score;\n                    p_table[i][L][R] = { -1, -1 };\n                }\n            }\n        }\n    }\n\n    // Find the global maximum score\n    long long best_total_score = -1e18;\n    int best_i = -1, best_L = -1, best_R = -1;\n    for (int i = 0; i < G; ++i) {\n        for (int L = 0; L < G; ++L) {\n            for (int R = L; R < G; ++R) {\n                if (dp[i][L][R] > best_total_score) {\n                    best_total_score = dp[i][L][R];\n                    best_i = i;\n                    best_L = L;\n                    best_R = R;\n                }\n            }\n        }\n    }\n\n    if (best_i == -1) return { -1, {}, -1, false };\n\n    // Backtrack to extract the optimal polygon structure\n    vector<pair<int, int>> path;\n    int curr_i = best_i;\n    int curr_L = best_L;\n    int curr_R = best_R;\n    while (curr_i >= 0 && curr_L != -1) {\n        path.push_back({ curr_L, curr_R });\n        auto p = p_table[curr_i][curr_L][curr_R];\n        curr_L = p.first;\n        curr_R = p.second;\n        curr_i--;\n    }\n    reverse(path.begin(), path.end());\n\n    return { best_total_score, path, best_i - (int)path.size() + 1, swap_xy };\n}\n\n// Perimeter length check to satisfy polygon constraints\nlong long calc_len(const vector<pair<int, int>>& unique_v) {\n    if (unique_v.empty()) return 0;\n    long long total_len = 0;\n    for (int i = 0; i < (int)unique_v.size(); ++i) {\n        int next = (i + 1) % (int)unique_v.size();\n        total_len += abs(unique_v[i].first - unique_v[next].first) + abs(unique_v[i].second - unique_v[next].second);\n    }\n    return total_len;\n}\n\n// Convert DP path result into official vertex format\nvoid output(const Result& res) {\n    // If no positive score is found, provide a minimal default solution\n    if (res.score < 0) {\n        cout << \"4\\n0 0\\n0 1\\n1 1\\n1 0\" << endl;\n        return;\n    }\n\n    int i_start = res.i_start;\n    int i_end = i_start + (int)res.path.size() - 1;\n    vector<pair<int, int>> v;\n\n    // Trace the boundary clockwise around the chosen set of cells\n    v.push_back({ i_start * CELL, res.path[0].first * CELL });\n    v.push_back({ i_start * CELL, (res.path[0].second + 1) * CELL });\n    for (int i = 0; i < (int)res.path.size() - 1; ++i) {\n        v.push_back({ (i_start + i + 1) * CELL, (res.path[i].second + 1) * CELL });\n        v.push_back({ (i_start + i + 1) * CELL, (res.path[i + 1].second + 1) * CELL });\n    }\n    v.push_back({ (i_end + 1) * CELL, (res.path.back().second + 1) * CELL });\n    v.push_back({ (i_end + 1) * CELL, res.path.back().first * CELL });\n    for (int i = (int)res.path.size() - 1; i > 0; --i) {\n        v.push_back({ (i_start + i) * CELL, res.path[i].first * CELL });\n        v.push_back({ (i_start + i) * CELL, res.path[i - 1].first * CELL });\n    }\n\n    // Restore original axes if solving the transposed problem\n    if (res.swapped) {\n        for (auto& p : v) swap(p.first, p.second);\n    }\n\n    // Distinct vertex constraint: remove consecutive duplicates\n    vector<pair<int, int>> unique_v;\n    for (int i = 0; i < (int)v.size(); ++i) {\n        if (i == 0 || v[i] != v[i - 1]) {\n            unique_v.push_back(v[i]);\n        }\n    }\n    if (unique_v.size() > 1 && unique_v.front() == unique_v.back()) {\n        unique_v.pop_back();\n    }\n\n    // Validation check for constraints\n    if (calc_len(unique_v) > 400000 || unique_v.size() > 1000) {\n        cout << \"4\\n0 0\\n0 1\\n1 1\\n1 0\" << endl;\n        return;\n    }\n\n    cout << unique_v.size() << endl;\n    for (auto p : unique_v) {\n        cout << p.first << \" \" << p.second << endl;\n    }\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    vector<Point> macks(N), sards(N);\n    for (int i = 0; i < N; ++i) cin >> macks[i].x >> macks[i].y;\n    for (int i = 0; i < N; ++i) cin >> sards[i].x >> sards[i].y;\n\n    // Check both x-monotone and y-monotone polygons and select the better one\n    Result res1 = solve(N, macks, sards, false);\n    Result res2 = solve(N, macks, sards, true);\n\n    if (res1.score >= res2.score) {\n        output(res1);\n    } else {\n        output(res2);\n    }\n\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Structure to represent a placed rectangle on the 2D plane\nstruct Rect {\n    long long x, y, w, h;\n    long long xw, yh; // Precalculated x+w and y+h for faster overlap checks\n};\n\n// Structure to represent a packing configuration for N rectangles\nstruct Config {\n    vector<int> r;     // Rotation: 0 (no rotation), 1 (90 degrees rotation)\n    vector<char> d;    // Direction: 'U' (Upward), 'L' (Leftward)\n    vector<int> b;     // Reference rectangle index (-1 or 0 to i-1)\n};\n\nint N, T;\ndouble sigma;\nvector<long long> w_obs, h_obs;\n\n// Timer utility to manage time budget within the 3.0-second limit\nauto start_time = chrono::steady_clock::now();\ndouble elapsed_time() {\n    auto now = chrono::steady_clock::now();\n    return chrono::duration<double>(now - start_time).count();\n}\n\n/**\n * Packs rectangles from index k to N-1 based on the configuration and current rectangle dimensions.\n * Previous placements (0 to k-1) are assumed to be fixed in the `placed` array.\n */\nlong long evaluate(const vector<long long>& w, const vector<long long>& h,\n                   const Config& config, Rect* placed, int k) {\n    for (int i = k; i < N; ++i) {\n        // Determine actual width and height based on rotation\n        long long cur_w = config.r[i] ? h[i] : w[i];\n        long long cur_h = config.r[i] ? w[i] : h[i];\n        long long cur_x, cur_y;\n\n        if (config.d[i] == 'U') {\n            // Place to the right of reference rectangle b[i]\n            cur_x = (config.b[i] == -1) ? 0 : placed[config.b[i]].xw;\n            cur_y = 0;\n            long long cur_x_plus_w = cur_x + cur_w;\n            // Move up until it hits another rectangle or y=0\n            for (int j = 0; j < i; ++j) {\n                if (cur_x < placed[j].xw && placed[j].x < cur_x_plus_w) {\n                    cur_y = max(cur_y, placed[j].yh);\n                }\n            }\n        } else {\n            // Place below the bottom edge of reference rectangle b[i]\n            cur_y = (config.b[i] == -1) ? 0 : placed[config.b[i]].yh;\n            cur_x = 0;\n            long long cur_y_plus_h = cur_y + cur_h;\n            // Move left until it hits another rectangle or x=0\n            for (int j = 0; j < i; ++j) {\n                if (cur_y < placed[j].yh && placed[j].y < cur_y_plus_h) {\n                    cur_x = max(cur_x, placed[j].xw);\n                }\n            }\n        }\n        // Update the placed information for the current rectangle\n        placed[i] = {cur_x, cur_y, cur_w, cur_h, cur_x + cur_w, cur_y + cur_h};\n    }\n\n    // Calculate the bounding box dimensions W and H\n    long long W = 0, H = 0;\n    for (int i = 0; i < N; ++i) {\n        W = max(W, placed[i].xw);\n        H = max(H, placed[i].yh);\n    }\n    return W + H; // We minimize W + H as a proxy for the perimeter-based shipping cost\n}\n\nint main() {\n    // Optimization for fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Initial input reading\n    if (!(cin >> N >> T >> sigma)) return 0;\n    w_obs.resize(N);\n    h_obs.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Random number generator with a fixed seed\n    mt19937 rng(42);\n    Config current_config;\n    current_config.r.assign(N, 0);\n    current_config.d.assign(N, 'U');\n    current_config.b.assign(N, -1);\n\n    // Initial random configuration\n    for (int i = 0; i < N; ++i) {\n        current_config.r[i] = rng() % 2;\n        current_config.d[i] = (rng() % 2) ? 'U' : 'L';\n        current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n    }\n\n    Rect placed[105];\n    long long current_score = evaluate(w_obs, h_obs, current_config, placed, 0);\n\n    // Main loop for T turns\n    for (int t = 0; t < T; ++t) {\n        double turn_start_time = elapsed_time();\n        // Allocate time fairly among remaining turns\n        double turn_time_limit = (2.85 - turn_start_time) / (T - t);\n\n        // Bayesian estimation approach: sample w, h from normal distribution based on measurements\n        vector<long long> w_sample(N), h_sample(N);\n        for (int i = 0; i < N; ++i) {\n            w_sample[i] = max(1LL, (long long)round(normal_distribution<double>((double)w_obs[i], sigma)(rng)));\n            h_sample[i] = max(1LL, (long long)round(normal_distribution<double>((double)h_obs[i], sigma)(rng)));\n        }\n\n        // Occasional random restart to escape local optima over turns\n        if (t > 0 && uniform_real_distribution<double>(0, 1)(rng) < 0.1) {\n            for (int i = 0; i < N; ++i) {\n                current_config.r[i] = rng() % 2;\n                current_config.d[i] = (rng() % 2) ? 'U' : 'L';\n                current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n            }\n        }\n        current_score = evaluate(w_sample, h_sample, current_config, placed, 0);\n\n        Config best_in_turn = current_config;\n        long long best_score_in_turn = current_score;\n\n        // Simulated Annealing parameters\n        double t_start = sigma * 2.0;\n        double t_end = 100.0;\n        \n        while (elapsed_time() - turn_start_time < turn_time_limit) {\n            // Select a random rectangle k and change its placement parameters\n            int k = rng() % N;\n            int old_r = current_config.r[k];\n            char old_d = current_config.d[k];\n            int old_b = current_config.b[k];\n            Rect backup_placed[105];\n            for (int i = k; i < N; ++i) backup_placed[i] = placed[i];\n\n            int type = rng() % 4;\n            if (type == 0) current_config.r[k] = 1 - current_config.r[k];\n            else if (type == 1) current_config.d[k] = (current_config.d[k] == 'U' ? 'L' : 'U');\n            else if (type == 2) current_config.b[k] = (int)(rng() % (k + 1)) - 1;\n            else {\n                current_config.r[k] = 1 - current_config.r[k];\n                current_config.d[k] = (current_config.d[k] == 'U' ? 'L' : 'U');\n                current_config.b[k] = (int)(rng() % (k + 1)) - 1;\n            }\n\n            // Partially re-evaluate the configuration starting from index k\n            long long new_score = evaluate(w_sample, h_sample, current_config, placed, k);\n            double time_ratio = (elapsed_time() - turn_start_time) / turn_time_limit;\n            double temp = t_start * pow(t_end / t_start, time_ratio);\n\n            // Accept or reject based on Metropolis criterion\n            if (new_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - new_score) / temp)) {\n                current_score = new_score;\n                if (new_score < best_score_in_turn) {\n                    best_score_in_turn = new_score;\n                    best_in_turn = current_config;\n                }\n            } else {\n                // Rollback changes if neighbor is rejected\n                current_config.r[k] = old_r;\n                current_config.d[k] = old_d;\n                current_config.b[k] = old_b;\n                for (int i = k; i < N; ++i) placed[i] = backup_placed[i];\n            }\n        }\n\n        // Final output for the current turn\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; ++i) {\n            cout << i << \" \" << best_in_turn.r[i] << \" \" << best_in_turn.d[i] << \" \" << best_in_turn.b[i] << \"\\n\";\n        }\n        cout.flush();\n\n        // Read measured feedback from the environment (W', H')\n        long long W_prime, H_prime;\n        if (!(cin >> W_prime >> H_prime)) break;\n\n        // Use the best found configuration as a starting point for the next turn\n        current_config = best_in_turn;\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// Maximum number of vertices as defined in the problem\nconst int MAXN = 1000;\nint N, M, H_limit;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nint depth[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_depth_rel[MAXN];\n\n/**\n * Checks if vertex u is an ancestor of vertex v.\n * Since the tree depth is at most 10, this check runs in O(H_limit).\n */\nbool is_ancestor(int u, int v) {\n    if (u == -1) return false;\n    if (depth[u] > depth[v]) return false;\n    int curr = v;\n    while (curr != -1) {\n        if (curr == u) return true;\n        if (depth[curr] <= depth[u]) break;\n        curr = parent[curr];\n    }\n    return false;\n}\n\n/**\n * Updates the depth of all vertices in the subtree of vertex v recursively.\n */\nvoid update_subtree_depth(int v, int diff) {\n    if (diff == 0) return;\n    depth[v] += diff;\n    for (int child : children[v]) {\n        update_subtree_depth(child, diff);\n    }\n}\n\n/**\n * Recomputes the subtree_sum_A and max_depth_rel for a vertex and its ancestors.\n * Limited to H_limit steps as the trees cannot be deeper than 10.\n */\nvoid update_ancestors(int curr) {\n    int count = 0;\n    while (curr != -1 && count <= 12) {\n        long long sum = A[curr];\n        int mx = 0;\n        for (int child : children[curr]) {\n            sum += subtree_sum_A[child];\n            mx = max(mx, max_depth_rel[child] + 1);\n        }\n        subtree_sum_A[curr] = sum;\n        max_depth_rel[curr] = mx;\n        curr = parent[curr];\n        count++;\n    }\n}\n\n/**\n * Moves vertex v to a new parent new_p. Handles subtree updates and ancestor recalculations.\n */\nvoid move_v(int v, int new_p) {\n    int old_p = parent[v];\n    if (old_p != -1) {\n        auto& cv = children[old_p];\n        for (size_t i = 0; i < cv.size(); ++i) {\n            if (cv[i] == v) {\n                cv[i] = cv.back();\n                cv.pop_back();\n                break;\n            }\n        }\n        update_ancestors(old_p);\n    }\n    \n    parent[v] = new_p;\n    if (new_p != -1) {\n        children[new_p].push_back(v);\n        update_ancestors(new_p);\n    }\n    \n    int old_depth = depth[v];\n    int new_depth = (new_p == -1 ? 0 : depth[new_p] + 1);\n    update_subtree_depth(v, new_depth - old_depth);\n}\n\nint main() {\n    // Standard fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> H_limit)) 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    // Read and ignore vertex coordinates, as they are not needed for the tree logic\n    int x_tmp, y_tmp;\n    for (int i = 0; i < N; ++i) cin >> x_tmp >> y_tmp;\n\n    // Initialization: each node starts as a root of its own tree\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        depth[i] = 0;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_depth_rel[i] = 0;\n    }\n\n    mt19937 mt(42);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    // Sort vertices by beauty value descending to give higher values more depth in greedy phase\n    sort(order.begin(), order.end(), [&](int i, int j){ return A[i] > A[j]; });\n\n    // Initial Greedy phase to create a better starting point for SA\n    for (int v : order) {\n        int best_p = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (!is_ancestor(v, u) && depth[u] + 1 + max_depth_rel[v] <= H_limit) {\n                if (depth[u] > max_d) {\n                    max_d = depth[u];\n                    best_p = u;\n                }\n            }\n        }\n        // If a deeper parent is found, move v there\n        if (best_p != -1 && depth[best_p] + 1 > depth[v]) {\n            move_v(v, best_p);\n        }\n    }\n\n    // Simulated Annealing setup\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 500.0;\n    double T_end = 0.01;\n    double log_T_ratio = log(T_end / T_start);\n    long long iter = 0;\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    double T = T_start;\n\n    // Main SA Loop\n    while (true) {\n        if (iter % 2000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double t = chrono::duration<double>(current_time - start_time).count();\n            if (t > 1.95) break; // Time limit: 2 seconds\n            T = T_start * exp(log_T_ratio * t / 1.95);\n        }\n        \n        // Randomly pick a vertex and a potential new parent from its neighbors or -1 (root)\n        int v = uniform_int_distribution<int>(0, N - 1)(mt);\n        int neighbor_idx = uniform_int_distribution<int>(0, adj[v].size())(mt);\n        int new_p = (neighbor_idx == (int)adj[v].size()) ? -1 : adj[v][neighbor_idx];\n        \n        if (new_p == parent[v]) {\n            iter++;\n            continue;\n        }\n\n        // Validate the move: cycle check and maximum height constraint\n        if (new_p != -1) {\n            if (is_ancestor(v, new_p)) {\n                iter++;\n                continue;\n            }\n            if (depth[new_p] + 1 + max_depth_rel[v] > H_limit) {\n                iter++;\n                continue;\n            }\n        }\n\n        // Calculate the score change: Delta = (new_h - old_h) * Sum(A_subtree)\n        int old_depth = depth[v];\n        int new_depth = (new_p == -1 ? 0 : depth[new_p] + 1);\n        long long delta = (long long)(new_depth - old_depth) * subtree_sum_A[v];\n\n        // Metropolis acceptance criterion\n        if (delta >= 0 || dist(mt) < exp((double)delta / T)) {\n            move_v(v, new_p);\n        }\n        iter++;\n    }\n\n    // Output the parent array of the constructed forest\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 <tuple>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We have an N x N board (N=20) with Oni ('x') and Fukunokami ('o').\n * Operations: Shift row/column by 1 square. Pieces pushed off are removed.\n * Goal: Remove all Oni, keep all Fukunokami, in as few moves as possible.\n *\n * Algorithm:\n * For each Oni, we identify which of the four directions (Left, Right, Up, Down)\n * is \"safe\" \u2013 that is, no Fukunokami exists between the Oni and that edge.\n * We assign each Oni one of its safe directions and calculate the total move\n * cost for a \"move-back\" strategy. In this strategy, for each row or column \n * that needs moves, we shift it enough to remove the required Oni and then \n * shift it back to restore the board for future operations.\n *\n * Cost Function:\n * Let T_L[i] be the maximum distance from the left edge needed to remove all\n * Oni in row i that were assigned the 'Left' direction. The move-back cost\n * for row i left-shifts is 2 * T_L[i]. The total moves T is the sum of these\n * costs across all rows, columns, and directions.\n *\n * optimization:\n * Since each Oni can pick from multiple safe directions, we use hill climbing\n * to find an assignment of directions that minimizes the total cost T.\n */\n\nconst int N = 20;\n\nstruct Oni {\n    int r, c, id;\n    vector<int> safe_dirs; // L:0, R:1, U:2, D:3\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in;\n    if (!(cin >> n_in)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Identify all Oni and their initially safe directions\n    vector<Oni> onis;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                Oni oni;\n                oni.r = i;\n                oni.c = j;\n                oni.id = (int)onis.size();\n                \n                // Direction safety check:\n                // L:0, R:1, U:2, D:3\n                bool L_safe = true;\n                for (int k = 0; k < j; ++k) if (board[i][k] == 'o') L_safe = false;\n                if (L_safe) oni.safe_dirs.push_back(0);\n\n                bool R_safe = true;\n                for (int k = j + 1; k < N; ++k) if (board[i][k] == 'o') R_safe = false;\n                if (R_safe) oni.safe_dirs.push_back(1);\n\n                bool U_safe = true;\n                for (int k = 0; k < i; ++k) if (board[k][j] == 'o') U_safe = false;\n                if (U_safe) oni.safe_dirs.push_back(2);\n\n                bool D_safe = true;\n                for (int k = i + 1; k < N; ++k) if (board[k][j] == 'o') D_safe = false;\n                if (D_safe) oni.safe_dirs.push_back(3);\n\n                onis.push_back(oni);\n            }\n        }\n    }\n\n    if (onis.empty()) return 0;\n\n    // Cost calculation: 2 * sum of max distances in each row/column direction\n    auto calc_cost = [&](const vector<int>& dirs) {\n        int T_L[N] = {0}, T_R[N] = {0}, T_U[N] = {0}, T_D[N] = {0};\n        for (int i = 0; i < (int)onis.size(); ++i) {\n            if (dirs[i] == 0) T_L[onis[i].r] = max(T_L[onis[i].r], onis[i].c + 1);\n            else if (dirs[i] == 1) T_R[onis[i].r] = max(T_R[onis[i].r], N - onis[i].c);\n            else if (dirs[i] == 2) T_U[onis[i].c] = max(T_U[onis[i].c], onis[i].r + 1);\n            else if (dirs[i] == 3) T_D[onis[i].c] = max(T_D[onis[i].c], N - onis[i].r);\n        }\n        int cost = 0;\n        for (int i = 0; i < N; ++i) {\n            cost += 2 * (T_L[i] + T_R[i] + T_U[i] + T_D[i]);\n        }\n        return cost;\n    };\n\n    // Initial assignment: pick the direction with the minimum distance for each Oni\n    vector<int> d(onis.size());\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        int best_dir = onis[i].safe_dirs[0];\n        int min_dist = 100;\n        for (int dir : onis[i].safe_dirs) {\n            int dist = 0;\n            if (dir == 0) dist = onis[i].c + 1;\n            else if (dir == 1) dist = N - onis[i].c;\n            else if (dir == 2) dist = onis[i].r + 1;\n            else if (dir == 3) dist = N - onis[i].r;\n            if (dist < min_dist) {\n                min_dist = dist;\n                best_dir = dir;\n            }\n        }\n        d[i] = best_dir;\n    }\n\n    int current_cost = calc_cost(d);\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    // Hill Climbing Search\n    long long iter = 0;\n    while (true) {\n        // Time management\n        if ((iter & 1023) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) break;\n        }\n        iter++;\n\n        // Select a random Oni and a random alternative safe direction\n        int k = rng() % onis.size();\n        if (onis[k].safe_dirs.size() <= 1) continue;\n        int old_dir = d[k];\n        int new_dir = onis[k].safe_dirs[rng() % onis[k].safe_dirs.size()];\n        if (old_dir == new_dir) continue;\n\n        // Evaluate change\n        d[k] = new_dir;\n        int new_cost = calc_cost(d);\n        if (new_cost <= current_cost) {\n            current_cost = new_cost;\n        } else {\n            d[k] = old_dir;\n        }\n    }\n\n    // Determine final shift requirements for each row and column\n    int T_L[N] = {0}, T_R[N] = {0}, T_U[N] = {0}, T_D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        if (d[i] == 0) T_L[onis[i].r] = max(T_L[onis[i].r], onis[i].c + 1);\n        else if (d[i] == 1) T_R[onis[i].r] = max(T_R[onis[i].r], N - onis[i].c);\n        else if (d[i] == 2) T_U[onis[i].c] = max(T_U[onis[i].c], onis[i].r + 1);\n        else if (d[i] == 3) T_D[onis[i].c] = max(T_D[onis[i].c], N - onis[i].r);\n    }\n\n    // Output all moves using the move-back strategy to ensure safety\n    for (int i = 0; i < N; ++i) {\n        if (T_L[i] > 0) {\n            for (int k = 0; k < T_L[i]; ++k) cout << \"L \" << i << \"\\n\";\n            for (int k = 0; k < T_L[i]; ++k) cout << \"R \" << i << \"\\n\";\n        }\n        if (T_R[i] > 0) {\n            for (int k = 0; k < T_R[i]; ++k) cout << \"R \" << i << \"\\n\";\n            for (int k = 0; k < T_R[i]; ++k) cout << \"L \" << i << \"\\n\";\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        if (T_U[j] > 0) {\n            for (int k = 0; k < T_U[j]; ++k) cout << \"U \" << j << \"\\n\";\n            for (int k = 0; k < T_U[j]; ++k) cout << \"D \" << j << \"\\n\";\n        }\n        if (T_D[j] > 0) {\n            for (int k = 0; k < T_D[j]; ++k) cout << \"D \" << j << \"\\n\";\n            for (int k = 0; k < T_D[j]; ++k) cout << \"U \" << j << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We need to determine two integers a_i and b_i for each employee i (0 to N-1).\n * Employee 0 cleans in Week 1.\n * Subsequent cleaners are decided by a simple rule based on how many times the previous cleaner had cleaned.\n * Objective: Minimize the sum of absolute differences between actual and target cleaner counts over 500,000 weeks.\n *\n * Algorithm Strategy:\n * 1. Model the cleaner assignment as a flow problem.\n *    Each employee i calls a_i on odd cleaning occurrences and b_i on even occurrences.\n *    Target cleaning count T_i suggests i calls a_i ceil(T_i/2) times and b_i floor(T_i/2) times.\n * 2. Use a proxy for the actual counts:\n *    current_T_j = (1 if j==0 else 0) + sum_{i in reachable_from_0} (U_i * (1 if a_i==j) + V_i * (1 if b_i==j))\n *    where U_i = ceil(T_i/2) and V_i = floor(T_i/2).\n * 3. Optimize the error cost sum(|current_T_j - T_j|) using Simulated Annealing (SA).\n * 4. The proxy cost accounts for reachability from employee 0. Nodes not reachable have an actual count of 0.\n */\n\nconst int N = 100;\n\n// Global arrays for efficient SA iterations\nbool reachable_node[N];\nint bfs_q[N];\nlong long cur_t_arr[N];\n\n/**\n * Computes the error cost proxy based on target counts and current assignments.\n * Complexity: O(N) where N = 100.\n */\nlong long get_cost(const int* cur_a, const int* cur_b, const long long* U, const long long* V, const long long* T_target) {\n    // Determine reachable nodes from starting employee 0\n    for (int i = 0; i < N; ++i) reachable_node[i] = false;\n    int head = 0, tail = 0;\n    bfs_q[tail++] = 0;\n    reachable_node[0] = true;\n    while (head < tail) {\n        int u = bfs_q[head++];\n        int v1 = cur_a[u];\n        if (!reachable_node[v1]) {\n            reachable_node[v1] = true;\n            bfs_q[tail++] = v1;\n        }\n        int v2 = cur_b[u];\n        if (!reachable_node[v2]) {\n            reachable_node[v2] = true;\n            bfs_q[tail++] = v2;\n        }\n    }\n\n    // Calculate approximate cleaner counts based on target call distribution\n    for (int i = 0; i < N; ++i) cur_t_arr[i] = 0;\n    cur_t_arr[0] = 1; // Week 1 starter\n    for (int i = 0; i < N; ++i) {\n        if (reachable_node[i]) {\n            cur_t_arr[cur_a[i]] += U[i];\n            cur_t_arr[cur_b[i]] += V[i];\n        }\n    }\n\n    // Sum absolute differences between proxy counts and target counts\n    long long err = 0;\n    for (int j = 0; j < N; ++j) {\n        if (reachable_node[j]) {\n            err += abs(cur_t_arr[j] - T_target[j]);\n        } else {\n            // Unreachable nodes contribute their full target count to the error\n            err += T_target[j];\n        }\n    }\n    return err;\n}\n\nint main() {\n    // Speed up standard input and output\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_val, l_val;\n    if (!(cin >> n_val >> l_val)) return 0;\n\n    long long target_T[N];\n    for (int i = 0; i < N; ++i) {\n        cin >> target_T[i];\n    }\n\n    // Precompute the call distribution for each employee based on target counts\n    long long U_calls[N], V_calls[N];\n    for (int i = 0; i < N; ++i) {\n        // U is for odd t-th cleaning occurrences; V is for even t-th occurrences\n        U_calls[i] = (target_T[i] + 1) / 2;\n        V_calls[i] = target_T[i] / 2;\n    }\n\n    // Initialize assignments randomly\n    int cur_a[N], cur_b[N];\n    mt19937 random_engine(1337);\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = random_engine() % N;\n        cur_b[i] = random_engine() % N;\n    }\n\n    long long current_err_cost = get_cost(cur_a, cur_b, U_calls, V_calls, target_T);\n    int best_assigned_a[N], best_assigned_b[N];\n    for (int i = 0; i < N; ++i) {\n        best_assigned_a[i] = cur_a[i];\n        best_assigned_b[i] = cur_b[i];\n    }\n    long long best_err_cost = current_err_cost;\n\n    // Simulated Annealing Parameters\n    auto start_timestamp = chrono::steady_clock::now();\n    int iteration_count = 0;\n    const int max_limit_iterations = 50000000; // Large enough to saturate the time limit\n    const double temp_start = 2500.0;\n    const double temp_end = 0.01;\n    const double duration_limit = 1.96; // Safe buffer below 2.0s\n    double current_elapsed_time = 0;\n\n    uniform_real_distribution<double> real_dist(0.0, 1.0);\n\n    while (iteration_count < max_limit_iterations) {\n        iteration_count++;\n        // Periodic time check\n        if ((iteration_count & 1023) == 0) {\n            auto current_timestamp = chrono::steady_clock::now();\n            current_elapsed_time = chrono::duration<double>(current_timestamp - start_timestamp).count();\n            if (current_elapsed_time > duration_limit) break;\n        }\n\n        // Propose a random change in assignment\n        int target_idx = random_engine() % N;\n        int transition_choice = random_engine() % 2;\n        int original_val = (transition_choice == 0 ? cur_a[target_idx] : cur_b[target_idx]);\n        int replacement_val = random_engine() % N;\n        if (original_val == replacement_val) continue;\n\n        if (transition_choice == 0) cur_a[target_idx] = replacement_val;\n        else cur_b[target_idx] = replacement_val;\n\n        long long updated_err_cost = get_cost(cur_a, cur_b, U_calls, V_calls, target_T);\n        \n        // Decide whether to accept the new state based on temperature\n        double annealing_temp = temp_start * pow(temp_end / temp_start, current_elapsed_time / duration_limit);\n        if (updated_err_cost <= current_err_cost || real_dist(random_engine) < exp((double)(current_err_cost - updated_err_cost) / annealing_temp)) {\n            current_err_cost = updated_err_cost;\n            if (current_err_cost < best_err_cost) {\n                best_err_cost = current_err_cost;\n                for (int k = 0; k < N; ++k) {\n                    best_assigned_a[k] = cur_a[k];\n                    best_assigned_b[k] = cur_b[k];\n                }\n            }\n        } else {\n            // Reject and revert state\n            if (transition_choice == 0) cur_a[target_idx] = original_val;\n            else cur_b[target_idx] = original_val;\n        }\n    }\n\n    // Final result output\n    for (int i = 0; i < N; ++i) {\n        cout << best_assigned_a[i] << \" \" << best_assigned_b[i] << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Standard Edge structure for MST with tie-breaking\nstruct Edge {\n    int u, v;\n    long long d;\n    bool operator<(const Edge& other) const {\n        if (d != other.d) return d < other.d;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<double> hat_x, hat_y;\nint est_dist[800][800];\nbool is_query_edge[800][800];\n\n// Returns a distance value that incorporates tie-breaking as specified by the problem.\n// Distance d first, then lexicographical order (u, v) with u < v.\nlong long get_unique_dist(int u, int v) {\n    if (u > v) swap(u, v);\n    return (long long)est_dist[u][v] * 1000000LL + (long long)u * 1000LL + (long long)v;\n}\n\n// Prim's algorithm for finding the MST length of a group in O(V^2).\n// Used as the objective function in simulated annealing.\nint mst_prim(const vector<int>& group) {\n    int n = (int)group.size();\n    if (n <= 1) return 0;\n    static int min_d[800];\n    static bool visited[800];\n    for (int i = 0; i < n; i++) {\n        min_d[i] = est_dist[group[0]][group[i]];\n        visited[i] = false;\n    }\n    visited[0] = true;\n    int total = 0;\n    for (int i = 0; i < n - 1; i++) {\n        int u = -1;\n        int best_d = 2000000000;\n        for (int j = 0; j < n; j++) {\n            if (!visited[j] && min_d[j] < best_d) {\n                best_d = min_d[j];\n                u = j;\n            }\n        }\n        if (u == -1) break;\n        visited[u] = true;\n        total += best_d;\n        int gu = group[u];\n        for (int j = 0; j < n; j++) {\n            if (!visited[j]) {\n                int d = est_dist[gu][group[j]];\n                if (d < min_d[j]) min_d[j] = d;\n            }\n        }\n    }\n    return total;\n}\n\n// Helper for query generation: DFS order to traverse MST edges linearly.\nvoid get_dfs_order(int u, int p, const vector<vector<int>>& adj, vector<int>& order) {\n    order.push_back(u);\n    for (int v : adj[u]) {\n        if (v != p) {\n            get_dfs_order(v, u, adj, order);\n        }\n    }\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial input reading\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    hat_x.resize(N); hat_y.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        hat_x[i] = (lx[i] + rx[i]) / 2.0;\n        hat_y[i] = (ly[i] + ry[i]) / 2.0;\n    }\n\n    // Precompute estimated integer distances using bounding box centers\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) est_dist[i][j] = 0;\n            else {\n                double dx = hat_x[i] - hat_x[j];\n                double dy = hat_y[i] - hat_y[j];\n                est_dist[i][j] = (int)floor(sqrt(dx * dx + dy * dy) + 1e-9);\n            }\n        }\n    }\n\n    // Heuristic initial grouping: simple spatial sort\n    vector<int> cities(N);\n    for (int i = 0; i < N; i++) cities[i] = i;\n    sort(cities.begin(), cities.end(), [&](int a, int b) {\n        if (hat_x[a] + hat_y[a] != hat_x[b] + hat_y[b])\n            return hat_x[a] + hat_y[a] < hat_x[b] + hat_y[b];\n        return a < b;\n    });\n\n    vector<vector<int>> groups(M);\n    int city_cursor = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(cities[city_cursor++]);\n        }\n    }\n\n    // Grouping optimization via Simulated Annealing\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    auto get_time = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    double current_total_mst = 0;\n    vector<int> group_mst_lengths(M);\n    for (int i = 0; i < M; i++) {\n        group_mst_lengths[i] = mst_prim(groups[i]);\n        current_total_mst += group_mst_lengths[i];\n    }\n\n    while (get_time() < 1.0) {\n        int idxA = rng() % M;\n        int idxB = rng() % M;\n        if (idxA == idxB || groups[idxA].empty() || groups[idxB].empty()) continue;\n\n        int posA = rng() % (int)groups[idxA].size();\n        int posB = rng() % (int)groups[idxB].size();\n\n        swap(groups[idxA][posA], groups[idxB][posB]);\n        int new_mstA = mst_prim(groups[idxA]);\n        int new_mstB = mst_prim(groups[idxB]);\n        double new_total = current_total_mst - group_mst_lengths[idxA] - group_mst_lengths[idxB] + new_mstA + new_mstB;\n\n        double progress = get_time() / 1.0;\n        double T = 100.0 * (1.0 - progress);\n\n        if (new_total < current_total_mst || (T > 0 && exp((current_total_mst - new_total) / T) > (double)rng() / rng.max())) {\n            current_total_mst = new_total;\n            group_mst_lengths[idxA] = new_mstA;\n            group_mst_lengths[idxB] = new_mstB;\n        } else {\n            swap(groups[idxA][posA], groups[idxB][posB]);\n        }\n    }\n\n    // Perform queries to obtain true MST information\n    int queries_made = 0;\n    for (int i = 0; i < M; i++) {\n        if (groups[i].size() <= 1) continue;\n        int gn = (int)groups[i].size();\n        \n        // Find a representative path of the estimated MST for the current group\n        vector<Edge> candidate_mst_edges;\n        for (int u_idx = 0; u_idx < gn; u_idx++) {\n            for (int v_idx = u_idx + 1; v_idx < gn; v_idx++) {\n                candidate_mst_edges.push_back({u_idx, v_idx, get_unique_dist(groups[i][u_idx], groups[i][v_idx])});\n            }\n        }\n        sort(candidate_mst_edges.begin(), candidate_mst_edges.end());\n        vector<vector<int>> adj(gn);\n        vector<int> parent(gn);\n        for (int j = 0; j < gn; j++) parent[j] = j;\n        auto find_root = [&](auto self, int node) -> int {\n            return (parent[node] == node) ? node : (parent[node] = self(self, parent[node]));\n        };\n        int count_edges = 0;\n        for (auto& e : candidate_mst_edges) {\n            int rootU = find_root(find_root, e.u), rootV = find_root(find_root, e.v);\n            if (rootU != rootV) {\n                adj[e.u].push_back(e.v); adj[e.v].push_back(e.u);\n                parent[rootU] = rootV;\n                if (++count_edges == gn - 1) break;\n            }\n        }\n\n        vector<int> dfs_order;\n        get_dfs_order(0, -1, adj, dfs_order);\n        \n        // Use overlapping subset queries along the DFS path to ensure connectivity\n        for (int j = 0; j + 1 < gn; j += (L - 1)) {\n            if (queries_made >= Q) break;\n            int l_size = min(gn - j, L);\n            cout << \"? \" << l_size;\n            for (int k = 0; k < l_size; k++) cout << \" \" << groups[i][dfs_order[j + k]];\n            cout << endl;\n            queries_made++;\n            for (int k = 0; k < l_size - 1; k++) {\n                int u, v; cin >> u >> v;\n                is_query_edge[u][v] = is_query_edge[v][u] = true;\n            }\n        }\n    }\n\n    // Exhaust remaining queries on random subsets of valid groups\n    while (queries_made < Q) {\n        int target_grp = rng() % M;\n        if (groups[target_grp].size() <= 1) {\n            bool found = false;\n            for (int k = 0; k < M; k++) if (groups[k].size() > 1) { target_grp = k; found = true; break; }\n            if (!found) break;\n        }\n        int gn = (int)groups[target_grp].size();\n        int l_size = min(gn, L);\n        vector<int> subset = groups[target_grp];\n        shuffle(subset.begin(), subset.end(), rng);\n        cout << \"? \" << l_size;\n        for (int k = 0; k < l_size; k++) cout << \" \" << subset[k];\n        cout << endl;\n        queries_made++;\n        for (int k = 0; k < l_size - 1; k++) {\n            int u, v; cin >> u >> v;\n            is_query_edge[u][v] = is_query_edge[v][u] = true;\n        }\n    }\n\n    // Output final results\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        int gn = (int)groups[i].size();\n        for (int j = 0; j < gn; j++) cout << groups[i][j] << (j == gn - 1 ? \"\" : \" \");\n        cout << endl;\n        if (gn > 1) {\n            // Find MST using true query edges where possible, falling back to estimated distances\n            vector<Edge> group_candidate_edges;\n            for (int u_idx = 0; u_idx < gn; u_idx++) {\n                for (int v_idx = u_idx + 1; v_idx < gn; v_idx++) {\n                    int u = groups[i][u_idx], v = groups[i][v_idx];\n                    long long ud = get_unique_dist(u, v);\n                    // Use a large offset to prioritize query-returned edges\n                    if (is_query_edge[u][v]) ud -= 1000000000000LL; \n                    group_candidate_edges.push_back({u, v, ud});\n                }\n            }\n            sort(group_candidate_edges.begin(), group_candidate_edges.end());\n            vector<int> dsu_parent(N);\n            for (int j = 0; j < N; j++) dsu_parent[j] = j;\n            auto find_dsu = [&](auto self, int node) -> int {\n                return (dsu_parent[node] == node) ? node : (dsu_parent[node] = self(self, dsu_parent[node]));\n            };\n            int edges_constructed = 0;\n            for (auto& e : group_candidate_edges) {\n                int rootU = find_dsu(find_dsu, e.u), rootV = find_dsu(find_dsu, e.v);\n                if (rootU != rootV) {\n                    cout << e.u << \" \" << e.v << endl;\n                    dsu_parent[rootU] = rootV;\n                    if (++edges_constructed == gn - 1) break;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 20;\nconst int M = 40;\nconst int INF = 1e9;\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dchar[] = {'U', 'D', 'L', 'R'};\n\nstruct Target {\n    int r, c;\n};\n\nstruct Action {\n    char type;\n    char dir;\n};\n\nstruct Result {\n    int cost;\n    vector<Action> actions;\n};\n\nstruct Node {\n    int r, c, h, cost;\n    bool operator>(const Node& other) const {\n        return cost > other.cost;\n    }\n};\n\nbool in_bounds(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Pre-allocate memory for Dijkstra to avoid repeated allocation\nint dists[N][N][2];\nstruct Parent {\n    int r, c, h;\n    char type, dir;\n} parents[N][N][2];\n\n// Dijkstra's algorithm to find the shortest path from start to target.\n// Optionally allows adding one block at (br, bc) during the path.\nResult dijkstra(int start_r, int start_c, int target_r, int target_c, const vector<vector<bool>>& grid, int br, int bc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j][0] = dists[i][j][1] = INF;\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[start_r][start_c][0] = 0;\n    pq.push({start_r, start_c, 0, 0});\n\n    while (!pq.empty()) {\n        Node curr = pq.top(); pq.pop();\n        if (curr.cost > dists[curr.r][curr.c][curr.h]) continue;\n        if (curr.r == target_r && curr.c == target_c) break;\n\n        // 1. Move action: cost 1 if empty, cost 2 if it requires 'Alter' to remove a block.\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i], nc = curr.c + dc[i];\n            if (in_bounds(nr, nc)) {\n                bool is_block = grid[nr][nc] || (curr.h && nr == br && nc == bc);\n                int cost = is_block ? 2 : 1;\n                // If we move into the added block (br, bc), it gets removed.\n                int next_h = (curr.h && (nr != br || nc != bc)) ? 1 : 0;\n                if (dists[nr][nc][next_h] > curr.cost + cost) {\n                    dists[nr][nc][next_h] = curr.cost + cost;\n                    parents[nr][nc][next_h] = {curr.r, curr.c, curr.h, 'M', dchar[i]};\n                    pq.push({nr, nc, next_h, dists[nr][nc][next_h]});\n                }\n            }\n        }\n\n        // 2. Slide action: cost 1 regardless of distance.\n        for (int i = 0; i < 4; ++i) {\n            int sr = curr.r, sc = curr.c;\n            while (true) {\n                int nr = sr + dr[i], nc = sc + dc[i];\n                if (!in_bounds(nr, nc) || grid[nr][nc] || (curr.h && nr == br && nc == bc)) break;\n                sr = nr; sc = nc;\n            }\n            if (sr != curr.r || sc != curr.c) {\n                if (dists[sr][sc][curr.h] > curr.cost + 1) {\n                    dists[sr][sc][curr.h] = curr.cost + 1;\n                    parents[sr][sc][curr.h] = {curr.r, curr.c, curr.h, 'S', dchar[i]};\n                    pq.push({sr, sc, curr.h, dists[sr][sc][curr.h]});\n                }\n            }\n        }\n\n        // 3. Place block (only if br, bc provided and h=0)\n        if (br != -1 && curr.h == 0) {\n            for (int i = 0; i < 4; ++i) {\n                if (curr.r + dr[i] == br && curr.c + dc[i] == bc) {\n                    if (dists[curr.r][curr.c][1] > curr.cost + 1) {\n                        dists[curr.r][curr.c][1] = curr.cost + 1;\n                        parents[curr.r][curr.c][1] = {curr.r, curr.c, 0, 'A', dchar[i]};\n                        pq.push({curr.r, curr.c, 1, dists[curr.r][curr.c][1]});\n                    }\n                }\n            }\n        }\n    }\n\n    int best_h = (dists[target_r][target_c][1] < dists[target_r][target_c][0]) ? 1 : 0;\n    if (dists[target_r][target_c][best_h] == INF) return {INF, {}};\n\n    // Path reconstruction\n    vector<Action> actions;\n    int cr = target_r, cc = target_c, ch = best_h;\n    while (cr != start_r || cc != start_c || ch != 0) {\n        Parent p = parents[cr][cc][ch];\n        if (p.type == 'M') {\n            bool was_block = grid[cr][cc] || (p.h && cr == br && cc == bc);\n            if (was_block) actions.push_back({'A', p.dir});\n            actions.push_back({'M', p.dir});\n        } else if (p.type == 'S') {\n            actions.push_back({'S', p.dir});\n        } else if (p.type == 'A') {\n            actions.push_back({'A', p.dir});\n        }\n        cr = p.r; cc = p.c; ch = p.h;\n    }\n    reverse(actions.begin(), actions.end());\n    return {dists[target_r][target_c][best_h], actions};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::steady_clock::now();\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    vector<Target> targets(m_in);\n    for (int i = 0; i < m_in; ++i) cin >> targets[i].r >> targets[i].c;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    int curr_r = targets[0].r, curr_c = targets[0].c;\n\n    for (int k = 1; k < m_in; ++k) {\n        int tr = targets[k].r, tc = targets[k].c;\n        Result best_res = dijkstra(curr_r, curr_c, tr, tc, grid, -1, -1);\n        \n        // Try all possible block placements that could assist in reaching the target via 'Slide'.\n        bool timeout = false;\n        for (int br = 0; br < N; ++br) {\n            for (int bc = 0; bc < N; ++bc) {\n                // Adaptive timeout management\n                auto current_time = chrono::steady_clock::now();\n                if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) {\n                    timeout = true; break;\n                }\n                if (grid[br][bc] || (br == tr && bc == tc) || (br == curr_r && bc == curr_c)) continue;\n                \n                // Heuristic skip: only consider blocks near target or curr pos, or in line with them\n                if (abs(br - tr) + abs(bc - tc) > 3 && br != tr && bc != tc && br != curr_r && bc != curr_c) continue;\n                \n                Result res = dijkstra(curr_r, curr_c, tr, tc, grid, br, bc);\n                if (res.cost < best_res.cost) {\n                    best_res = res;\n                }\n            }\n            if (timeout) break;\n        }\n\n        // Output actions and update the state of the rink\n        for (auto& act : best_res.actions) {\n            cout << act.type << \" \" << act.dir << \"\\n\";\n            int dr_val = (act.dir == 'U' ? -1 : act.dir == 'D' ? 1 : 0);\n            int dc_val = (act.dir == 'L' ? -1 : act.dir == 'R' ? 1 : 0);\n            if (act.type == 'A') {\n                grid[curr_r + dr_val][curr_c + dc_val] = !grid[curr_r + dr_val][curr_c + dc_val];\n            } else if (act.type == 'M') {\n                curr_r += dr_val; curr_c += dc_val;\n            } else if (act.type == 'S') {\n                int d_idx = (act.dir == 'U' ? 0 : act.dir == 'D' ? 1 : act.dir == 'L' ? 2 : 3);\n                while (true) {\n                    int nr = curr_r + dr[d_idx], nc = curr_c + dc[d_idx];\n                    if (!in_bounds(nr, nc) || grid[nr][nc]) break;\n                    curr_r = nr; curr_c = nc;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <numeric>\n\nusing namespace std;\n\n// Structure for axis-parallel rectangles\nstruct Rect {\n    int a, b, c, d; // (a, b) is bottom-left, (c, d) is top-right\n};\n\n// Structure for company data\nstruct Company {\n    int x, y, r;\n    Rect rect;\n    double p;\n};\n\n// Calculate satisfaction p_i\ninline double get_p(int a, int b, int c, int d, int r) {\n    long long s = (long long)(c - a) * (d - b);\n    if (s <= 0) return 0.0;\n    double ratio = (s < (long long)r) ? (double)s / r : (double)r / s;\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Check if two rectangles overlap with positive area\ninline bool overlaps(const Rect& r1, const Rect& r2) {\n    return max(r1.a, r2.a) < min(r1.c, r2.c) &&\n           max(r1.b, r2.b) < min(r1.d, r2.d);\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<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        // Start with 1x1 rectangles containing the required points\n        companies[i].rect = {companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1};\n        companies[i].p = get_p(companies[i].rect.a, companies[i].rect.b, companies[i].rect.c, companies[i].rect.d, companies[i].r);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    // Phase 1: Initial Greedy Expansion (fast way to get a solid starting layout)\n    for (int iter = 0; iter < 150; ++iter) {\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3}; // 0:L, 1:B, 2:R, 3:T\n            shuffle(dirs, dirs + 4, rng);\n            for (int dir : dirs) {\n                Rect next = companies[i].rect;\n                if (dir == 0 && next.a > 0) next.a--;\n                else if (dir == 1 && next.b > 0) next.b--;\n                else if (dir == 2 && next.c < 10000) next.c++;\n                else if (dir == 3 && next.d < 10000) next.d++;\n                else continue;\n\n                // Ensure target point stays inside\n                if (next.a > companies[i].x || next.c <= companies[i].x ||\n                    next.b > companies[i].y || next.d <= companies[i].y) continue;\n\n                bool ok = true;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next, companies[j].rect)) { ok = false; break; }\n                }\n                if (ok) {\n                    companies[i].rect = next;\n                    companies[i].p = get_p(next.a, next.b, next.c, next.d, companies[i].r);\n                }\n            }\n        }\n    }\n\n    // Phase 2: Simulated Annealing with \"Push\" Moves\n    double current_total_p = 0;\n    for (int i = 0; i < n; ++i) current_total_p += companies[i].p;\n\n    double T_start = 0.01; // Initial temperature\n    double T_end = 0.0001;  // Final temperature\n    const double TIME_LIMIT = 4.8;\n\n    long long iter = 0;\n    vector<pair<int, Rect>> changes;\n    changes.reserve(n);\n\n    while (true) {\n        if ((iter & 1023) == 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            double progress = elapsed / TIME_LIMIT;\n            double T = T_start + (T_end - T_start) * progress; // Linear cooling\n\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            int side = uniform_int_distribution<int>(0, 3)(rng);\n            \n            int old_val;\n            if (side == 0) old_val = companies[i].rect.a;\n            else if (side == 1) old_val = companies[i].rect.b;\n            else if (side == 2) old_val = companies[i].rect.c;\n            else old_val = companies[i].rect.d;\n\n            int new_val;\n            int r_move = uniform_int_distribution<int>(0, 99)(rng);\n            if (r_move < 70) new_val = old_val + uniform_int_distribution<int>(-100, 100)(rng);\n            else if (r_move < 90) new_val = old_val + uniform_int_distribution<int>(-500, 500)(rng);\n            else if (r_move < 95) { // Try to reach target area\n                int current_w = companies[i].rect.c - companies[i].rect.a;\n                int current_h = companies[i].rect.d - companies[i].rect.b;\n                if (side == 0) new_val = companies[i].rect.c - (companies[i].r / max(1, current_h));\n                else if (side == 1) new_val = companies[i].rect.d - (companies[i].r / max(1, current_w));\n                else if (side == 2) new_val = companies[i].rect.a + (companies[i].r / max(1, current_h));\n                else new_val = companies[i].rect.b + (companies[i].r / max(1, current_w));\n            } else new_val = uniform_int_distribution<int>(0, 10000)(rng);\n\n            new_val = max(0, min(10000, new_val));\n            if (new_val == old_val) { iter++; continue; }\n\n            Rect next_i = companies[i].rect;\n            if (side == 0) next_i.a = new_val;\n            else if (side == 1) next_i.b = new_val;\n            else if (side == 2) next_i.c = new_val;\n            else next_i.d = new_val;\n\n            bool can_move = true;\n            // Validate basic rectangle properties and point inclusion\n            if (next_i.a >= next_i.c || next_i.b >= next_i.d ||\n                !(next_i.a <= companies[i].x && companies[i].x < next_i.c) ||\n                !(next_i.b <= companies[i].y && companies[i].y < next_i.d)) {\n                can_move = false;\n            }\n\n            changes.clear();\n            if (can_move) {\n                changes.push_back({i, next_i});\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next_i, companies[j].rect)) {\n                        Rect next_j = companies[j].rect;\n                        // Resolve overlap by shrinking j\n                        if (side == 0) next_j.c = next_i.a;\n                        else if (side == 1) next_j.d = next_i.b;\n                        else if (side == 2) next_j.a = next_i.c;\n                        else next_j.b = next_i.d;\n\n                        if (next_j.a >= next_j.c || next_j.b >= next_j.d ||\n                            !(next_j.a <= companies[j].x && companies[j].x < next_j.c) ||\n                            !(next_j.b <= companies[j].y && companies[j].y < next_j.d)) {\n                            can_move = false;\n                            break;\n                        }\n                        changes.push_back({j, next_j});\n                    }\n                }\n            }\n\n            if (can_move) {\n                double new_p_sum = current_total_p;\n                for (auto& ch : changes) {\n                    new_p_sum -= companies[ch.first].p;\n                    new_p_sum += get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                }\n\n                double delta = new_p_sum - current_total_p;\n                if (delta >= 0 || uniform_real_distribution<double>(0, 1)(rng) < exp(delta / T)) {\n                    current_total_p = new_p_sum;\n                    for (auto& ch : changes) {\n                        companies[ch.first].rect = ch.second;\n                        companies[ch.first].p = get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                    }\n                }\n            }\n        }\n        iter++;\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << companies[i].rect.a << \" \" << companies[i].rect.b << \" \"\n             << companies[i].rect.c << \" \" << companies[i].rect.d << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <bitset>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to find a path on a 50x50 grid with tile constraints.\n * - Each square belongs to a tile (1x1, 1x2, or 2x1).\n * - Each tile can be visited at most once.\n * - The goal is to maximize the sum of values p[i][j] of visited squares.\n * \n * Algorithm Improvement:\n * - Use Beam Search with a larger beam width (K=10000).\n * - Diversity constraint: keep at most B=10 paths per square at each step.\n * - Optimize bitset operations and state memory management.\n * - Use a history pointer system to reconstruct the path after the search.\n */\n\n// Grid and maximum tile constants\nconst int GRID_SIZE = 50;\nconst int MAX_TILES = 2500;\n\n// PathNode for reconstructing the final path from the search history\nstruct PathNode {\n    int parent_idx;\n    short r, c;\n    char move;\n};\n\n// State representing a partial path in the beam search\nstruct State {\n    int score;\n    int history_idx;\n    short r, c;\n    bitset<MAX_TILES> visited;\n};\n\n// Candidate for the next step of the path\nstruct Candidate {\n    int score;\n    int parent_beam_idx;\n    short ni, nj;\n    char move;\n\n    // Comparator for sorting candidates by total score in descending order.\n    // Ties are broken using coordinate values to ensure deterministic results.\n    bool operator>(const Candidate& other) const {\n        if (score != other.score) return score > other.score;\n        if (ni != other.ni) return ni > other.ni;\n        return nj > other.nj;\n    }\n};\n\nint main() {\n    // Fast I/O for better performance\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    // Read initial position\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    // Read tile configurations\n    int t[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> t[i][j];\n\n    // Read square scores\n    int p[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> p[i][j];\n\n    // Beam search configuration\n    const int K = 10000; // Maximum number of states to maintain in the beam\n    const int B = 10;    // Diversity: max number of paths allowed to end at the same grid square\n\n    // Store the history of path expansions to reconstruct the final path\n    // Using a flat vector for history to optimize memory allocation and access speed\n    vector<PathNode> history;\n    history.reserve(15000000);\n\n    // Current beam of states representing paths of the current length\n    vector<State> current_beam;\n    current_beam.reserve(K);\n\n    // Initial state: Takahashi starts at (si, sj)\n    bitset<MAX_TILES> initial_visited;\n    initial_visited.set(t[si][sj]);\n    current_beam.push_back({p[si][sj], 0, (short)si, (short)sj, initial_visited});\n    history.push_back({-1, (short)si, (short)sj, ' '});\n\n    int best_score = p[si][sj];\n    int best_history_idx = 0;\n\n    // Movement directions\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    // Candidate list for the next beam expansion\n    vector<Candidate> candidates;\n    candidates.reserve(K * 4);\n\n    // Array to track diversity per cell\n    int counts[GRID_SIZE * GRID_SIZE];\n\n    // Main Beam Search loop\n    while (true) {\n        // Exit search if time limit (2s) is nearing (leaving some margin)\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        candidates.clear();\n        // For each state in the current beam, explore all 4 adjacent moves\n        for (int i = 0; i < (int)current_beam.size(); ++i) {\n            const auto& s = current_beam[i];\n            for (int d = 0; d < 4; ++d) {\n                int ni = s.r + dr[d];\n                int nj = s.c + dc[d];\n                // Check grid boundaries\n                if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE) {\n                    // Check if the tile at the destination has already been visited\n                    if (!s.visited.test(t[ni][nj])) {\n                        candidates.push_back({s.score + p[ni][nj], i, (short)ni, (short)nj, move_chars[d]});\n                    }\n                }\n            }\n        }\n\n        // If no more valid expansions are found, stop the search\n        if (candidates.empty()) break;\n\n        // Sort all possible next moves by score to select the best states for the next beam\n        sort(candidates.begin(), candidates.end(), greater<Candidate>());\n\n        vector<State> next_beam;\n        next_beam.reserve(K);\n        memset(counts, 0, sizeof(counts));\n\n        // Fill the next beam with the top K candidates, respecting the diversity constraint B\n        for (const auto& cand : candidates) {\n            int pos = cand.ni * GRID_SIZE + cand.nj;\n            if (counts[pos] < B) {\n                if (next_beam.size() >= K) break;\n\n                State next_s;\n                next_s.score = cand.score;\n                next_s.r = cand.ni;\n                next_s.c = cand.nj;\n                // Inherit visited bitset from parent and mark the new tile\n                next_s.visited = current_beam[cand.parent_beam_idx].visited;\n                next_s.visited.set(t[cand.ni][cand.nj]);\n                next_s.history_idx = (int)history.size();\n                \n                // Track expansion history\n                history.push_back({current_beam[cand.parent_beam_idx].history_idx, cand.ni, cand.nj, cand.move});\n                \n                // Update overall best path found\n                if (next_s.score > best_score) {\n                    best_score = next_s.score;\n                    best_history_idx = next_s.history_idx;\n                }\n\n                next_beam.push_back(std::move(next_s));\n                counts[pos]++;\n            }\n        }\n\n        // Move to the next step\n        if (next_beam.empty()) break;\n        current_beam = std::move(next_beam);\n    }\n\n    // Trace back through history to reconstruct the sequence of moves for the best path\n    string result_path = \"\";\n    int curr_node_idx = best_history_idx;\n    while (history[curr_node_idx].parent_idx != -1) {\n        result_path += history[curr_node_idx].move;\n        curr_node_idx = history[curr_node_idx].parent_idx;\n    }\n    // Reverse moves as we traced from finish to start\n    reverse(result_path.begin(), result_path.end());\n    \n    // Output the resulting path string\n    cout << result_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 * Analysis & Improved Approach:\n * 1. The problem involves a 30x30 grid with hidden edge lengths. \n * 2. Edge lengths have a strong structural pattern: edges in the same row or column \n *    are often similar (M=1 or M=2).\n * 3. The noise in feedback is +/- 10%, meaning a single query is unreliable, \n *    but the expected value is accurate.\n * 4. Earlier queries are weighted much less than later queries (0.998^(1000-k)).\n * \n * Strategy:\n * - Use Dijkstra's algorithm for pathfinding based on current edge weight estimates.\n * - For the first ~150 queries, introduce a \"bonus\" for less-visited edges to encourage exploration.\n * - Use a kernel-smoothing update rule: when a path length is measured, update the weights\n *   of edges on the path and nearby edges in the same row/column to exploit the generation logic.\n * - Apply a decaying learning rate to balance learning speed and stability against noise.\n */\n\n// Constant grid dimensions.\nconst int N = 30;\n// Constraints on edge lengths based on problem generation logic.\nconst double MIN_WEIGHT = 1000.0;\nconst double MAX_WEIGHT = 9000.0;\n// Initial weight estimate (mean of potential range).\nconst double INIT_WEIGHT = 5000.0;\n\nstruct EdgeInfo {\n    int type; // 0 for horizontal (h_weights), 1 for vertical (v_weights)\n    int i, j;\n};\n\n// Global variables to store current edge estimates and visit frequency.\ndouble h_weights[N][N - 1];\ndouble v_weights[N - 1][N];\nint h_counts[N][N - 1];\nint v_counts[N - 1][N];\n\n/**\n * Initializes weight estimates and counts.\n */\nvoid init() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            h_weights[i][j] = INIT_WEIGHT;\n            h_counts[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = INIT_WEIGHT;\n            v_counts[i][j] = 0;\n        }\n    }\n}\n\n/**\n * Calculates adjusted weight for Dijkstra search.\n * Includes exploration bias for early queries.\n */\ndouble get_dijkstra_weight(int type, int i, int j, int k) {\n    double w = (type == 0) ? h_weights[i][j] : v_weights[i][j];\n    // Encourage exploration by underestimating less-visited edges in early queries.\n    if (k < 150) {\n        int count = (type == 0) ? h_counts[i][j] : v_counts[i][j];\n        return w * (1.0 - 0.10 / (1.0 + (double)count));\n    }\n    return w;\n}\n\n/**\n * Uses Dijkstra's algorithm to compute the best path under current estimates.\n */\nstring find_path(int si, int sj, int ti, int tj, int k, vector<EdgeInfo>& path_edges) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<pair<int, int>, char>>> parent(N, vector<pair<pair<int, int>, char>>(N, {{-1, -1}, ' '}));\n    using P = pair<double, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int i = pq.top().second.first;\n        int j = pq.top().second.second;\n        pq.pop();\n\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        // Traverse edges: Up, Down, Left, Right\n        // Vertical edges connect (i, j) and (i+1, j)\n        // Horizontal edges connect (i, j) and (i, j+1)\n\n        // Up\n        if (i > 0) {\n            double w = get_dijkstra_weight(1, i - 1, j, k);\n            if (dist[i - 1][j] > d + w) {\n                dist[i - 1][j] = d + w;\n                parent[i - 1][j] = {{i, j}, 'U'};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        // Down\n        if (i < N - 1) {\n            double w = get_dijkstra_weight(1, i, j, k);\n            if (dist[i + 1][j] > d + w) {\n                dist[i + 1][j] = d + w;\n                parent[i + 1][j] = {{i, j}, 'D'};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double w = get_dijkstra_weight(0, i, j - 1, k);\n            if (dist[i][j - 1] > d + w) {\n                dist[i][j - 1] = d + w;\n                parent[i][j - 1] = {{i, j}, 'L'};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        // Right\n        if (j < N - 1) {\n            double w = get_dijkstra_weight(0, i, j, k);\n            if (dist[i][j + 1] > d + w) {\n                dist[i][j + 1] = d + w;\n                parent[i][j + 1] = {{i, j}, 'R'};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char dir = parent[ci][cj].second;\n        path += dir;\n        int pi = parent[ci][cj].first.first;\n        int pj = parent[ci][cj].first.second;\n        if (dir == 'U') {\n            path_edges.push_back({1, ci, cj});\n            v_counts[ci][cj]++;\n        } else if (dir == 'D') {\n            path_edges.push_back({1, pi, pj});\n            v_counts[pi][pj]++;\n        } else if (dir == 'L') {\n            path_edges.push_back({0, ci, cj});\n            h_counts[ci][cj]++;\n        } else if (dir == 'R') {\n            path_edges.push_back({0, pi, pj});\n            h_counts[pi][pj]++;\n        }\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/**\n * Updates estimated edge weights using a kernel-smoothing mechanism.\n * The total update shift is normalized to ensure accuracy.\n */\nvoid update_weights(const vector<EdgeInfo>& path_edges, int result, int k) {\n    double predicted_len = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) predicted_len += h_weights[e.i][e.j];\n        else predicted_len += v_weights[e.i][e.j];\n    }\n\n    double error = (double)result - predicted_len;\n    // Decaying learning rate helps stabilize estimates over time.\n    double lr = 0.5 * pow(0.9992, (double)k); \n    // Spatial smoothing constant to distribute updates along rows/columns.\n    double gamma = 0.88;\n\n    vector<vector<double>> coeff_h(N, vector<double>(N - 1, 0.0));\n    vector<vector<double>> coeff_v(N - 1, vector<double>(N, 0.0));\n\n    // Distribute error across edges in the same row/column.\n    for (const auto& e : path_edges) {\n        if (e.type == 0) {\n            for (int jp = 0; jp < N - 1; ++jp) {\n                coeff_h[e.i][jp] += pow(gamma, (double)abs(e.j - jp));\n            }\n        } else {\n            for (int ip = 0; ip < N - 1; ++ip) {\n                coeff_v[ip][e.j] += pow(gamma, (double)abs(e.i - ip));\n            }\n        }\n    }\n\n    // Normalization factor: Sum of contributions for edges on the actual path.\n    double path_coeff_sum = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) path_coeff_sum += coeff_h[e.i][e.j];\n        else path_coeff_sum += coeff_v[e.i][e.j];\n    }\n\n    if (path_coeff_sum <= 0) return;\n    double step = (error * lr) / path_coeff_sum;\n\n    // Apply the updates globally while respecting domain constraints.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            if (coeff_h[i][j] > 0) {\n                h_weights[i][j] += step * coeff_h[i][j];\n                h_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, h_weights[i][j]));\n            }\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (coeff_v[i][j] > 0) {\n                v_weights[i][j] += step * coeff_v[i][j];\n                v_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, v_weights[i][j]));\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    init();\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        vector<EdgeInfo> path_edges;\n        string path = find_path(si, sj, ti, tj, k, path_edges);\n        cout << path << endl; // cout << endl automatically flushes.\n\n        int result;\n        if (!(cin >> result)) break;\n        update_weights(path_edges, result, k);\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <cmath>\n#include <cstring>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Fast xorshift random number generator for performance\nuint32_t xorshift() {\n    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t t = x ^ (x << 11);\n    x = y; y = z; z = w;\n    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n}\n\nconst int N = 20;\nint M;\nint A[N][N];\nint best_A[N][N];\nint current_c = 0;\nint current_d = 0;\nint count_in_matrix[1000];\nint weights[1000];\nbool length_exists[13];\n\n// Hash table for mapping packed strings to unique internal IDs\nstruct HashTable {\n    static const int SIZE = 8192;\n    long long keys[SIZE];\n    int values[SIZE];\n    HashTable() { memset(keys, -1, sizeof(keys)); }\n    void insert(long long key, int val) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return;\n            h = (h + 1) & (SIZE - 1);\n        }\n        keys[h] = key;\n        values[h] = val;\n    }\n    int query(long long key) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return values[h];\n            h = (h + 1) & (SIZE - 1);\n        }\n        return -1;\n    }\n} id_map;\n\n// Pack a string into a 64-bit integer for fast comparison and hashing\nlong long pack(const string& str) {\n    long long res = 0;\n    for (char ch : str) res = (res << 3) | (ch - 'A');\n    return (res << 4) | (long long)str.length();\n}\n\n// Get packed value of a row subsequence starting at (r, start) with length L\ninline long long pack_row(int r, int start, int L) {\n    long long res = 0;\n    for (int k = 0; k < L; ++k) {\n        int pos = (start + k) % N;\n        int v = A[r][pos];\n        if (v == 0) return -1; // '.' is encountered\n        res = (res << 3) | (v - 1);\n    }\n    return (res << 4) | (long long)L;\n}\n\n// Get packed value of a column subsequence starting at (start, c) with length L\ninline long long pack_col(int c, int start, int L) {\n    long long res = 0;\n    for (int k = 0; k < L; ++k) {\n        int pos = (start + k) % N;\n        int v = A[pos][c];\n        if (v == 0) return -1; // '.' is encountered\n        res = (res << 3) | (v - 1);\n    }\n    return (res << 4) | (long long)L;\n}\n\n// Simulated annealing score function. Prioritizes maximizing 'c' (covered strings), \n// then maximizing 'd' (dots) once c equals M.\ndouble get_score(int c, int d) {\n    if (c < M) return (double)c;\n    return (double)M + (double)d / (N * N + 1.0);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n_input;\n    if (!(cin >> n_input >> M)) return 0;\n\n    vector<string> all_strings(M);\n    map<string, int> string_counts;\n    memset(length_exists, false, sizeof(length_exists));\n    for (int i = 0; i < M; ++i) {\n        cin >> all_strings[i];\n        string_counts[all_strings[i]]++;\n        length_exists[all_strings[i].length()] = true;\n    }\n\n    int k_unique = 0;\n    for (auto const& [str, weight] : string_counts) {\n        weights[k_unique] = weight;\n        id_map.insert(pack(str), k_unique);\n        k_unique++;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n\n    // Greedy initialization to pack as many strings as possible efficiently\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) A[i][j] = 0;\n    vector<string> sorted_s = all_strings;\n    sort(sorted_s.begin(), sorted_s.end(), [](const string& a, const string& b) {\n        return a.length() > b.length();\n    });\n\n    for (const string& s : sorted_s) {\n        int best_r = -1, best_c = -1, best_dir = -1;\n        int best_score = -1000000;\n        for (int dir = 0; dir < 2; ++dir) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    int score = 0;\n                    for (int k = 0; k < (int)s.length(); ++k) {\n                        int rr = (dir == 0) ? r : (r + k) % N;\n                        int cc = (dir == 0) ? (c + k) % N : c;\n                        if (A[rr][cc] == 0) score += 5;\n                        else if (A[rr][cc] == (s[k] - 'A' + 1)) score += 10;\n                        else score -= 15;\n                    }\n                    if (score > best_score) {\n                        best_score = score;\n                        best_r = r; best_c = c; best_dir = dir;\n                    }\n                }\n            }\n        }\n        for (int k = 0; k < (int)s.length(); ++k) {\n            int rr = (best_dir == 0) ? best_r : (best_r + k) % N;\n            int cc = (best_dir == 0) ? (best_c + k) % N : best_c;\n            A[rr][cc] = s[k] - 'A' + 1;\n        }\n    }\n\n    // Evaluate initial matrix state\n    memset(count_in_matrix, 0, sizeof(count_in_matrix));\n    current_c = 0; current_d = 0;\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (A[r][c] == 0) current_d++;\n            for (int L = 2; L <= 12; ++L) {\n                if (!length_exists[L]) continue;\n                long long pr = pack_row(r, c, L);\n                if (pr != -1) {\n                    int id = id_map.query(pr);\n                    if (id != -1) {\n                        if (count_in_matrix[id] == 0) current_c += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n                long long pc = pack_col(c, r, L);\n                if (pc != -1) {\n                    int id = id_map.query(pc);\n                    if (id != -1) {\n                        if (count_in_matrix[id] == 0) current_c += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n            }\n        }\n    }\n\n    double old_score = get_score(current_c, current_d);\n    double best_total_score = old_score;\n    memcpy(best_A, A, sizeof(A));\n\n    // Simulated Annealing\n    double T_start = 1.0, T_end = 0.01;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.85) break;\n        double T = T_start * pow(T_end / T_start, elapsed / 2.85);\n        \n        for (int sub = 0; sub < 100; ++sub) {\n            int r = xorshift() % N, c = xorshift() % N;\n            int old_v = A[r][c], new_v = xorshift() % 9;\n            if (new_v == old_v) continue;\n\n            int old_c = current_c, old_d = current_d;\n\n            // Compute changes to current_c based on substrings affected by A[r][c]\n            for (int L = 2; L <= 12; ++L) {\n                if (!length_exists[L]) continue;\n                for (int k_idx = 0; k_idx < L; ++k_idx) {\n                    int sc = (c - k_idx + N) % N;\n                    long long pr_old = pack_row(r, sc, L);\n                    A[r][c] = new_v;\n                    long long pr_new = pack_row(r, sc, L);\n                    A[r][c] = old_v;\n                    if (pr_old != pr_new) {\n                        if (pr_old != -1) {\n                            int id = id_map.query(pr_old);\n                            if (id != -1) { count_in_matrix[id]--; if (count_in_matrix[id] == 0) current_c -= weights[id]; }\n                        }\n                        if (pr_new != -1) {\n                            int id = id_map.query(pr_new);\n                            if (id != -1) { if (count_in_matrix[id] == 0) current_c += weights[id]; count_in_matrix[id]++; }\n                        }\n                    }\n                    int sr = (r - k_idx + N) % N;\n                    long long pc_old = pack_col(c, sr, L);\n                    A[r][c] = new_v;\n                    long long pc_new = pack_col(c, sr, L);\n                    A[r][c] = old_v;\n                    if (pc_old != pc_new) {\n                        if (pc_old != -1) {\n                            int id = id_map.query(pc_old);\n                            if (id != -1) { count_in_matrix[id]--; if (count_in_matrix[id] == 0) current_c -= weights[id]; }\n                        }\n                        if (pc_new != -1) {\n                            int id = id_map.query(pc_new);\n                            if (id != -1) { if (count_in_matrix[id] == 0) current_c += weights[id]; count_in_matrix[id]++; }\n                        }\n                    }\n                }\n            }\n\n            if (old_v == 0) current_d--;\n            if (new_v == 0) current_d++;\n            A[r][c] = new_v;\n\n            double new_score = get_score(current_c, current_d);\n            if (new_score >= old_score || exp((new_score - old_score) / T) > (double)xorshift() / 4294967295.0) {\n                old_score = new_score;\n                if (new_score > best_total_score) {\n                    best_total_score = new_score;\n                    memcpy(best_A, A, sizeof(A));\n                }\n            } else {\n                // Revert all changes\n                A[r][c] = old_v; current_c = old_c; current_d = old_d;\n                for (int L = 2; L <= 12; ++L) {\n                    if (!length_exists[L]) continue;\n                    for (int k_idx = 0; k_idx < L; ++k_idx) {\n                        int sc = (c - k_idx + N) % N;\n                        long long pr_old = pack_row(r, sc, L);\n                        A[r][c] = new_v;\n                        long long pr_new = pack_row(r, sc, L);\n                        A[r][c] = old_v;\n                        if (pr_old != pr_new) {\n                            if (pr_new != -1) { int id = id_map.query(pr_new); if (id != -1) count_in_matrix[id]--; }\n                            if (pr_old != -1) { int id = id_map.query(pr_old); if (id != -1) count_in_matrix[id]++; }\n                        }\n                        int sr = (r - k_idx + N) % N;\n                        long long pc_old = pack_col(c, sr, L);\n                        A[r][c] = new_v;\n                        long long pc_new = pack_col(c, sr, L);\n                        A[r][c] = old_v;\n                        if (pc_old != pc_new) {\n                            if (pc_new != -1) { int id = id_map.query(pc_new); if (id != -1) count_in_matrix[id]--; }\n                            if (pc_old != -1) { int id = id_map.query(pc_old); if (id != -1) count_in_matrix[id]++; }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output final results\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (best_A[i][j] == 0) cout << '.';\n            else cout << (char)('A' + best_A[i][j] - 1);\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXR = 4800; // N*N max is 4761\n\nint N, SI, SJ;\nvector<string> grid;\nstruct Road { int r, c, cost; };\nvector<Road> roads;\nint road_idx_map[70][70];\nvector<pair<int, int>> adj[MAXR];\n\nint dists[MAXR][MAXR];\nshort parents[MAXR][MAXR];\n\n// Dial's algorithm for faster all-pairs shortest paths on a grid graph\nvoid dial(int start, int* d, short* p, int R) {\n    for (int i = 0; i < R; ++i) d[i] = INF;\n    d[start] = 0;\n    p[start] = -1;\n    static vector<int> buckets[16];\n    for (int i = 0; i < 16; ++i) buckets[i].clear();\n    buckets[0].push_back(start);\n    int cur_dist = 0;\n    int empty_count = 0;\n    while (empty_count < 16) {\n        int b_idx = cur_dist & 15;\n        if (buckets[b_idx].empty()) {\n            empty_count++;\n        } else {\n            empty_count = 0;\n            while (!buckets[b_idx].empty()) {\n                int u = buckets[b_idx].back();\n                buckets[b_idx].pop_back();\n                if (d[u] < cur_dist) continue;\n                for (auto& edge : adj[u]) {\n                    int v = edge.first;\n                    int weight = edge.second;\n                    if (d[v] > cur_dist + weight) {\n                        d[v] = cur_dist + weight;\n                        p[v] = (short)u;\n                        buckets[d[v] & 15].push_back(v);\n                    }\n                }\n            }\n        }\n        cur_dist++;\n    }\n}\n\n// DFS-based bipartite matching\nbool match_dfs(int u, const vector<int> b_adj[], int match_v[], bool vis[]) {\n    for (int v : b_adj[u]) {\n        if (vis[v]) continue;\n        vis[v] = true;\n        if (match_v[v] == -1 || match_dfs(match_v[v], b_adj, match_v, vis)) {\n            match_v[v] = u;\n            return true;\n        }\n    }\n    return false;\n}\n\n// A node in the TSP can either be a fixed square or a road segment\nstruct TSPNode {\n    bool is_fixed;\n    int id; // used if fixed\n    int seg_id; // used if flexible\n    int current_square; // the square currently selected to represent the node\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    if (!(cin >> N >> SI >> SJ)) return 0;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // Identify all road squares\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_idx_map[i][j] = (int)roads.size();\n                roads.push_back({i, j, grid[i][j] - '0'});\n            } else road_idx_map[i][j] = -1;\n        }\n    }\n    int R = (int)roads.size();\n    for (int i = 0; i < R; ++i) {\n        int r = roads[i].r, c = roads[i].c;\n        int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != '#') {\n                adj[i].push_back({road_idx_map[nr][nc], grid[nr][nc] - '0'});\n            }\n        }\n    }\n\n    // Precalculate all-pairs shortest paths\n    for (int i = 0; i < R; ++i) dial(i, dists[i], parents[i], R);\n\n    // Identify maximal horizontal and vertical road segments\n    vector<vector<int>> h_segs, v_segs;\n    vector<int> h_seg_of(R), v_seg_of(R);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                if (j == 0 || grid[i][j - 1] == '#') {\n                    int sid = (int)h_segs.size();\n                    vector<int> seg;\n                    for (int k = j; k < N && grid[i][k] != '#'; ++k) {\n                        seg.push_back(road_idx_map[i][k]);\n                        h_seg_of[road_idx_map[i][k]] = sid;\n                    }\n                    h_segs.push_back(seg);\n                }\n                if (i == 0 || grid[i - 1][j] == '#') {\n                    int sid = (int)v_segs.size();\n                    vector<int> seg;\n                    for (int k = i; k < N && grid[k][j] != '#'; ++k) {\n                        seg.push_back(road_idx_map[k][j]);\n                        v_seg_of[road_idx_map[k][j]] = sid;\n                    }\n                    v_segs.push_back(seg);\n                }\n            }\n        }\n    }\n\n    int n_h = (int)h_segs.size(), n_v = (int)v_segs.size();\n    vector<int> b1_adj[n_h];\n    for (int i = 0; i < R; ++i) b1_adj[h_seg_of[i]].push_back(v_seg_of[i]);\n    for (int i = 0; i < n_h; ++i) {\n        sort(b1_adj[i].begin(), b1_adj[i].end());\n        b1_adj[i].erase(unique(b1_adj[i].begin(), b1_adj[i].end()), b1_adj[i].end());\n    }\n\n    // Minimum Vertex Cover via bipartite matching\n    int match_v[n_v], match_h[n_h];\n    fill(match_v, match_v + n_v, -1);\n    fill(match_h, match_h + n_h, -1);\n    for (int i = 0; i < n_h; ++i) {\n        bool vis[n_v]; fill(vis, vis + n_v, false);\n        match_dfs(i, b1_adj, match_v, vis);\n    }\n    for (int i = 0; i < n_v; ++i) if (match_v[i] != -1) match_h[match_v[i]] = i;\n\n    vector<bool> vis_l(n_h, false), vis_r(n_v, false);\n    vector<int> q;\n    for (int i = 0; i < n_h; ++i) if (match_h[i] == -1) { vis_l[i] = true; q.push_back(i); }\n    int head = 0;\n    while (head < (int)q.size()) {\n        int u = q[head++];\n        for (int v : b1_adj[u]) {\n            if (!vis_r[v]) {\n                vis_r[v] = true;\n                int next_u = match_v[v];\n                if (next_u != -1 && !vis_l[next_u]) { vis_l[next_u] = true; q.push_back(next_u); }\n            }\n        }\n    }\n    vector<int> MVC;\n    for (int i = 0; i < n_h; ++i) if (!vis_l[i]) MVC.push_back(i);\n    for (int i = 0; i < n_v; ++i) if (vis_r[i]) MVC.push_back(n_h + i);\n\n    // Identify segments not covered by the starting point\n    int start_node = road_idx_map[SI][SJ];\n    vector<int> M_uncovered;\n    for (int m : MVC) {\n        bool covered = false;\n        if (m < n_h) { for (int r_idx : h_segs[m]) if (r_idx == start_node) covered = true; }\n        else { for (int r_idx : v_segs[m - n_h]) if (r_idx == start_node) covered = true; }\n        if (!covered) M_uncovered.push_back(m);\n    }\n\n    // Max matching between segments to minimize unique visited squares\n    vector<int> b2_adj[n_h];\n    vector<bool> is_uncovered(n_h + n_v, false);\n    for (int m : M_uncovered) is_uncovered[m] = true;\n    for (int i = 0; i < R; ++i) {\n        int h = h_seg_of[i], v = n_h + v_seg_of[i];\n        if (is_uncovered[h] && is_uncovered[v]) b2_adj[h].push_back(v - n_h);\n    }\n    for (int i = 0; i < n_h; ++i) {\n        sort(b2_adj[i].begin(), b2_adj[i].end());\n        b2_adj[i].erase(unique(b2_adj[i].begin(), b2_adj[i].end()), b2_adj[i].end());\n    }\n\n    int match2_v[n_v], match2_h[n_h];\n    fill(match2_v, match2_v + n_v, -1);\n    fill(match2_h, match2_h + n_h, -1);\n    for (int i = 0; i < n_h; ++i) {\n        if (is_uncovered[i]) {\n            bool vis[n_v]; fill(vis, vis + n_v, false);\n            match_dfs(i, b2_adj, match2_v, vis);\n        }\n    }\n    for (int i = 0; i < n_v; ++i) if (match2_v[i] != -1) match2_h[match2_v[i]] = i;\n\n    vector<TSPNode> tsp_nodes;\n    tsp_nodes.push_back({true, start_node, -1, start_node});\n    vector<bool> m_covered(n_h + n_v, false);\n    for (int i = 0; i < n_h; ++i) {\n        if (is_uncovered[i] && match2_h[i] != -1) {\n            int mv = match2_h[i];\n            int intersect_node = -1;\n            for (int r_idx : h_segs[i]) if (v_seg_of[r_idx] == mv) intersect_node = r_idx;\n            tsp_nodes.push_back({true, intersect_node, -1, intersect_node});\n            m_covered[i] = m_covered[n_h + mv] = true;\n        }\n    }\n    for (int m : M_uncovered) {\n        if (!m_covered[m]) {\n            int default_sq = (m < n_h) ? h_segs[m][0] : v_segs[m - n_h][0];\n            tsp_nodes.push_back({false, -1, m, default_sq});\n        }\n    }\n\n    // GTSP solver: 2-opt and square optimization\n    int K = (int)tsp_nodes.size() - 1;\n    vector<int> best_tour;\n    int min_total_dist = INF;\n    vector<TSPNode> best_tsp_nodes;\n\n    mt19937 rng(42);\n    for (int rep = 0; rep < 100; ++rep) {\n        vector<int> tour(K + 1);\n        for (int i = 0; i <= K; ++i) tour[i] = i;\n        if (rep > 0) shuffle(tour.begin() + 1, tour.end(), rng);\n        \n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 1; i <= K; ++i) {\n                for (int j = i + 1; j <= K; ++j) {\n                    int p = tour[i - 1], cur = tour[i], nxt = tour[j], nn = tour[(j + 1) % (K + 1)];\n                    int d_old = dists[tsp_nodes[p].current_square][tsp_nodes[cur].current_square] + dists[tsp_nodes[nxt].current_square][tsp_nodes[nn].current_square];\n                    int d_new = dists[tsp_nodes[p].current_square][tsp_nodes[nxt].current_square] + dists[tsp_nodes[cur].current_square][tsp_nodes[nn].current_square];\n                    if (d_new < d_old) { reverse(tour.begin() + i, tour.begin() + j + 1); improved = true; }\n                }\n            }\n            for (int i = 0; i <= K; ++i) {\n                if (!tsp_nodes[tour[i]].is_fixed) {\n                    int p = tour[(i + K) % (K + 1)], nn = tour[(i + 1) % (K + 1)];\n                    int p_sq = tsp_nodes[p].current_square, nn_sq = tsp_nodes[nn].current_square;\n                    int m = tsp_nodes[tour[i]].seg_id, best_sq = -1, min_d = INF;\n                    const vector<int>& opts = (m < n_h) ? h_segs[m] : v_segs[m - n_h];\n                    for (int sq : opts) {\n                        int d = dists[p_sq][sq] + dists[sq][nn_sq];\n                        if (d < min_d) { min_d = d; best_sq = sq; }\n                    }\n                    if (best_sq != tsp_nodes[tour[i]].current_square) { tsp_nodes[tour[i]].current_square = best_sq; improved = true; }\n                }\n            }\n        }\n        int total_d = 0;\n        for (int i = 0; i <= K; ++i) total_d += dists[tsp_nodes[tour[i]].current_square][tsp_nodes[tour[(i + 1) % (K + 1)]].current_square];\n        if (total_d < min_total_dist) { min_total_dist = total_d; best_tour = tour; best_tsp_nodes = tsp_nodes; }\n    }\n\n    // Output final path\n    string res = \"\";\n    for (int i = 0; i <= K; ++i) {\n        int u = best_tsp_nodes[best_tour[i]].current_square, v = best_tsp_nodes[best_tour[(i + 1) % (K + 1)]].current_square;\n        vector<int> path;\n        int curr = v;\n        while (curr != u) { path.push_back(curr); curr = parents[u][curr]; }\n        reverse(path.begin(), path.end());\n        int prev = u;\n        for (int node : path) {\n            if (roads[node].r < roads[prev].r) res += 'U';\n            else if (roads[node].r > roads[prev].r) res += 'D';\n            else if (roads[node].c < roads[prev].c) res += 'L';\n            else res += 'R';\n            prev = node;\n        }\n    }\n    cout << res << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\n// Configuration based on problem statement\nconst int MAX_DAYS = 2000;\nconst int N_TASKS = 1000;\nconst int M_MEMBERS = 20;\n\nstruct History {\n    vector<int> d;\n    int t;\n};\n\nstruct Task {\n    int id;\n    vector<int> d;\n    vector<int> deps;\n    vector<int> rev_deps;\n    double height;\n    int descendants;\n    int status; // -1: not ready, 0: ready, 1: ongoing, 2: completed\n};\n\nstruct Member {\n    int id;\n    vector<double> s;\n    int current_task;\n    int start_day;\n    vector<History> history;\n};\n\nint N, M, K, R;\nvector<Task> tasks;\nvector<Member> members;\n\n// Calculate the difficulty term w_i,j = sum(max(0, d_i,k - s_j,k))\ndouble get_w(const vector<double>& s, const vector<int>& d) {\n    double w = 0;\n    for (int k = 0; k < K; ++k) {\n        if ((double)d[k] > s[k]) w += (double)d[k] - s[k];\n    }\n    return w;\n}\n\n// Calculate the expected number of days for completion based on w_i,j\ndouble expected_duration(double w) {\n    if (w <= 0.0) return 1.0;\n    double sum = 0;\n    for (int r = -3; r <= 3; ++r) {\n        sum += max(1.0, w + (double)r);\n    }\n    return sum / 7.0;\n}\n\n// Refined height calculation based on task duration estimates\nvoid calculate_heights() {\n    double avg_s_val = 30.0 / sqrt((double)K);\n    vector<double> avg_s(K, avg_s_val);\n    \n    vector<double> duration_ests(N);\n    for (int i = 0; i < N; ++i) {\n        duration_ests[i] = expected_duration(get_w(avg_s, tasks[i].d));\n    }\n\n    for (int i = 0; i < N; ++i) tasks[i].height = 0;\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; ++i) out_degree[i] = (int)tasks[i].rev_deps.size();\n    \n    vector<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (out_degree[i] == 0) {\n            q.push_back(i);\n            tasks[i].height = duration_ests[i];\n        }\n    }\n    \n    int head = 0;\n    while(head < (int)q.size()){\n        int v = q[head++];\n        for(int u : tasks[v].deps){\n            tasks[u].height = max(tasks[u].height, tasks[v].height + duration_ests[u]);\n            if(--out_degree[u] == 0) q.push_back(u);\n        }\n    }\n}\n\nvoid calculate_descendants() {\n    for (int i = 0; i < N; ++i) {\n        vector<bool> visited(N, false);\n        vector<int> q_d;\n        q_d.push_back(i);\n        visited[i] = true;\n        int count = 0;\n        int head = 0;\n        while(head < (int)q_d.size()){\n            int v = q_d[head++];\n            for(int next_v : tasks[v].rev_deps){\n                if(!visited[next_v]){\n                    visited[next_v] = true;\n                    q_d.push_back(next_v);\n                    count++;\n                }\n            }\n        }\n        tasks[i].descendants = count;\n    }\n}\n\n// Gradient descent to estimate team member skills from task completion history\nvoid update_skills(int m_idx) {\n    auto& m = members[m_idx];\n    if (m.history.empty()) return;\n    \n    for (int iter = 0; iter < 1000; ++iter) {\n        double eta = 0.10 / (1.0 + iter * 0.01);\n        for (const auto& h : m.history) {\n            double w = get_w(m.s, h.d);\n            double diff = 0;\n            if (h.t > 1) {\n                diff = w - (double)h.t;\n            } else {\n                // For t=1, w is likely small (0 to 4). Pull w towards a small target value.\n                diff = (w - 0.5) * 0.5;\n            }\n            if (abs(diff) < 1e-7) continue;\n            for (int k = 0; k < K; ++k) {\n                if ((double)h.d[k] > m.s[k]) {\n                    m.s[k] -= eta * diff * (-1.0);\n                }\n            }\n        }\n        // Project back to non-negative and satisfy the known norm constraints [20, 60]\n        double norm2 = 0;\n        for (int k = 0; k < K; ++k) {\n            m.s[k] = max(0.0, m.s[k]);\n            norm2 += m.s[k] * m.s[k];\n        }\n        double norm = sqrt(norm2);\n        if (norm < 20.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 20.0 / norm;\n        } else if (norm > 60.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 60.0 / norm;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    tasks.resize(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].id = i;\n        tasks[i].d.resize(K);\n        for (int k = 0; k < K; ++k) cin >> tasks[i].d[k];\n        tasks[i].status = -1;\n    }\n    \n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        tasks[v].deps.push_back(u);\n        tasks[u].rev_deps.push_back(v);\n    }\n    \n    calculate_heights();\n    calculate_descendants();\n    \n    members.resize(M);\n    for (int j = 0; j < M; ++j) {\n        members[j].id = j;\n        members[j].s.assign(K, 40.0 / sqrt((double)K));\n        members[j].current_task = -1;\n    }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        \n        // Update task status based on completed dependencies\n        for (int i = 0; i < N; ++i) {\n            if (tasks[i].status == -1) {\n                bool ok = true;\n                for (int dep : tasks[i].deps) {\n                    if (tasks[dep].status != 2) { ok = false; break; }\n                }\n                if (ok) tasks[i].status = 0;\n            }\n        }\n        \n        vector<int> idle_members, ready_tasks;\n        for (int j = 0; j < M; ++j) if (members[j].current_task == -1) idle_members.push_back(j);\n        for (int i = 0; i < N; ++i) if (tasks[i].status == 0) ready_tasks.push_back(i);\n        \n        vector<pair<int, int>> assignments;\n        while (!idle_members.empty() && !ready_tasks.empty()) {\n            double best_score = -1e18;\n            int best_m_idx = -1, best_t_idx = -1;\n            int best_m_in_idle = -1, best_t_in_ready = -1;\n\n            for (int mi = 0; mi < (int)idle_members.size(); ++mi) {\n                int j = idle_members[mi];\n                for (int ti = 0; ti < (int)ready_tasks.size(); ++ti) {\n                    int i = ready_tasks[ti];\n                    double w_est = get_w(members[j].s, tasks[i].d);\n                    double dur = expected_duration(w_est);\n                    // Use a priority score balancing critical path height, descendants, and member efficiency\n                    double score = (tasks[i].height * 100.0 + (double)tasks[i].descendants) / dur;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m_idx = j;\n                        best_t_idx = i;\n                        best_m_in_idle = mi;\n                        best_t_in_ready = ti;\n                    }\n                }\n            }\n            \n            if (best_m_idx != -1) {\n                assignments.push_back({best_m_idx, best_t_idx});\n                tasks[best_t_idx].status = 1;\n                members[best_m_idx].current_task = best_t_idx;\n                members[best_m_idx].start_day = current_day;\n                idle_members.erase(idle_members.begin() + best_m_in_idle);\n                ready_tasks.erase(ready_tasks.begin() + best_t_in_ready);\n            } else break;\n        }\n        \n        cout << (int)assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        cout << endl;\n        \n        int n_completed;\n        if (!(cin >> n_completed) || n_completed == -1) break;\n        for (int i = 0; i < n_completed; ++i) {\n            int m_id; cin >> m_id; --m_id;\n            int t_idx = members[m_id].current_task;\n            int duration = current_day - members[m_id].start_day + 1;\n            members[m_id].history.push_back({tasks[t_idx].d, duration});\n            tasks[t_idx].status = 2;\n            members[m_id].current_task = -1;\n            update_skills(m_id);\n        }\n    }\n    \n    return 0;\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// Order information and state arrays\nint orders_a[1000], orders_b[1000], orders_c[1000], orders_d[1000];\nint order_in_s[50];\nbool in_s[1000];\nint route[102];\nint pos[101]; // position of point index 0-99 in route\nint cur_x[101], cur_y[101]; // coords of point 0-99, and point 100 is the office (400, 400)\n\n// Calculate Manhattan distance between two points by their index in cur_x/cur_y\ninline int dist_points(int p1, int p2) {\n    return abs(cur_x[p1] - cur_x[p2]) + abs(cur_y[p1] - cur_y[p2]);\n}\n\n// Calculate Manhattan distance between a route index and specific coordinates\ninline int dist_to_coord(int r_idx, int x, int y) {\n    return abs(cur_x[route[r_idx]] - x) + abs(cur_y[route[r_idx]] - y);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read 1000 orders\n    for (int i = 0; i < 1000; i++) {\n        if (!(cin >> orders_a[i] >> orders_b[i] >> orders_c[i] >> orders_d[i])) break;\n    }\n\n    // Heuristic: Pick a pool of candidates closest to the office center (400, 400)\n    vector<pair<int, int>> pool_candidates;\n    for (int i = 0; i < 1000; i++) {\n        int d = abs(orders_a[i] - 400) + abs(orders_b[i] - 400) + abs(orders_c[i] - 400) + abs(orders_d[i] - 400);\n        pool_candidates.push_back({d, i});\n    }\n    sort(pool_candidates.begin(), pool_candidates.end());\n\n    // Use a subset of size 400 for selection\n    int pool_size = 400;\n    vector<int> pool;\n    for (int i = 0; i < pool_size; i++) {\n        pool.push_back(pool_candidates[i].second);\n    }\n\n    // Initialize chosen orders S with the first 50 closest orders\n    for (int i = 0; i < 50; i++) {\n        int order_idx = pool[i];\n        order_in_s[i] = order_idx;\n        in_s[order_idx] = true;\n        cur_x[i] = orders_a[order_idx];      // Pickup coordinate x\n        cur_y[i] = orders_b[order_idx];      // Pickup coordinate y\n        cur_x[i + 50] = orders_c[order_idx]; // Delivery coordinate x\n        cur_y[i + 50] = orders_d[order_idx]; // Delivery coordinate y\n    }\n    cur_x[100] = 400; cur_y[100] = 400; // Office coordinate\n\n    // Build an initial route using a Greedy Pickup-Delivery heuristic\n    int current_x = 400, current_y = 400;\n    vector<bool> visited_p(100, false);\n    route[0] = 100; route[101] = 100;\n    for (int step = 1; step <= 100; step++) {\n        int best_dist = 1e9, best_p = -1;\n        for (int p = 0; p < 100; p++) {\n            if (visited_p[p]) continue;\n            if (p >= 50 && !visited_p[p - 50]) continue; // Cannot deliver before pickup\n            int d = abs(current_x - cur_x[p]) + abs(current_y - cur_y[p]);\n            if (d < best_dist) { best_dist = d; best_p = p; }\n        }\n        route[step] = best_p;\n        pos[best_p] = step;\n        visited_p[best_p] = true;\n        current_x = cur_x[best_p]; current_y = cur_y[best_p];\n    }\n\n    // Initial total travel time\n    int current_t = 0;\n    for (int i = 0; i <= 100; i++) {\n        current_t += dist_points(route[i], route[i+1]);\n    }\n\n    // Simulated Annealing setup\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double t_start = 30.0, t_end = 0.1;\n    long long total_iter = 0;\n\n    while (true) {\n        // Limit total execution time to 1.96 seconds\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.96) break;\n\n        double progress = elapsed / 1.96;\n        double temp = t_start * pow(t_end / t_start, progress);\n\n        // Perform chunks of iterations\n        for (int j = 0; j < 2000; j++) {\n            int move_type = rng() % 100;\n\n            if (move_type < 45) { // Relocate point Move\n                int i = 1 + rng() % 100;\n                int k_pos = 1 + rng() % 100;\n                if (i == k_pos) continue;\n\n                int vi = route[i];\n                // Precedence Constraint Check\n                if (vi < 50) { if (i < k_pos && k_pos >= pos[vi + 50]) continue; }\n                else { if (i > k_pos && k_pos <= pos[vi - 50]) continue; }\n\n                // Distance Delta Calculation\n                int d_before, d_after;\n                if (i < k_pos) {\n                    d_before = dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]) + dist_points(route[k_pos], route[k_pos+1]);\n                    d_after = dist_points(route[i-1], route[i+1]) + dist_points(route[k_pos], route[i]) + dist_points(route[i], route[k_pos+1]);\n                } else {\n                    d_before = dist_points(route[k_pos-1], route[k_pos]) + dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]);\n                    d_after = dist_points(route[k_pos-1], route[i]) + dist_points(route[i], route[k_pos]) + dist_points(route[i-1], route[i+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    int v = route[i];\n                    if (i < k_pos) {\n                        for (int k = i; k < k_pos; k++) { route[k] = route[k+1]; pos[route[k]] = k; }\n                    } else {\n                        for (int k = i; k > k_pos; k--) { route[k] = route[k-1]; pos[route[k]] = k; }\n                    }\n                    route[k_pos] = v; pos[v] = k_pos;\n                }\n            } else if (move_type < 90) { // Swap two points Move\n                int i = 1 + rng() % 100;\n                int j = 1 + rng() % 100;\n                if (i == j) continue;\n                int vi = route[i], vj = route[j];\n\n                // Precedence Constraint Check\n                if (vi < 50) { if (j >= pos[vi + 50]) continue; }\n                else { if (j <= pos[vi - 50]) continue; }\n                if (vj < 50) { if (i >= pos[vj + 50]) continue; }\n                else { if (i <= pos[vj - 50]) continue; }\n\n                int d_before, d_after;\n                int i_low = min(i, j), i_high = max(i, j);\n                if (i_high == i_low + 1) {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                } else {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_low+1]) +\n                               dist_points(route[i_high-1], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low+1]) +\n                              dist_points(route[i_high-1], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    swap(route[i], route[j]);\n                    pos[route[i]] = i; pos[route[j]] = j;\n                }\n            } else { // Replace one order in S Move\n                int k = rng() % 50;\n                int old_idx = order_in_s[k];\n                int new_idx = pool[rng() % pool_size];\n                if (in_s[new_idx]) continue;\n\n                int pk_pos = pos[k], dk_pos = pos[k+50];\n                int nax = orders_a[new_idx], nay = orders_b[new_idx], ncx = orders_c[new_idx], ncy = orders_d[new_idx];\n\n                int d_before = dist_points(route[pk_pos-1], k) + dist_points(k, route[pk_pos+1]) +\n                               dist_points(route[dk_pos-1], k+50) + dist_points(k+50, route[dk_pos+1]);\n                if (pk_pos + 1 == dk_pos) {\n                    d_before = dist_points(route[pk_pos-1], k) + dist_points(k, k+50) + dist_points(k+50, route[dk_pos+1]);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_before = dist_points(route[dk_pos-1], k+50) + dist_points(k+50, k) + dist_points(k, route[pk_pos+1]);\n                }\n\n                int d_after = dist_to_coord(pk_pos-1, nax, nay) + dist_to_coord(pk_pos+1, nax, nay) +\n                              dist_to_coord(dk_pos-1, ncx, ncy) + dist_to_coord(dk_pos+1, ncx, ncy);\n                if (pk_pos + 1 == dk_pos) {\n                    d_after = dist_to_coord(pk_pos-1, nax, nay) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(dk_pos+1, ncx, ncy);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_after = dist_to_coord(dk_pos-1, ncx, ncy) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(pk_pos+1, nax, nay);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    in_s[old_idx] = false; in_s[new_idx] = true;\n                    order_in_s[k] = new_idx;\n                    cur_x[k] = nax; cur_y[k] = nay;\n                    cur_x[k+50] = ncx; cur_y[k+50] = ncy;\n                }\n            }\n        }\n        total_iter++;\n    }\n\n    // Final Output: Number of orders and their 1-indexed IDs\n    cout << 50;\n    for (int i = 0; i < 50; i++) cout << \" \" << order_in_s[i] + 1;\n    cout << \"\\n\";\n\n    // Final Output: Route coordinates (start office, pickups/deliveries, end office)\n    cout << 102;\n    for (int i = 0; i <= 101; i++) {\n        int x, y;\n        if (i == 0 || i == 101) { x = 400; y = 400; }\n        else {\n            int p = route[i];\n            if (p < 50) { x = orders_a[order_in_s[p]]; y = orders_b[order_in_s[p]]; }\n            else { x = orders_c[order_in_s[p - 50]]; y = orders_d[order_in_s[p - 50]]; }\n        }\n        cout << \" \" << x << \" \" << y;\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We have an online minimum spanning tree (MST) problem where edge weights are revealed one by one.\n * The goal is to minimize the total weight of the selected edges while ensuring connectivity.\n * Since we must decide whether to pick an edge before seeing the weights of future edges,\n * this is a classic scenario for a Monte Carlo (MC) heuristic.\n *\n * Algorithm Strategy:\n * 1. Maintain a current set of adopted edges using a Disjoint Set Union (DSU) to track connectivity.\n * 2. For each edge (u_i, v_i) with revealed weight l_i:\n *    a. If u_i and v_i are already connected, reject the edge (it's redundant).\n *    b. Mandatory Check: Check if edge i is absolutely necessary to keep the graph connected.\n *       If the vertices cannot be connected using any of the remaining edges, we MUST pick it.\n *    c. Monte Carlo Simulation: Perform multiple simulations where future edge weights are\n *       sampled from their known distributions [d_j, 3*d_j]. For each scenario, check if\n *       edge i would be part of the MST.\n *    d. If the edge is \"mandatory\" or appears in the MST in more than 50% of the simulated\n *       scenarios, we adopt it.\n */\n\n// Fast DSU implementation for maintaining the base connectivity.\nstruct FastDSU {\n    int parent[400];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    int find(int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]]; // Path halving for performance\n            i = parent[i];\n        }\n        return i;\n    }\n    void unite(int i, int j) {\n        int r1 = find(i);\n        int r2 = find(j);\n        if (r1 != r2) parent[r1] = r2;\n    }\n};\n\n// Simplified DSU structure for simulations, optimized for speed.\nstruct SimDSU {\n    int parent[400];\n    inline int find(int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]];\n            i = parent[i];\n        }\n        return i;\n    }\n    inline void unite(int i, int j) {\n        int r1 = find(i);\n        int r2 = find(j);\n        if (r1 != r2) parent[r1] = r2;\n    }\n};\n\nint main() {\n    // Fast I/O for competitive programming.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> x[i] >> y[i])) break;\n    }\n\n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; ++i) {\n        if (!(cin >> u[i] >> v[i])) break;\n        double dx = (double)x[u[i]] - x[v[i]];\n        double dy = (double)y[u[i]] - y[v[i]];\n        // Distance is the rounded Euclidean distance between endpoints.\n        d[i] = (int)round(sqrt(dx * dx + dy * dy));\n    }\n\n    FastDSU dsu_base;\n    dsu_base.init(N);\n\n    // Seeded random engine for consistent Monte Carlo simulations.\n    mt19937 rng(1337);\n    // Number of scenarios. Higher values improve accuracy but take more time.\n    // 60 simulations is a good balance for the 2.0s time limit.\n    const int K = 60; \n    \n    // Pre-sample weights for all simulations to maintain consistency and optimize speed.\n    vector<vector<int>> sampled_l(K, vector<int>(M));\n    for (int k = 0; k < K; ++k) {\n        for (int j = 0; j < M; ++j) {\n            // Weights are uniformly distributed between d_j and 3*d_j.\n            sampled_l[k][j] = d[j] + (int)(rng() % (2 * d[j] + 1));\n        }\n    }\n\n    SimDSU sim;\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n\n        int r_u = dsu_base.find(u[i]);\n        int r_v = dsu_base.find(v[i]);\n\n        // If the nodes are already connected by previously adopted lines, discard this line.\n        if (r_u == r_v) {\n            cout << 0 << endl;\n            continue;\n        }\n\n        // Filtering: Only consider remaining edges that actually connect different components.\n        // This drastically speeds up the simulation logic as the graph gets more connected.\n        vector<int> root_u_list, root_v_list, rel_idx;\n        root_u_list.reserve(M - i);\n        root_v_list.reserve(M - i);\n        rel_idx.reserve(M - i);\n\n        for (int j = i + 1; j < M; ++j) {\n            int ru_j = dsu_base.find(u[j]);\n            int rv_j = dsu_base.find(v[j]);\n            if (ru_j != rv_j) {\n                root_u_list.push_back(ru_j);\n                root_v_list.push_back(rv_j);\n                rel_idx.push_back(j);\n            }\n        }\n\n        bool pick = false;\n        \n        // 1. Mandatory Check:\n        // Use a temporary simulation DSU to see if (r_u, r_v) can be connected \n        // by ANY of the future candidate lines.\n        for (int n = 0; n < N; ++n) sim.parent[n] = n;\n        for (size_t j = 0; j < root_u_list.size(); ++j) {\n            sim.unite(root_u_list[j], root_v_list[j]);\n        }\n        \n        if (sim.find(r_u) != sim.find(r_v)) {\n            // No other future edge can connect these components; adoption is mandatory.\n            pick = true;\n        } else {\n            // 2. Monte Carlo Logic:\n            // For K scenarios, calculate if edge i belongs to the MST.\n            // Edge i is in the MST if no path exists between its endpoints \n            // using only edges with lower weights than l_i.\n            int count = 0;\n            for (int k = 0; k < K; ++k) {\n                for (int n = 0; n < N; ++n) sim.parent[n] = n;\n                for (size_t j = 0; j < root_u_list.size(); ++j) {\n                    if (sampled_l[k][rel_idx[j]] < l_i) {\n                        int r1 = sim.find(root_u_list[j]);\n                        int r2 = sim.find(root_v_list[j]);\n                        if (r1 != r2) {\n                            sim.parent[r1] = r2;\n                            // Optimization: Stop once endpoints are connected.\n                            if (sim.find(r_u) == sim.find(r_v)) break;\n                        }\n                    }\n                }\n                if (sim.find(r_u) != sim.find(r_v)) count++;\n            }\n            // Adopt the edge if it is statistically likely to be optimal.\n            if (count > K / 2) pick = true;\n        }\n\n        if (pick) {\n            dsu_base.unite(r_u, r_v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int TURNS = 300;\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y; };\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool is_blocked[GRID_SIZE + 1][GRID_SIZE + 1];\n\n// Check if any pet is at or adjacent to (x, y) at the beginning of the turn\nbool is_pet_near(int x, int y) {\n    for (int i = 0; i < N; i++) {\n        if (abs(pets[i].x - x) + abs(pets[i].y - y) <= 1) return true;\n    }\n    return false;\n}\n\n// Check if any human is currently at (x, y)\nbool is_human_at_start(int x, int y) {\n    for (const auto& h : humans) if (h.x == x && h.y == y) return true;\n    return false;\n}\n\n// BFS to find the first move in the shortest path while avoiding blocked squares and other humans\nstring bfs_move(int sx, int sy, int tx, int ty, const vector<Human>& current_humans, const vector<Human>& next_humans, int human_idx, const vector<pair<int, int>>& planned_blocks) {\n    if (sx == tx && sy == ty) return \".\";\n    \n    struct Node { int x, y; string path; };\n    queue<Node> q;\n    q.push({sx, sy, \"\"});\n    vector<vector<int>> dist(GRID_SIZE + 1, vector<int>(GRID_SIZE + 1, -1));\n    dist[sx][sy] = 0;\n    \n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    char mc[] = {'U', 'D', 'L', 'R'};\n\n    while (!q.empty()) {\n        Node curr = q.front(); q.pop();\n        if (curr.x == tx && curr.y == ty) return curr.path.substr(0, 1);\n\n        for (int i = 0; i < 4; i++) {\n            int nx = curr.x + dx[i], ny = curr.y + dy[i];\n            if (nx < 1 || nx > GRID_SIZE || ny < 1 || ny > GRID_SIZE || is_blocked[nx][ny]) continue;\n            \n            bool forbidden = false;\n            // Avoid squares currently being blocked by other humans in the same turn\n            for (auto& pb : planned_blocks) if (nx == pb.first && ny == pb.second) forbidden = true;\n            // Avoid other humans' positions (next positions for already moved humans, current positions for others)\n            for (int j = 0; j < human_idx; j++) if (nx == next_humans[j].x && ny == next_humans[j].y) forbidden = true;\n            for (int j = human_idx + 1; j < M; j++) if (nx == current_humans[j].x && ny == current_humans[j].y) forbidden = true;\n\n            if (!forbidden && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.x][curr.y] + 1;\n                q.push({nx, ny, curr.path + mc[i]});\n            }\n        }\n    }\n    return \".\";\n}\n\nint main() {\n    ios::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].x >> pets[i].y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) cin >> humans[i].x >> humans[i].y;\n\n    // Define vertical walls at column multiples of 3\n    vector<int> wall_cols = {3, 6, 9, 12, 15, 18, 21, 24, 27};\n\n    for (int t = 0; t < TURNS; t++) {\n        string turn_actions(M, '.');\n        vector<Human> next_humans = humans;\n        vector<pair<int, int>> planned_blocks;\n\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            int best_tx = -1, best_ty = -1, min_dist = 1000;\n\n            // Strategy: Build vertical columns and then close them if no pets are inside\n            for (int y : wall_cols) {\n                // Prioritize building column segments (except the gate at row 15)\n                for (int x = 1; x <= 30; x++) {\n                    if (x == 15) continue;\n                    if (is_blocked[x][y]) continue;\n                    int d = abs(hx - x) + abs(hy - y);\n                    if (d < min_dist) { min_dist = d; best_tx = x; best_ty = y; }\n                }\n                // Check if the wall is complete and the gate can be closed\n                bool wall_done = true;\n                for (int x = 1; x <= 30; x++) if (x != 15 && !is_blocked[x][y]) wall_done = false;\n                if (wall_done && !is_blocked[15][y]) {\n                    bool pet_in_section = false;\n                    for (int p = 0; p < N; p++) {\n                        // Section to the left of the wall\n                        if (pets[p].y == y - 1 || pets[p].y == y - 2) pet_in_section = true;\n                    }\n                    if (!pet_in_section) {\n                        int d = abs(hx - 15) + abs(hy - y);\n                        if (d < min_dist) { min_dist = d; best_tx = 15; best_ty = y; }\n                    }\n                }\n            }\n\n            if (best_tx != -1) {\n                if (min_dist == 1) {\n                    // Try to perform a blocking action\n                    if (!is_pet_near(best_tx, best_ty) && !is_human_at_start(best_tx, best_ty)) {\n                        bool human_will_be_there = false;\n                        for (int j = 0; j < i; j++) if (next_humans[j].x == best_tx && next_humans[j].y == best_ty) human_will_be_there = true;\n                        for (int j = i + 1; j < M; j++) if (humans[j].x == best_tx && humans[j].y == best_ty) human_will_be_there = true;\n                        \n                        if (!human_will_be_there) {\n                            planned_blocks.push_back({best_tx, best_ty});\n                            if (best_tx < hx) turn_actions[i] = 'u';\n                            else if (best_tx > hx) turn_actions[i] = 'd';\n                            else if (best_ty < hy) turn_actions[i] = 'l';\n                            else turn_actions[i] = 'r';\n                            continue;\n                        }\n                    }\n                }\n                // Try to move to a square adjacent to the target\n                int adj_x = -1, adj_y = -1, adj_min_d = 1000;\n                int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n                for (int k = 0; k < 4; k++) {\n                    int nx = best_tx + dx[k], ny = best_ty + dy[k];\n                    if (nx >= 1 && nx <= GRID_SIZE && ny >= 1 && ny <= GRID_SIZE && !is_blocked[nx][ny]) {\n                        bool blocked_by_other = false;\n                        for (auto& pb : planned_blocks) if (nx == pb.first && ny == pb.second) blocked_by_other = true;\n                        if (!blocked_by_other) {\n                            int d = abs(hx - nx) + abs(hy - ny);\n                            if (d < adj_min_d) { adj_min_d = d; adj_x = nx; adj_y = ny; }\n                        }\n                    }\n                }\n                if (adj_x != -1) {\n                    string mv = bfs_move(hx, hy, adj_x, adj_y, humans, next_humans, i, planned_blocks);\n                    if (mv != \".\") {\n                        turn_actions[i] = mv[0];\n                        if (mv[0] == 'U') next_humans[i].x--;\n                        else if (mv[0] == 'D') next_humans[i].x++;\n                        else if (mv[0] == 'L') next_humans[i].y--;\n                        else if (mv[0] == 'R') next_humans[i].y++;\n                    }\n                }\n            }\n        }\n\n        // Execute actions\n        cout << turn_actions << endl;\n        for (int i = 0; i < M; i++) {\n            if (turn_actions[i] >= 'a' && turn_actions[i] <= 'z') {\n                int tx = humans[i].x, ty = humans[i].y;\n                if (turn_actions[i] == 'u') tx--; else if (turn_actions[i] == 'd') tx++;\n                else if (turn_actions[i] == 'l') ty--; else if (turn_actions[i] == 'r') ty++;\n                is_blocked[tx][ty] = true;\n            } else {\n                humans[i] = next_humans[i];\n            }\n        }\n\n        // Update pet positions based on feedback\n        for (int i = 0; i < N; i++) {\n            string pm; if (!(cin >> pm)) break;\n            for (char c : pm) {\n                if (c == 'U') pets[i].x--; else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--; else if (c == 'R') pets[i].y++;\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 <numeric>\n\nusing namespace std;\n\n// Directional moves: Up (0), Down (1), Left (2), Right (3)\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nint si, sj, ti, tj;\ndouble p_prob_val;\nstring h_wall[20], v_wall[19];\nint dist_to_target[400];\nint move_to[400][4];\ndouble P_mat[401][201];\ndouble W_mat[401][201];\ndouble G_prime_mat[401][201];\ndouble H_precomputed[401][201];\n\n// Check if a move from (i, j) in a given direction is possible (no walls)\nbool can_move_func(int i, int j, int dir) {\n    if (dir == 0) { // Up\n        if (i > 0 && v_wall[i - 1][j] == '0') return true;\n    } else if (dir == 1) { // Down\n        if (i < 19 && v_wall[i][j] == '0') return true;\n    } else if (dir == 2) { // Left\n        if (j > 0 && h_wall[i][j - 1] == '0') return true;\n    } else if (dir == 3) { // Right\n        if (j < 19 && h_wall[i][j] == '0') return true;\n    }\n    return false;\n}\n\n// Compute shortest distance from every square to the target (ti, tj) using BFS\nvoid bfs_target_dist() {\n    for (int i = 0; i < 400; ++i) dist_to_target[i] = 999;\n    int target_idx = ti * 20 + tj;\n    dist_to_target[target_idx] = 0;\n    queue<int> q;\n    q.push(target_idx);\n    while (!q.empty()) {\n        int idx = q.front();\n        q.pop();\n        int r = idx / 20, c = idx % 20;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = r - di[dir], nj = c - dj[dir]; // Inverse the direction to find neighbors\n            if (ni >= 0 && ni < 20 && nj >= 0 && nj < 20) {\n                // If we can move from (ni, nj) in direction 'dir' to reach (r, c)\n                if (can_move_func(ni, nj, dir)) {\n                    int n_idx = ni * 20 + nj;\n                    if (dist_to_target[n_idx] == 999) {\n                        dist_to_target[n_idx] = dist_to_target[idx] + 1;\n                        q.push(n_idx);\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Precompute probabilities for the heuristic evaluation\nvoid precompute_scoring() {\n    double l1p = log(1.0 - p_prob_val);\n    double lp = log(p_prob_val);\n    for (int d = 1; d <= 400; ++d) {\n        for (int t = 1; t <= 200; ++t) {\n            if (t < d) {\n                P_mat[d][t] = 0;\n            } else {\n                // Prob(d-th success occurs at turn t) = C(t-1, d-1) * (1-p)^d * p^(t-d)\n                double log_comb = lgamma(t) - lgamma(d) - lgamma(t - d + 1);\n                P_mat[d][t] = exp(log_comb + (double)d * l1p + (double)(t - d) * lp);\n            }\n        }\n        W_mat[d][0] = 0;\n        G_prime_mat[d][0] = 0;\n        for (int rem = 1; rem <= 200; ++rem) {\n            W_mat[d][rem] = W_mat[d][rem - 1] + P_mat[d][rem];\n            G_prime_mat[d][rem] = G_prime_mat[d][rem - 1] + (double)rem * P_mat[d][rem];\n        }\n        for (int k = 0; k <= 200; ++k) {\n            int rem_len = 200 - k;\n            // H_precomputed[d][k] = sum_{t=d}^{200-k} (401 - (k+t)) * P(d, t)\n            H_precomputed[d][k] = (401.0 - (double)k) * W_mat[d][rem_len] - G_prime_mat[d][rem_len];\n        }\n    }\n    for (int k = 0; k <= 200; ++k) H_precomputed[0][k] = 0;\n}\n\nstruct State {\n    string s;\n    double P[400];\n    double current_E_S;\n    double score;\n\n    State() {\n        for (int i = 0; i < 400; i++) P[i] = 0;\n        current_E_S = 0;\n        score = 0;\n        s = \"\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p_prob_val)) return 0;\n    for (int i = 0; i < 20; i++) cin >> h_wall[i];\n    for (int i = 0; i < 19; i++) cin >> v_wall[i];\n\n    bfs_target_dist();\n    precompute_scoring();\n\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            int idx = i * 20 + j;\n            for (int dir = 0; dir < 4; ++dir) {\n                if (can_move_func(i, j, dir)) {\n                    move_to[idx][dir] = (i + di[dir]) * 20 + (j + dj[dir]);\n                } else {\n                    move_to[idx][dir] = -1;\n                }\n            }\n        }\n    }\n\n    int target_idx = ti * 20 + tj;\n    const int B = 800; // Beam width\n    vector<State> current_beam;\n    State initial_state;\n    initial_state.P[si * 20 + sj] = 1.0;\n    initial_state.score = H_precomputed[dist_to_target[si * 20 + sj]][0];\n    current_beam.push_back(move(initial_state));\n\n    for (int k = 1; k <= 200; ++k) {\n        vector<State> next_beam_pool;\n        next_beam_pool.reserve(current_beam.size() * 4);\n\n        for (const auto& state : current_beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                State next_s;\n                next_s.s = state.s + dc[dir];\n                double p_reached = 0;\n\n                for (int idx = 0; idx < 400; ++idx) {\n                    if (idx == target_idx) continue; // Office is a sink\n                    double p_val = state.P[idx];\n                    if (p_val < 1e-18) continue;\n\n                    int n_idx = move_to[idx][dir];\n                    if (n_idx != -1) {\n                        // Prob p: stays in current square due to forgetfulness\n                        next_s.P[idx] += p_val * p_prob_val;\n                        // Prob 1-p: moves successfully\n                        if (n_idx == target_idx) {\n                            p_reached += p_val * (1.0 - p_prob_val);\n                        } else {\n                            next_s.P[n_idx] += p_val * (1.0 - p_prob_val);\n                        }\n                    } else {\n                        // Wall or forget both lead to staying in the square\n                        next_s.P[idx] += p_val;\n                    }\n                }\n\n                // Update accumulated expected score and heuristic for future steps\n                next_s.current_E_S = state.current_E_S + (401.0 - (double)k) * p_reached;\n                double h_future = 0;\n                for (int idx = 0; idx < 400; ++idx) {\n                    if (next_s.P[idx] > 1e-18) {\n                        int d = dist_to_target[idx];\n                        if (d <= 400) h_future += next_s.P[idx] * H_precomputed[d][k];\n                    }\n                }\n                next_s.score = next_s.current_E_S + h_future;\n                next_beam_pool.push_back(move(next_s));\n            }\n        }\n\n        // Sorting and pruning for Beam Search\n        if (next_beam_pool.size() > B) {\n            vector<int> indices(next_beam_pool.size());\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return next_beam_pool[a].score > next_beam_pool[b].score;\n            });\n            vector<State> pruned;\n            pruned.reserve(B);\n            for (int i = 0; i < B; i++) {\n                pruned.push_back(move(next_beam_pool[indices[i]]));\n            }\n            current_beam = move(pruned);\n        } else {\n            sort(next_beam_pool.begin(), next_beam_pool.end(), [](const State& a, const State& b) {\n                return a.score > b.score;\n            });\n            current_beam = move(next_beam_pool);\n        }\n    }\n\n    // Output the resulting string of movements\n    cout << current_beam[0].s << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 30;\nconst double TIME_LIMIT = 1950.0; // In milliseconds\n\n// Grid data\nint initial_grid[N][N];\nint current_tiles[N][N];\nint rot[N][N];\nint visited[N][N][4];\nint timer = 0;\n\n// Tile port connection table based on the problem hint\n// Directions: 0: Left, 1: Up, 2: Right, 3: Down\nint to_tbl[8][4] = {\n    {1, 0, -1, -1}, // Tile 0: Left <-> Top\n    {3, -1, -1, 0}, // Tile 1: Left <-> Bottom\n    {-1, -1, 3, 2}, // Tile 2: Right <-> Bottom\n    {-1, 2, 1, -1}, // Tile 3: Right <-> Top\n    {1, 0, 3, 2},   // Tile 4: Left <-> Top, Right <-> Bottom\n    {3, 2, 1, 0},   // Tile 5: Left <-> Bottom, Top <-> Right\n    {2, -1, 0, -1}, // Tile 6: Left <-> Right\n    {-1, 3, -1, 1}  // Tile 7: Top <-> Bottom\n};\n\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Rotation mapping for tile types based on 90\u00b0 CCW increments\ninline int get_tile_type(int initial_type, int rotation) {\n    if (initial_type <= 3) return (initial_type + rotation) % 4;\n    if (initial_type <= 5) return 4 + (initial_type - 4 + rotation) % 2;\n    if (initial_type <= 7) return 6 + (initial_type - 6 + rotation) % 2;\n    return initial_type;\n}\n\n// Evaluate function to find loop lengths and calculate a score for SA\nlong long evaluate(int& max1, int& max2) {\n    timer++;\n    max1 = 0; max2 = 0;\n    int num_loops = 0;\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) continue;\n                if (to_tbl[current_tiles[i][j]][d] == -1) continue;\n\n                int length = 0;\n                int ci = i, cj = j, cd = d;\n                bool loop = false;\n                while (true) {\n                    visited[ci][cj][cd] = timer;\n                    int d_out = to_tbl[current_tiles[ci][cj]][cd];\n                    if (d_out == -1) break;\n                    visited[ci][cj][d_out] = timer;\n\n                    int ni = ci + di[d_out];\n                    int nj = cj + dj[d_out];\n                    int nd = d_out ^ 2; // XOR with 2 switches between 0<->2 and 1<->3 (opposite directions)\n                    length++;\n\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    if (ni == i && nj == j && nd == d) {\n                        loop = true;\n                        break;\n                    }\n                    if (visited[ni][nj][nd] == timer) break;\n                    ci = ni; cj = nj; cd = nd;\n                }\n                if (loop) {\n                    num_loops++;\n                    if (length > max1) {\n                        max2 = max1;\n                        max1 = length;\n                    } else if (length > max2) {\n                        max2 = length;\n                    }\n                }\n            }\n        }\n    }\n    // Strategic scoring: prioritize having at least 2 loops\n    if (num_loops >= 2) return 1000000LL + (long long)max1 * max2;\n    if (num_loops == 1) return (long long)max1;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Reading grid input\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            initial_grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // RNG for Simulated Annealing\n    mt19937 rng(42);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rot[i][j] = rng() % 4;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    int m1, m2;\n    long long current_score = evaluate(m1, m2);\n    long long best_score = current_score;\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] = rot[i][j];\n\n    // SA Parameters\n    double T_start = 1000.0;\n    double T_end = 1.0;\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        // Periodic time check\n        if ((iter & 127) == 0) {\n            auto current_time = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n\n        // Randomly pick a tile and a new rotation\n        int i = rng() % N;\n        int j = rng() % N;\n        int old_r = rot[i][j];\n        int new_r = rng() % 4;\n        if (old_r == new_r) continue;\n\n        rot[i][j] = new_r;\n        current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n\n        int nm1, nm2;\n        long long next_score = evaluate(nm1, nm2);\n\n        bool accept = false;\n        if (next_score >= current_score) {\n            accept = true;\n        } else {\n            auto current_time = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            double t = elapsed / TIME_LIMIT;\n            double T = T_start * pow(T_end / T_start, t);\n            if (exp((double)(next_score - current_score) / T) > (double)rng() / rng.max()) {\n                accept = true;\n            }\n        }\n\n        if (accept) {\n            current_score = next_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int r = 0; r < N; ++r) {\n                    for (int c = 0; c < N; ++c) {\n                        best_rot[r][c] = rot[r][c];\n                    }\n                }\n            }\n        } else {\n            // Revert changes\n            rot[i][j] = old_r;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n\n    // Output result\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}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint N, T_max;\nint initial_empty_r, initial_empty_c;\nint empty_tile_id;\nint id_to_type[100];\n\nint get_type(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    if (c >= 'a' && c <= 'f') return c - 'a' + 10;\n    return 0;\n}\n\nstruct DSU {\n    vector<int> parent;\n    vector<int> sz;\n    vector<int> edges;\n    DSU(int n) : parent(n), sz(n, 1), edges(n, 0) {\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    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            parent[root_i] = root_j;\n            sz[root_j] += sz[root_i];\n            edges[root_j] += edges[root_i] + 1;\n        } else {\n            edges[root_i]++;\n        }\n    }\n};\n\nint get_tree_score(const vector<int>& p) {\n    DSU dsu(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int u = r * N + c;\n            int type_u = id_to_type[p[u]];\n            if (type_u == 0) continue;\n            if (c + 1 < N) {\n                int v = u + 1;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 4) && (type_v & 1)) dsu.unite(u, v);\n            }\n            if (r + 1 < N) {\n                int v = u + N;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 8) && (type_v & 2)) dsu.unite(u, v);\n            }\n        }\n    }\n    int max_s = 0;\n    for (int i = 0; i < N * N; ++i) {\n        if (dsu.parent[i] == i && id_to_type[p[i]] != 0) {\n            if (dsu.edges[i] == dsu.sz[i] - 1) max_s = max(max_s, dsu.sz[i]);\n        }\n    }\n    return max_s;\n}\n\nint get_manhattan(const vector<int>& p) {\n    int dist = 0;\n    for (int i = 0; i < N * N; ++i) {\n        int id = p[i];\n        int r0 = id / N, c0 = id % N;\n        int r1 = i / N, c1 = i % N;\n        dist += abs(r0 - r1) + abs(c0 - c1);\n    }\n    return dist;\n}\n\nbool is_reachable(const vector<int>& p) {\n    int inv = 0;\n    int er = -1, ec = -1;\n    for (int i = 0; i < N * N; ++i) {\n        if (p[i] == empty_tile_id) { er = i / N; ec = i % N; }\n        for (int j = i + 1; j < N * N; ++j) {\n            if (p[i] > p[j]) inv++;\n        }\n    }\n    return (inv % 2) == (abs(er - initial_empty_r) + abs(ec - initial_empty_c)) % 2;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    if (!(cin >> N >> T_max)) return 0;\n    vector<int> current_p(N * N);\n    for (int i = 0; i < N; ++i) {\n        string row; cin >> row;\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            id_to_type[id] = get_type(row[j]);\n            if (id_to_type[id] == 0) { initial_empty_r = i; initial_empty_c = j; empty_tile_id = id; }\n            current_p[id] = id;\n        }\n    }\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    vector<int> target_p = current_p;\n    long long current_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n    vector<int> best_p = target_p; long long best_score = current_score;\n    double initial_temp = 5000.0, final_temp = 1.0;\n    for (int iter = 0; ; ++iter) {\n        if (iter % 256 == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > 2.0) break;\n            double temp = initial_temp + (final_temp - initial_temp) * (elapsed / 2.0);\n            int p1 = rng() % (N * N), p2 = rng() % (N * N);\n            if (p1 == p2) continue;\n            swap(target_p[p1], target_p[p2]);\n            long long next_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n            if (next_score > current_score || exp((double)(next_score - current_score) / temp) > (double)rng() / rng.max()) {\n                current_score = next_score;\n                if (current_score > best_score) { best_score = current_score; best_p = target_p; }\n            } else swap(target_p[p1], target_p[p2]);\n        } else {\n            int p1 = rng() % (N * N), p2 = rng() % (N * N);\n            if (p1 == p2) continue;\n            swap(target_p[p1], target_p[p2]);\n            long long next_score = (long long)get_tree_score(target_p) * 10000 - get_manhattan(target_p);\n            if (next_score > current_score) {\n                current_score = next_score;\n                if (current_score > best_score) { best_score = current_score; best_p = target_p; }\n            } else swap(target_p[p1], target_p[p2]);\n        }\n    }\n    target_p = best_p;\n    if (!is_reachable(target_p)) {\n        bool flipped = false;\n        for (int i = 0; i < N * N; ++i) {\n            for (int j = i + 1; j < N * N; ++j)\n                if (target_p[i] != empty_tile_id && target_p[j] != empty_tile_id && id_to_type[target_p[i]] == id_to_type[target_p[j]]) {\n                    swap(target_p[i], target_p[j]); flipped = true; break;\n                }\n            if (flipped) break;\n        }\n    }\n    string all_moves = \"\"; vector<bool> solved(N * N, false);\n    auto move_to_pos = [&](int target_id, int tr, int tc) {\n        int curr_idx = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == target_id) curr_idx = i;\n        if (curr_idx == tr * N + tc) return;\n        int er = -1, ec = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == empty_tile_id) { er = i / N; ec = i % N; }\n        queue<int> q; q.push(er * N * N * N + ec * N * N + (curr_idx / N) * N + (curr_idx % N));\n        vector<int> dist(N * N * N * N, -1); vector<int> parent(N * N * N * N, -1); vector<char> move_from(N * N * N * N);\n        dist[q.front()] = 0; int end_state = -1;\n        while (!q.empty()) {\n            int s = q.front(); q.pop();\n            int cer = s / (N * N * N), cec = (s / (N * N)) % N, ctr = (s / N) % N, ctc = s % N;\n            if (ctr == tr && ctc == tc) { end_state = s; break; }\n            int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; char dchar[] = {'U', 'D', 'L', 'R'};\n            for (int i = 0; i < 4; ++i) {\n                int ner = cer + dr[i], nec = cec + dc[i];\n                if (ner >= 0 && ner < N && nec >= 0 && nec < N && !solved[ner * N + nec]) {\n                    int ntr = ctr, ntc = ctc; if (ner == ctr && nec == ctc) { ntr = cer; ntc = cec; }\n                    int ns = ner * N * N * N + nec * N * N + ntr * N + ntc;\n                    if (dist[ns] == -1) { dist[ns] = dist[s] + 1; parent[ns] = s; move_from[ns] = dchar[i]; q.push(ns); }\n                }\n            }\n        }\n        if (end_state == -1) return;\n        string moves = \"\"; for (int s = end_state; s != -1 && parent[s] != -1; s = parent[s]) moves += move_from[s];\n        reverse(moves.begin(), moves.end()); all_moves += moves;\n        for (char m : moves) {\n            int cer = -1, cec = -1; for (int i = 0; i < N * N; ++i) if (current_p[i] == empty_tile_id) { cer = i / N; cec = i % N; }\n            int ner = cer, nec = cec; if (m == 'U') ner--; else if (m == 'D') ner++; else if (m == 'L') nec--; else if (m == 'R') nec++;\n            swap(current_p[cer * N + cec], current_p[ner * N + nec]);\n        }\n    };\n    for (int r = 0; r < N - 3; ++r) for (int c = 0; c < N; ++c) { move_to_pos(target_p[r * N + c], r, c); solved[r * N + c] = true; }\n    for (int c = 0; c < N - 3; ++c) for (int r = N - 3; r < N; ++r) { move_to_pos(target_p[r * N + c], r, c); solved[r * N + c] = true; }\n    vector<int> p33; for (int r = N - 3; r < N; ++r) for (int c = N - 3; c < N; ++c) p33.push_back(r * N + c);\n    vector<int> target_sub(9); for (int i = 0; i < 9; ++i) target_sub[i] = target_p[p33[i]];\n    vector<int> vals = target_sub; sort(vals.begin(), vals.end());\n    auto get_perm = [&](const vector<int>& p) {\n        vector<int> res(9); for (int i = 0; i < 9; ++i) res[i] = lower_bound(vals.begin(), vals.end(), p[i]) - vals.begin();\n        return res;\n    };\n    vector<int> fact(10, 1); for (int i = 1; i <= 9; ++i) fact[i] = fact[i - 1] * i;\n    auto perm_to_int = [&](const vector<int>& p) {\n        int res = 0; for (int i = 0; i < 9; ++i) {\n            int cnt = 0; for (int j = i + 1; j < 9; ++j) if (p[i] > p[j]) cnt++;\n            res += cnt * fact[8 - i];\n        } return res;\n    };\n    auto int_to_perm = [&](int s) {\n        vector<int> p(9); vector<int> digits(9); vector<bool> used(9, false);\n        for (int i = 0; i < 9; ++i) { digits[i] = s / fact[8 - i]; s %= fact[8 - i]; }\n        for (int i = 0; i < 9; ++i) {\n            int cnt = 0; for (int j = 0; j < 9; ++j) {\n                if (!used[j]) { if (cnt == digits[i]) { p[i] = j; used[j] = true; break; } cnt++; }\n            }\n        } return p;\n    };\n    int target_idx = perm_to_int(get_perm(target_sub));\n    vector<int> start_p(9); for (int i = 0; i < 9; ++i) start_p[i] = current_p[p33[i]];\n    int start_idx = perm_to_int(get_perm(start_p));\n    int er_rel = -1; vector<int> target_rel = get_perm(target_sub);\n    for (int i = 0; i < 9; ++i) if (target_sub[i] == empty_tile_id) er_rel = target_rel[i];\n    queue<int> q; q.push(start_idx); vector<int> dist33(362880, -1); vector<int> parent33(362880, -1); vector<char> move_from33(362880);\n    dist33[start_idx] = 0;\n    while (!q.empty()) {\n        int s = q.front(); q.pop(); if (s == target_idx) break;\n        vector<int> p = int_to_perm(s); int ep = -1; for (int i = 0; i < 9; ++i) if (p[i] == er_rel) ep = i;\n        int er = ep / 3, ec = ep % 3; int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1}; char dchar[] = {'U', 'D', 'L', 'R'};\n        for (int i = 0; i < 4; ++i) {\n            int ner = er + dr[i], nec = ec + dc[i];\n            if (ner >= 0 && ner < 3 && nec >= 0 && nec < 3) {\n                vector<int> np = p; swap(np[ep], np[ner * 3 + nec]); int ns = perm_to_int(np);\n                if (dist33[ns] == -1) { dist33[ns] = dist33[s] + 1; parent33[ns] = s; move_from33[ns] = dchar[i]; q.push(ns); }\n            }\n        }\n    }\n    string moves33 = \"\"; for (int s = target_idx; s != -1 && parent33[s] != -1; s = parent33[s]) moves33 += move_from33[s];\n    reverse(moves33.begin(), moves33.end()); all_moves += moves33;\n    cout << all_moves << endl;\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Strawberry structure to keep track of its coordinates and its grid cell\nstruct Strawberry {\n    int x, y;\n    int sx, sy;\n    int posInSlabX;\n    int posInSlabY;\n};\n\n// Global counts and pieces\nint count_grid[52][52];\nint b[5505];\nint a[11];\nint current_sum_min = 0;\n\n// Efficient update of b_d and the score sum(min(a_d, b_d))\nvoid update_b(int d, int delta) {\n    if (d >= 1 && d <= 10) current_sum_min -= min(a[d], b[d]);\n    b[d] += delta;\n    if (d >= 1 && d <= 10) current_sum_min += min(a[d], b[d]);\n}\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K_limit;\n    if (!(cin >> N >> K_limit)) return 0;\n\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Strawberry> strawberries(N);\n    vector<int> all_x, all_y;\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        all_x.push_back(strawberries[i].x);\n        all_y.push_back(strawberries[i].y);\n    }\n\n    // kx and ky are the number of vertical and horizontal cuts, kx+ky <= 100\n    int kx = 50, ky = 50;\n    vector<int> X(kx + 2), Y(ky + 2);\n    X[0] = -1000000; X[kx + 1] = 1000000;\n    Y[0] = -1000000; Y[ky + 1] = 1000000;\n\n    // Initialize cuts based on strawberry density\n    sort(all_x.begin(), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    for (int i = 1; i <= kx; ++i) X[i] = all_x[i * N / (kx + 1)];\n    for (int j = 1; j <= ky; ++j) Y[j] = all_y[j * N / (ky + 1)];\n\n    // Ensure all cuts are strictly increasing and within integer point boundaries\n    for (int i = 1; i <= kx; ++i) if (X[i] <= X[i - 1]) X[i] = X[i - 1] + 1;\n    for (int i = kx; i >= 1; --i) if (X[i] >= X[i + 1]) X[i] = X[i + 1] - 1;\n    for (int j = 1; j <= ky; ++j) if (Y[j] <= Y[j - 1]) Y[j] = Y[j - 1] + 1;\n    for (int j = ky; j >= 1; --j) if (Y[j] >= Y[j + 1]) Y[j] = Y[j + 1] - 1;\n\n    vector<vector<int>> SlabX(kx + 1), SlabY(ky + 1);\n    for (int d = 0; d <= N; ++d) b[d] = 0;\n\n    // Assign strawberries to slabs and grid cells\n    for (int i = 0; i < N; ++i) {\n        int sx = 0;\n        while (sx < kx && strawberries[i].x > X[sx + 1]) sx++;\n        int sy = 0;\n        while (sy < ky && strawberries[i].y > Y[sy + 1]) sy++;\n\n        strawberries[i].sx = sx;\n        strawberries[i].sy = sy;\n        strawberries[i].posInSlabX = SlabX[sx].size();\n        SlabX[sx].push_back(i);\n        strawberries[i].posInSlabY = SlabY[sy].size();\n        SlabY[sy].push_back(i);\n\n        update_b(count_grid[sx][sy], -1);\n        count_grid[sx][sy]++;\n        update_b(count_grid[sx][sy], 1);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    long long iterations = 0;\n\n    // Optimization through Hill Climbing\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n        }\n        iterations++;\n\n        bool is_x = rng() % 2 == 0;\n        if (is_x) {\n            int i = rng() % kx + 1;\n            int oldX = X[i];\n            int range = X[i + 1] - X[i - 1] - 1;\n            if (range <= 0) continue;\n\n            int newX;\n            int r = rng() % 100;\n            if (r < 50) newX = X[i] + (rng() % 21 - 10);\n            else if (r < 80) newX = strawberries[rng() % N].x;\n            else newX = X[i - 1] + 1 + rng() % range;\n            if (newX <= X[i - 1] || newX >= X[i + 1]) newX = X[i - 1] + 1 + (rng() % range);\n            if (newX == oldX) continue;\n\n            vector<int> moved_k;\n            if (newX > oldX) {\n                for (int k : SlabX[i]) if (strawberries[k].x <= newX) moved_k.push_back(k);\n            } else {\n                for (int k : SlabX[i - 1]) if (strawberries[k].x > newX) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sy = strawberries[k].sy;\n                if (newX > oldX) { // move from SlabX[i] to SlabX[i-1]\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                } else { // move from SlabX[i-1] to SlabX[i]\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                }\n            }\n\n            // Accept if score improved or stayed the same (plateau-walking)\n            if (current_sum_min >= prev_sum) {\n                X[i] = newX;\n                for (int k : moved_k) {\n                    int old_sx = strawberries[k].sx;\n                    int new_sx = (newX > oldX) ? i - 1 : i;\n                    // Slab update: O(1) remove/add\n                    int pos = strawberries[k].posInSlabX;\n                    int last_k = SlabX[old_sx].back();\n                    SlabX[old_sx][pos] = last_k;\n                    strawberries[last_k].posInSlabX = pos;\n                    SlabX[old_sx].pop_back();\n                    strawberries[k].sx = new_sx;\n                    strawberries[k].posInSlabX = SlabX[new_sx].size();\n                    SlabX[new_sx].push_back(k);\n                }\n            } else { // Undo changes if rejected\n                for (int k : moved_k) {\n                    int sy = strawberries[k].sy;\n                    if (newX > oldX) {\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                    } else {\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                    }\n                }\n            }\n        } else {\n            // Symmetrical horizontal move\n            int j = rng() % ky + 1;\n            int oldY = Y[j];\n            int range = Y[j + 1] - Y[j - 1] - 1;\n            if (range <= 0) continue;\n\n            int newY;\n            int r = rng() % 100;\n            if (r < 50) newY = Y[j] + (rng() % 21 - 10);\n            else if (r < 80) newY = strawberries[rng() % N].y;\n            else newY = Y[j - 1] + 1 + rng() % range;\n            if (newY <= Y[j - 1] || newY >= Y[j + 1]) newY = Y[j - 1] + 1 + (rng() % range);\n            if (newY == oldY) continue;\n\n            vector<int> moved_k;\n            if (newY > oldY) {\n                for (int k : SlabY[j]) if (strawberries[k].y <= newY) moved_k.push_back(k);\n            } else {\n                for (int k : SlabY[j - 1]) if (strawberries[k].y > newY) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sx = strawberries[k].sx;\n                if (newY > oldY) { // move from SlabY[j] to SlabY[j-1]\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                } else { // move from SlabY[j-1] to SlabY[j]\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                }\n            }\n\n            if (current_sum_min >= prev_sum) {\n                Y[j] = newY;\n                for (int k : moved_k) {\n                    int old_sy = strawberries[k].sy;\n                    int new_sy = (newY > oldY) ? j - 1 : j;\n                    int pos = strawberries[k].posInSlabY;\n                    int last_k = SlabY[old_sy].back();\n                    SlabY[old_sy][pos] = last_k;\n                    strawberries[last_k].posInSlabY = pos;\n                    SlabY[old_sy].pop_back();\n                    strawberries[k].sy = new_sy;\n                    strawberries[k].posInSlabY = SlabY[new_sy].size();\n                    SlabY[new_sy].push_back(k);\n                }\n            } else {\n                for (int k : moved_k) {\n                    int sx = strawberries[k].sx;\n                    if (newY > oldY) {\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                    } else {\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                    }\n                }\n            }\n        }\n    }\n\n    // Output formatting\n    cout << kx + ky << endl;\n    for (int i = 1; i <= kx; ++i) {\n        // Vertical lines x ~ X[i] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << X[i] << \" -1000000000 \" << X[i] + 1 << \" 1000000000\" << endl;\n    }\n    for (int j = 1; j <= ky; ++j) {\n        // Horizontal lines y ~ Y[j] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << \"-1000000000 \" << Y[j] << \" 1000000000 \" << Y[j] + 1 << endl;\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Point structure to represent grid points\nstruct Point {\n    int x, y;\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Rect structure to represent the chosen rectangle\nstruct Rect {\n    Point p1, p2, p3, p4;\n    int d1, d2;\n};\n\n// Op structure to store the operations for output\nstruct Op {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\n// Movement vectors for the 8 directions (axis-parallel and 45-degree)\nint dx[] = {1, 1, 0, -1, -1, -1, 0, 1};\nint dy[] = {0, 1, 1, 1, 0, -1, -1, -1};\n\n// Directions for orthogonal pairs used to form rectangles\npair<int, int> orthogonal_pairs[] = {\n    {0, 2}, {2, 4}, {4, 6}, {6, 0}, // Axis-parallel: Right-Up, Up-Left, Left-Down, Down-Right\n    {1, 3}, {3, 5}, {5, 7}, {7, 1}  // 45-degree: UR-UL, UL-DL, DL-DR, DR-UR\n};\n\nlong long weights[61][61];\n\n// Function to find the nearest dot in a given direction from a point\nPoint find_nearest_dot(int x, int y, int d, int N, const vector<vector<bool>>& has_dot) {\n    x += dx[d]; y += dy[d];\n    while (x >= 0 && x < N && y >= 0 && y < N) {\n        if (has_dot[x][y]) return {x, y};\n        x += dx[d]; y += dy[d];\n    }\n    return {-1, -1};\n}\n\n// Function to check if any part of a segment has been used by an existing rectangle\nbool is_segment_used(Point a, Point b, int d, const vector<vector<vector<bool>>>& used) {\n    int x = a.x, y = a.y;\n    while (x != b.x || y != b.y) {\n        if (used[x][y][d]) return true;\n        x += dx[d]; y += dy[d];\n    }\n    return false;\n}\n\n// Function to mark all unit segments of a rectangle's perimeter as used\nvoid mark_segment(Point a, Point b, int d, vector<vector<vector<bool>>>& used) {\n    int x = a.x, y = a.y;\n    while (x != b.x || y != b.y) {\n        used[x][y][d] = true;\n        int nx = x + dx[d], ny = y + dy[d];\n        used[nx][ny][(d + 4) % 8] = true;\n        x = nx; y = ny;\n    }\n}\n\n// Chebyshev distance measure for both axis-parallel and 45-degree alignments\nint dist(Point a, Point b) {\n    return max(abs(a.x - b.x), abs(a.y - b.y));\n}\n\n// Validation function to check if a rectangle formation is legal according to the rules\nbool is_valid(const Rect& r, int N, const vector<vector<bool>>& has_dot, const vector<vector<vector<bool>>>& used) {\n    if (has_dot[r.p1.x][r.p1.y]) return false;\n    if (!has_dot[r.p2.x][r.p2.y] || !has_dot[r.p3.x][r.p3.y] || !has_dot[r.p4.x][r.p4.y]) return false;\n    \n    // Nearest dot checks ensure condition 2: no other dots on the perimeter\n    if (find_nearest_dot(r.p1.x, r.p1.y, r.d1, N, has_dot) != r.p2) return false;\n    if (find_nearest_dot(r.p1.x, r.p1.y, r.d2, N, has_dot) != r.p4) return false;\n    if (find_nearest_dot(r.p2.x, r.p2.y, r.d2, N, has_dot) != r.p3) return false;\n    if (find_nearest_dot(r.p4.x, r.p4.y, r.d1, N, has_dot) != r.p3) return false;\n    \n    // Segment checks ensure condition 3: no shared segments with existing rectangles\n    if (is_segment_used(r.p1, r.p2, r.d1, used)) return false;\n    if (is_segment_used(r.p2, r.p3, r.d2, used)) return false;\n    if (is_segment_used(r.p3, r.p4, (r.d1 + 4) % 8, used)) return false;\n    if (is_segment_used(r.p4, r.p1, (r.d2 + 4) % 8, used)) return false;\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    \n    vector<vector<bool>> has_dot_init(N, vector<bool>(N, false));\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        has_dot_init[x][y] = true;\n    }\n\n    // Precalculate point weights based on their distance from the center (c, c)\n    double c = (N - 1) / 2.0;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y < N; ++y) {\n            weights[x][y] = (long long)((x - c) * (x - c) + (y - c) * (y - c) + 1);\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    long long best_weight_sum = -1;\n    vector<Op> best_ops;\n\n    vector<Point> all_points;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y < N; ++y) {\n            all_points.push_back({x, y});\n        }\n    }\n\n    // Heuristic approach: multi-start greedy search with varying strategies and randomization\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 4750) {\n        vector<vector<bool>> has_dot = has_dot_init;\n        vector<vector<vector<bool>>> used(N, vector<vector<bool>>(N, vector<bool>(8, false)));\n        vector<Op> current_ops;\n        long long current_weight_sum = 0;\n\n        for (int x = 0; x < N; ++x)\n            for (int y = 0; y < N; ++y)\n                if (has_dot[x][y]) current_weight_sum += weights[x][y];\n\n        // Randomize the heuristic parameter to explore different expansion patterns\n        double perimeter_weight = (rng() % 3501) / 1000.0;\n        vector<Point> p1_list = all_points;\n        int strategy = rng() % 10;\n        if (strategy < 3) {\n            // Center-out: prioritize adding dots near the middle to create \"bridges\"\n            sort(p1_list.begin(), p1_list.end(), [&](Point a, Point b) {\n                return weights[a.x][a.y] < weights[b.x][b.y];\n            });\n        } else if (strategy < 6) {\n            // Boundary-in: prioritize adding high-value dots first\n            sort(p1_list.begin(), p1_list.end(), [&](Point a, Point b) {\n                return weights[a.x][a.y] > weights[b.x][b.y];\n            });\n        } else {\n            // Random: ensure variety in dot addition order\n            shuffle(p1_list.begin(), p1_list.end(), rng);\n        }\n\n        while (true) {\n            bool added_any_in_pass = false;\n            for (auto& p1 : p1_list) {\n                if (has_dot[p1.x][p1.y]) continue;\n                \n                Rect best_r;\n                double max_s = -1.0;\n                // Evaluate all 8 possible rectangle orientations for the current empty point p1\n                for (int i = 0; i < 8; ++i) {\n                    int d1 = orthogonal_pairs[i].first, d2 = orthogonal_pairs[i].second;\n                    Point p2 = find_nearest_dot(p1.x, p1.y, d1, N, has_dot);\n                    Point p4 = find_nearest_dot(p1.x, p1.y, d2, N, has_dot);\n                    if (p2.x != -1 && p4.x != -1) {\n                        Point p3 = {p2.x + p4.x - p1.x, p2.y + p4.y - p1.y};\n                        if (p3.x >= 0 && p3.x < N && p3.y >= 0 && p3.y < N && has_dot[p3.x][p3.y]) {\n                            Rect r = {p1, p2, p3, p4, d1, d2};\n                            if (is_valid(r, N, has_dot, used)) {\n                                int p_len = 2 * (dist(p1, p2) + dist(p1, p4));\n                                // Score function balances high-value coordinates and the \"blocking\" effect of large perimeters\n                                double s = (double)weights[p1.x][p1.y] / pow(p_len, perimeter_weight);\n                                if (s > max_s) {\n                                    max_s = s;\n                                    best_r = r;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (max_s != -1.0) {\n                    // Update the state with the selected rectangle\n                    has_dot[best_r.p1.x][best_r.p1.y] = true;\n                    mark_segment(best_r.p1, best_r.p2, best_r.d1, used);\n                    mark_segment(best_r.p2, best_r.p3, best_r.d2, used);\n                    mark_segment(best_r.p3, best_r.p4, (best_r.d1 + 4) % 8, used);\n                    mark_segment(best_r.p4, best_r.p1, (best_r.d2 + 4) % 8, used);\n                    current_ops.push_back({best_r.p1.x, best_r.p1.y, best_r.p2.x, best_r.p2.y, best_r.p3.x, best_r.p3.y, best_r.p4.x, best_r.p4.y});\n                    current_weight_sum += weights[best_r.p1.x][best_r.p1.y];\n                    added_any_in_pass = true;\n                }\n            }\n            if (!added_any_in_pass) break;\n            shuffle(p1_list.begin(), p1_list.end(), rng);\n        }\n\n        if (current_weight_sum > best_weight_sum) {\n            best_weight_sum = current_weight_sum;\n            best_ops = current_ops;\n        }\n    }\n\n    // Output the total number of operations and the specifics for each operation\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.x1 << \" \" << op.y1 << \" \" << op.x2 << \" \" << op.y2 << \" \"\n             << op.x3 << \" \" << op.y3 << \" \" << op.x4 << \" \" << op.y4 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <chrono>\n#include <algorithm>\n#include <cstdint>\n\nusing namespace std;\n\n/**\n * Xorshift algorithm for fast pseudo-random number generation.\n */\nstruct Xorshift {\n    uint32_t x;\n    Xorshift(uint32_t seed = 123456789) : x(seed) {}\n    uint32_t next() {\n        x ^= (x << 13);\n        x ^= (x >> 17);\n        x ^= (x << 5);\n        return x;\n    }\n};\n\n/**\n * Represents the 10x10 candy box grid using a linear array for speed.\n */\nstruct Board {\n    int8_t grid[100]; // 0: empty, 1-3: flavor\n\n    Board() {\n        for (int i = 0; i < 100; ++i) grid[i] = 0;\n    }\n\n    /**\n     * Tilts the box in a given direction (0:F, 1:B, 2:L, 3:R).\n     * Returns true if any candy moved.\n     */\n    bool tilt(int dir) {\n        bool changed = false;\n        if (dir == 0) { // Forward (Up)\n            for (int j = 0; j < 10; ++j) {\n                int last = 0;\n                for (int i = 0; i < 10; ++i) {\n                    if (grid[i * 10 + j]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[i * 10 + j];\n                            grid[i * 10 + j] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 1) { // Backward (Down)\n            for (int j = 0; j < 10; ++j) {\n                int last = 9;\n                for (int i = 9; i >= 0; --i) {\n                    if (grid[i * 10 + j]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[i * 10 + j];\n                            grid[i * 10 + j] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        } else if (dir == 2) { // Left\n            for (int i = 0; i < 10; ++i) {\n                int last = 0;\n                for (int j = 0; j < 10; ++j) {\n                    if (grid[i * 10 + j]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[i * 10 + j];\n                            grid[i * 10 + j] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 3) { // Right\n            for (int i = 0; i < 10; ++i) {\n                int last = 9;\n                for (int j = 9; j >= 0; --j) {\n                    if (grid[i * 10 + j]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[i * 10 + j];\n                            grid[i * 10 + j] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * Quickly checks if a tilt direction is valid (moves anything) without copying the board.\n     */\n    bool can_tilt(int dir) const {\n        if (dir == 0) { // Up\n            for (int j = 0; j < 10; ++j) {\n                bool empty = false;\n                for (int i = 0; i < 10; ++i) {\n                    if (grid[i * 10 + j] == 0) empty = true;\n                    else if (empty) return true;\n                }\n            }\n        } else if (dir == 1) { // Down\n            for (int j = 0; j < 10; ++j) {\n                bool empty = false;\n                for (int i = 9; i >= 0; --i) {\n                    if (grid[i * 10 + j] == 0) empty = true;\n                    else if (empty) return true;\n                }\n            }\n        } else if (dir == 2) { // Left\n            for (int i = 0; i < 10; ++i) {\n                bool empty = false;\n                for (int j = 0; j < 10; ++j) {\n                    if (grid[i * 10 + j] == 0) empty = true;\n                    else if (empty) return true;\n                }\n            }\n        } else if (dir == 3) { // Right\n            for (int i = 0; i < 10; ++i) {\n                bool empty = false;\n                for (int j = 9; j >= 0; --j) {\n                    if (grid[i * 10 + j] == 0) empty = true;\n                    else if (empty) return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    void place_actual(int p, int flavor) {\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                if (++count == p) { grid[i] = flavor; return; }\n            }\n        }\n    }\n\n    void place_randomly(int flavor, Xorshift& rng) {\n        int empty_indices[100], num_empty = 0;\n        for (int i = 0; i < 100; ++i) if (grid[i] == 0) empty_indices[num_empty++] = i;\n        if (num_empty > 0) grid[empty_indices[rng.next() % num_empty]] = flavor;\n    }\n\n    int eval_score() const {\n        int sum_sq = 0;\n        bool visited[100] = {false};\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0 || visited[i]) continue;\n            int count = 0, flavor = grid[i], q[100], head = 0, tail = 0;\n            q[tail++] = i; visited[i] = true;\n            while (head < tail) {\n                int cur = q[head++], r = cur / 10, c = cur % 10; count++;\n                if (r > 0 && !visited[cur - 10] && grid[cur - 10] == flavor) { visited[cur - 10] = true; q[tail++] = cur - 10; }\n                if (r < 9 && !visited[cur + 10] && grid[cur + 10] == flavor) { visited[cur + 10] = true; q[tail++] = cur + 10; }\n                if (c > 0 && !visited[cur - 1] && grid[cur - 1] == flavor) { visited[cur - 1] = true; q[tail++] = cur - 1; }\n                if (c < 9 && !visited[cur + 1] && grid[cur + 1] == flavor) { visited[cur + 1] = true; q[tail++] = cur + 1; }\n            }\n            sum_sq += count * count;\n        }\n        return sum_sq;\n    }\n};\n\nconst int policies[4][4] = {{0, 2, 3, 1}, {0, 3, 2, 1}, {1, 2, 3, 0}, {1, 3, 2, 0}};\n\nvoid apply_fixed_policy(Board& b, int p_idx) {\n    for (int d : policies[p_idx]) if (b.tilt(d)) return;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Xorshift rng; Board current_board; char d_chars[] = {'F', 'B', 'L', 'R'};\n    auto start_program = chrono::high_resolution_clock::now();\n\n    for (int t = 0; t < 100; ++t) {\n        int p; cin >> p;\n        current_board.place_actual(p, flavors[t]);\n\n        auto now_turn = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration_cast<chrono::microseconds>(now_turn - start_program).count() / 1e6;\n        double remaining_time = 1.95 - elapsed;\n        double time_for_this_turn = (100.0 - t) * (remaining_time > 0 ? remaining_time : 0) / ((101.0 - t) * (100.0 - t) / 2.0 + 1.0);\n\n        int avail[4], num_avail = 0;\n        for (int d = 0; d < 4; ++d) if (current_board.can_tilt(d)) avail[num_avail++] = d;\n        \n        if (num_avail == 0) { cout << \"F\" << endl; continue; }\n\n        double time_per_move = time_for_this_turn / (double)num_avail;\n        long long scores[4] = {0, 0, 0, 0}; int trials[4] = {0, 0, 0, 0};\n\n        for (int i = 0; i < num_avail; ++i) {\n            int d = avail[i]; auto start_m = chrono::high_resolution_clock::now();\n            while (chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - start_m).count() / 1e6 < time_per_move) {\n                Board sim = current_board; sim.tilt(d);\n                int p_idx = rng.next() % 4;\n                for (int k = t + 1; k < 100; ++k) { sim.place_randomly(flavors[k], rng); apply_fixed_policy(sim, p_idx); }\n                scores[d] += sim.eval_score(); trials[d]++;\n            }\n        }\n\n        int best_d = avail[0]; double max_avg = -1.0;\n        for (int i = 0; i < num_avail; ++i) {\n            int d = avail[i];\n            if (trials[d] > 0) {\n                double avg = (double)scores[d] / trials[d];\n                if (avg > max_avg) { max_avg = avg; best_d = d; }\n            }\n        }\n        cout << d_chars[best_d] << endl;\n        current_board.tilt(best_d);\n    }\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Normal CDF function: Phi(x) = 0.5 * (1 + erf((x - mean) / (sigma * sqrt(2))))\n * This function calculates the probability that a random variable following a normal \n * distribution with the given mean and sigma is less than x.\n */\ndouble normal_cdf(double x, double mean, double sigma) {\n    if (sigma < 1e-9) {\n        if (x < mean) return 0.0;\n        if (x > mean) return 1.0;\n        return 0.5;\n    }\n    return 0.5 * (1.0 + erf((x - mean) / (sigma * sqrt(2.0))));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double eps;\n    // Read the number of graphs M and the error rate epsilon.\n    if (!(cin >> M >> eps)) return 0;\n\n    int bestN = 4;\n    double bestExpectedScore = -1.0;\n\n    // Iterate through all possible values for N (the number of vertices) to find the one that \n    // maximizes the expected score. The score is calculated based on the expected number of \n    // errors using an edge count encoding/decoding method.\n    for (int N = 4; N <= 100; ++N) {\n        int K = N * (N - 1) / 2; // Maximum number of possible edges.\n        vector<int> Es(M);\n        for (int s = 0; s < M; ++s) {\n            // Encode the number of edges for each graph G_s.\n            Es[s] = (int)round((double)s * K / (M - 1));\n        }\n\n        // Standard deviation of the edge count after noise (Binomial sum approximation).\n        double sigma = sqrt((double)K * eps * (1.0 - eps));\n        double P_avg = 0.0;\n\n        for (int s = 0; s < M; ++s) {\n            // Count how many graphs have the same number of edges as G_s.\n            int c = 0;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] == Es[s]) c++;\n            }\n\n            // The expected mean number of edges in the noisy graph H generated from G_s.\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n\n            // Find the closest different edge counts to identify the decision boundaries.\n            double E_prev = -1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] < Es[s]) {\n                    if (E_prev < -1e17 || Es[j] > E_prev) {\n                        E_prev = (double)Es[j];\n                    }\n                }\n            }\n\n            double E_next = 1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] > Es[s]) {\n                    if (E_next > 1e17 || Es[j] < E_next) {\n                        E_next = (double)Es[j];\n                    }\n                }\n            }\n\n            double low, high;\n            if (E_prev < -1e17) {\n                low = -1e18; // No lower bound for the first category.\n            } else {\n                double mu_prev = E_prev * (1.0 - 2.0 * eps) + (double)K * eps;\n                low = (mu_s + mu_prev) / 2.0;\n            }\n\n            if (E_next > 1e17) {\n                high = 1e18; // No upper bound for the last category.\n            } else {\n                double mu_next = E_next * (1.0 - 2.0 * eps) + (double)K * eps;\n                high = (mu_s + mu_next) / 2.0;\n            }\n\n            // Estimate the probability of correct decoding for the s-th graph.\n            double prob_correct_in_range;\n            if (sigma < 1e-9) {\n                prob_correct_in_range = 1.0;\n            } else {\n                prob_correct_in_range = normal_cdf(high, mu_s, sigma) - normal_cdf(low, mu_s, sigma);\n            }\n            // If multiple graphs have the same edge count, they are indistinguishable.\n            P_avg += prob_correct_in_range / (double)c;\n        }\n\n        // Calculate the overall expected probability of a correct prediction.\n        P_avg /= (double)M;\n        double p_error = 1.0 - P_avg;\n        // Expected absolute score formula: (1 - 0.1 * p_error)^100 / N.\n        double expectedScore = pow(1.0 - 0.1 * p_error, 100) / (double)N;\n\n        if (expectedScore > bestExpectedScore) {\n            bestExpectedScore = expectedScore;\n            bestN = N;\n        }\n    }\n\n    // Set up the selected N and the corresponding graphs G_0, ..., G_{M-1}.\n    int N = bestN;\n    int K = N * (N - 1) / 2;\n    vector<int> Es(M);\n    for (int s = 0; s < M; ++s) {\n        Es[s] = (int)round((double)s * K / (M - 1));\n    }\n\n    // Output the chosen number of vertices N.\n    cout << N << endl;\n    // Output the string representations for the M graphs.\n    for (int s = 0; s < M; ++s) {\n        string g(K, '0');\n        for (int i = 0; i < Es[s]; ++i) {\n            g[i] = '1';\n        }\n        cout << g << endl;\n    }\n    cout.flush();\n\n    // Process 100 noisy graph queries.\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        if (!(cin >> H)) break;\n        // Count the number of edges in the received graph H.\n        int EH = 0;\n        for (char c : H) {\n            if (c == '1') EH++;\n        }\n\n        // Find the graph s whose expected noisy edge count mean is closest to EH.\n        int best_s = 0;\n        double min_diff = 1e18;\n        for (int s = 0; s < M; ++s) {\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n            double diff = abs((double)EH - mu_s);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        // Output the prediction for the current query.\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Takahashi City Road Repair Problem\n * Objective: Minimize total frustration caused by road repairs over D days.\n * \n * Strategy:\n * 1. Initial assignment: Sort edges by angle from the city centroid and distribute them \n *    in a round-robin fashion (Day 1, 2, ..., D). This ensures that edges repaired \n *    on the same day are spatially far apart, reducing the risk of large detours.\n * 2. Optimization: Perform Hill Climbing by swapping edges between repair days.\n *    A proxy frustration score is used, based on shortest-path distances (SSSP) \n *    from a subset of vertices (S=20) chosen via Farthest Point Sampling.\n */\n\n// Maximum distance cap as defined in the problem.\nconst int INF = 1000000000;\nconst int MAXN = 1005;\n\nstruct Edge {\n    int to, weight, id;\n};\n\n// Global graph and problem variables.\nvector<Edge> adj[MAXN];\nint N, M, D, K;\nint X[MAXN], Y[MAXN];\nint edge_u[3005], edge_v[3005], edge_w[3005];\n\n// Reusable Dijkstra buffer.\nint dists[MAXN];\nint vis[MAXN];\nint timer = 0;\n\n/**\n * Dijkstra's algorithm to compute shortest paths from a source vertex,\n * ignoring edges scheduled for repair on 'repair_day'.\n */\nvoid dijkstra(int start, int repair_day, const vector<int>& edge_day) {\n    timer++;\n    dists[start] = 0;\n    vis[start] = timer;\n    using P = pair<int, int>;\n    // Priority queue for standard Dijkstra implementation.\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, start});\n    \n    while (!pq.empty()) {\n        P top = pq.top(); pq.pop();\n        int d = top.first;\n        int u = top.second;\n        if (d > dists[u]) continue;\n        \n        for (const auto& e : adj[u]) {\n            // Check if edge is under repair.\n            if (edge_day[e.id] == repair_day) continue;\n            int vd = d + e.weight;\n            if (vis[e.to] != timer || vd < dists[e.to]) {\n                dists[e.to] = vd;\n                vis[e.to] = timer;\n                pq.push({vd, e.to});\n            }\n        }\n    }\n}\n\n// Precomputed distances from sources in the full (original) graph.\nint base_dists[25][MAXN];\nint S = 20; // Number of source points for the frustration proxy.\nvector<int> sources;\n\n/**\n * Computes a frustration proxy for a specific day:\n * sum over selected sources of (dist_modified - dist_original).\n */\nlong long compute_frustration(int day, const vector<int>& edge_day) {\n    long long total = 0;\n    for (int i = 0; i < S; ++i) {\n        dijkstra(sources[i], day, edge_day);\n        for (int j = 1; j <= N; ++j) {\n            int d_k = (vis[j] == timer) ? min(dists[j], INF) : INF;\n            total += (long long)(d_k - base_dists[i][j]);\n        }\n    }\n    return total;\n}\n\nstruct EdgeInfo {\n    int id;\n    double angle;\n};\n\nint main() {\n    // Fast I/O.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    for (int i = 1; i <= M; ++i) {\n        cin >> edge_u[i] >> edge_v[i] >> edge_w[i];\n        adj[edge_u[i]].push_back({edge_v[i], edge_w[i], i});\n        adj[edge_v[i]].push_back({edge_u[i], edge_w[i], i});\n    }\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    // Source vertex selection using Farthest Point Sampling for better coverage.\n    sources.push_back(1);\n    for (int i = 1; i < S; ++i) {\n        int best_v = -1;\n        long long max_d = -1;\n        for (int v = 1; v <= N; ++v) {\n            long long min_d = 1e18;\n            for (int s : sources) {\n                long long d = (long long)(X[v]-X[s])*(X[v]-X[s]) + (long long)(Y[v]-Y[s])*(Y[v]-Y[s]);\n                if (d < min_d) min_d = d;\n            }\n            if (min_d > max_d) {\n                max_d = min_d;\n                best_v = v;\n            }\n        }\n        sources.push_back(best_v);\n    }\n\n    // Precalculate original distances for proxy.\n    vector<int> dummy_day(M + 1, -1);\n    for (int i = 0; i < S; ++i) {\n        dijkstra(sources[i], -1, dummy_day);\n        for (int j = 1; j <= N; ++j) {\n            base_dists[i][j] = (vis[j] == timer) ? min(dists[j], INF) : INF;\n        }\n    }\n\n    // Initial spatial heuristic: distribute edges based on their angle from the centroid.\n    double cx = 0, cy = 0;\n    for (int i = 1; i <= N; ++i) { cx += X[i]; cy += Y[i]; }\n    cx /= N; cy /= N;\n\n    vector<EdgeInfo> all_edges(M);\n    for (int i = 1; i <= M; ++i) {\n        double mx = (X[edge_u[i]] + X[edge_v[i]]) / 2.0;\n        double my = (Y[edge_u[i]] + Y[edge_v[i]]) / 2.0;\n        all_edges[i-1] = {i, atan2(my - cy, mx - cx)};\n    }\n    sort(all_edges.begin(), all_edges.end(), [](const EdgeInfo& a, const EdgeInfo& b) {\n        return a.angle < b.angle;\n    });\n\n    vector<int> edge_day(M + 1);\n    vector<vector<int>> day_lists(D + 1);\n    for (int i = 0; i < M; ++i) {\n        int d = (i % D) + 1;\n        edge_day[all_edges[i].id] = d;\n        day_lists[d].push_back(all_edges[i].id);\n    }\n\n    // Initialize frustration for each day.\n    vector<long long> day_frust(D + 1);\n    for (int d = 1; d <= D; ++d) {\n        day_frust[d] = compute_frustration(d, edge_day);\n    }\n\n    // Local Optimization: Hill Climbing.\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    while (true) {\n        // Time management check.\n        if ((++iterations & 31) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5750) break;\n        }\n\n        // Randomly select two days to potentially swap repair work.\n        int d1 = uniform_int_distribution<int>(1, D)(rng);\n        int d2 = uniform_int_distribution<int>(1, D)(rng);\n        if (d1 == d2) continue;\n\n        // Adaptive strategy: Bias towards selecting high-frustration days for optimization.\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            int max_d = 1;\n            for(int d=2; d<=D; ++d) if(day_frust[d] > day_frust[max_d]) max_d = d;\n            d1 = max_d;\n        }\n\n        if (day_lists[d1].empty() || day_lists[d2].empty()) continue;\n\n        // Select random edges from the chosen days.\n        int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n        int idx2 = uniform_int_distribution<int>(0, (int)day_lists[d2].size() - 1)(rng);\n        int e1 = day_lists[d1][idx1];\n        int e2 = day_lists[d2][idx2];\n\n        // Tentative swap.\n        edge_day[e1] = d2;\n        edge_day[e2] = d1;\n        long long nf1 = compute_frustration(d1, edge_day);\n        long long nf2 = compute_frustration(d2, edge_day);\n\n        // Keep the swap only if total frustration across the two days decreases.\n        if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n            day_frust[d1] = nf1;\n            day_frust[d2] = nf2;\n            day_lists[d1][idx1] = e2;\n            day_lists[d2][idx2] = e1;\n        } else {\n            // Revert.\n            edge_day[e1] = d1;\n            edge_day[e2] = d2;\n        }\n    }\n\n    // Print final schedule.\n    for (int i = 1; i <= M; ++i) {\n        cout << edge_day[i] << (i == M ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n// Coordinate structure for voxels\nstruct Voxel {\n    int x, y, z;\n    bool operator<(const Voxel& o) const {\n        if (x != o.x) return x < o.x;\n        if (y != o.y) return y < o.y;\n        return z < o.z;\n    }\n};\n\n// Standard rotations for 90-degree axis changes\nVoxel rotX(Voxel v) { return {v.x, -v.z, v.y}; }\nVoxel rotY(Voxel v) { return {v.z, v.y, -v.x}; }\nVoxel rotZ(Voxel v) { return {-v.y, v.x, v.z}; }\n\n// Pre-calculate all 24 possible 90-degree rotations\nvector<vector<Voxel>> get_rotations() {\n    set<vector<Voxel>> unique_rots;\n    vector<Voxel> unit_cube = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};\n    for (int i = 0; i < 4; ++i) {\n        for (int j = 0; j < 4; ++j) {\n            for (int k = 0; k < 4; ++k) {\n                vector<Voxel> current = unit_cube;\n                for (int ii = 0; ii < i; ++ii) for (auto& v : current) v = rotX(v);\n                for (int jj = 0; jj < j; ++jj) for (auto& v : current) v = rotY(v);\n                for (int kk = 0; kk < k; ++kk) for (auto& v : current) v = rotZ(v);\n                unique_rots.insert(current);\n            }\n        }\n    }\n    vector<vector<Voxel>> res;\n    for (auto& rot : unique_rots) res.push_back(rot);\n    return res;\n}\n\nint D;\nstring f1[14], r1[14], f2[14], r2[14];\n\nstruct State {\n    int r_idx;\n    int dx, dy, dz;\n    double score = 1e18;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> D)) return 0;\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    // Q1 and Q2 are the maximal sets of voxels satisfying the silhouette requirements\n    vector<Voxel> Q1, Q2;\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 (f1[z][x] == '1' && r1[z][y] == '1') Q1.push_back({x, y, z});\n                if (f2[z][x] == '1' && r2[z][y] == '1') Q2.push_back({x, y, z});\n            }\n        }\n    }\n\n    auto rots = get_rotations();\n    vector<vector<Voxel>> Q2_rots(rots.size());\n    for (int i = 0; i < rots.size(); ++i) {\n        for (auto& v : Q2) {\n            Voxel rv;\n            rv.x = v.x * rots[i][0].x + v.y * rots[i][1].x + v.z * rots[i][2].x;\n            rv.y = v.x * rots[i][0].y + v.y * rots[i][1].y + v.z * rots[i][2].y;\n            rv.z = v.x * rots[i][0].z + v.y * rots[i][1].z + v.z * rots[i][2].z;\n            Q2_rots[i].push_back(rv);\n        }\n    }\n\n    State best_state;\n    static bool q2_rot_grid[60][60][60];\n\n    for (int ri = 0; ri < (int)rots.size(); ++ri) {\n        int min_x = 100, max_x = -100, min_y = 100, max_y = -100, min_z = 100, max_z = -100;\n        for (auto& v : Q2_rots[ri]) {\n            min_x = min(min_x, v.x); max_x = max(max_x, v.x);\n            min_y = min(min_y, v.y); max_y = max(max_y, v.y);\n            min_z = min(min_z, v.z); max_z = max(max_z, v.z);\n        }\n        \n        for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid[i][j][k] = false;\n        for (auto& v : Q2_rots[ri]) q2_rot_grid[v.x + 30][v.y + 30][v.z + 30] = true;\n\n        for (int dx = -(max_x + 1); dx <= D - min_x; ++dx) {\n            for (int dy = -(max_y + 1); dy <= D - min_y; ++dy) {\n                for (int dz = -(max_z + 1); dz <= D - min_z; ++dz) {\n                    vector<Voxel> S;\n                    bool s_f1[14][14] = {false}, s_r1[14][14] = {false};\n                    bool s_f2[14][14] = {false}, s_r2[14][14] = {false};\n                    \n                    for (auto& v : Q1) {\n                        if (q2_rot_grid[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) {\n                            S.push_back(v);\n                            s_f1[v.z][v.x] = true;\n                            s_r1[v.z][v.y] = true;\n                            \n                            int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n                            int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n                            int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n                            s_f2[oz][ox] = true;\n                            s_r2[oz][oy] = true;\n                        }\n                    }\n                    if (S.empty()) continue;\n\n                    int n1 = 0, n2 = 0;\n                    for (int z = 0; z < D; ++z) {\n                        int uf1 = 0, ur1 = 0, uf2 = 0, ur2 = 0;\n                        for (int x = 0; x < D; ++x) if (f1[z][x] == '1' && !s_f1[z][x]) uf1++;\n                        for (int y = 0; y < D; ++y) if (r1[z][y] == '1' && !s_r1[z][y]) ur1++;\n                        n1 += max(uf1, ur1);\n                        for (int x = 0; x < D; ++x) if (f2[z][x] == '1' && !s_f2[z][x]) uf2++;\n                        for (int y = 0; y < D; ++y) if (r2[z][y] == '1' && !s_r2[z][y]) ur2++;\n                        n2 += max(uf2, ur2);\n                    }\n\n                    if (max(n1, n2) > best_state.score) continue;\n\n                    double sum1v = 0;\n                    vector<bool> visited(S.size(), false);\n                    for (int i = 0; i < (int)S.size(); ++i) {\n                        if (!visited[i]) {\n                            int count = 0;\n                            queue<int> q; q.push(i); visited[i] = true;\n                            while (!q.empty()) {\n                                int u = q.front(); q.pop();\n                                count++;\n                                for (int v = 0; v < (int)S.size(); ++v) {\n                                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                                        visited[v] = true; q.push(v);\n                                    }\n                                }\n                            }\n                            sum1v += 1.0 / count;\n                        }\n                    }\n\n                    if (max(n1, n2) + sum1v < best_state.score) {\n                        best_state = {ri, dx, dy, dz, max(n1, n2) + sum1v};\n                    }\n                }\n            }\n        }\n    }\n\n    // Finalize output with the best rotation and translation found\n    int ri = best_state.r_idx;\n    int dx = best_state.dx, dy = best_state.dy, dz = best_state.dz;\n    vector<Voxel> S;\n    static bool q2_rot_grid_final[60][60][60];\n    for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid_final[i][j][k] = false;\n    for (auto& v : Q2_rots[ri]) q2_rot_grid_final[v.x + 30][v.y + 30][v.z + 30] = true;\n    for (auto& v : Q1) if (q2_rot_grid_final[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) S.push_back(v);\n\n    static int b1[14][14][14], b2[14][14][14];\n    for (int i = 0; i < 14; ++i) for (int j = 0; j < 14; ++j) for (int k = 0; k < 14; ++k) b1[i][j][k] = b2[i][j][k] = 0;\n    int block_id = 1;\n\n    vector<bool> visited(S.size(), false);\n    for (int i = 0; i < (int)S.size(); ++i) {\n        if (!visited[i]) {\n            queue<int> q; q.push(i); visited[i] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                b1[S[u].x][S[u].y][S[u].z] = block_id;\n                int ox = (S[u].x - dx) * rots[ri][0].x + (S[u].y - dy) * rots[ri][0].y + (S[u].z - dz) * rots[ri][0].z;\n                int oy = (S[u].x - dx) * rots[ri][1].x + (S[u].y - dy) * rots[ri][1].y + (S[u].z - dz) * rots[ri][1].z;\n                int oz = (S[u].x - dx) * rots[ri][2].x + (S[u].y - dy) * rots[ri][2].y + (S[u].z - dz) * rots[ri][2].z;\n                b2[ox][oy][oz] = block_id;\n                for (int v = 0; v < (int)S.size(); ++v) {\n                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                        visited[v] = true; q.push(v);\n                    }\n                }\n            }\n            block_id++;\n        }\n    }\n\n    auto get_extra_voxels = [&](const vector<Voxel>& s, const string* f, const string* r) {\n        vector<Voxel> extra_voxels;\n        bool s_f[14][14] = {false}, s_r[14][14] = {false};\n        for (auto& v : s) { s_f[v.z][v.x] = true; s_r[v.z][v.y] = true; }\n        for (int z = 0; z < D; ++z) {\n            vector<int> uf, ur;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1' && !s_f[z][x]) uf.push_back(x);\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1' && !s_r[z][y]) ur.push_back(y);\n            if (uf.empty() && ur.empty()) continue;\n            int any_x = -1, any_y = -1;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1') { any_x = x; break; }\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1') { any_y = y; break; }\n            int m = max((int)uf.size(), (int)ur.size());\n            for (int i = 0; i < m; ++i) {\n                extra_voxels.push_back({(i < (int)uf.size()) ? uf[i] : any_x, (i < (int)ur.size()) ? ur[i] : any_y, z});\n            }\n        }\n        return extra_voxels;\n    };\n\n    vector<Voxel> S_in_Q2_orig;\n    for (auto& v : S) {\n        int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n        int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n        int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n        S_in_Q2_orig.push_back({ox, oy, oz});\n    }\n\n    auto extra1 = get_extra_voxels(S, f1, r1);\n    auto extra2 = get_extra_voxels(S_in_Q2_orig, f2, r2);\n\n    int k = min((int)extra1.size(), (int)extra2.size());\n    for (int i = 0; i < k; ++i) {\n        b1[extra1[i].x][extra1[i].y][extra1[i].z] = b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n    }\n    for (int i = k; i < (int)extra1.size(); ++i) b1[extra1[i].x][extra1[i].y][extra1[i].z] = block_id++;\n    for (int i = k; i < (int)extra2.size(); ++i) b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n\n    cout << block_id - 1 << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b1[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b2[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct MetricEdge {\n    int u, v;\n    long long dist;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n + 1);\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    void reset(int n) {\n        for (int i = 0; i <= n; ++i) parent[i] = i;\n    }\n};\n\nlong long dist2_pts(int x1, int y1, int x2, int y2) {\n    return (long long)(x1 - x2) * (x1 - x2) + (long long)(y1 - y2) * (y1 - y2);\n}\n\nconst long long PENALTY = 1e15;\n\nint main() {\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<pair<int, int>> vertices(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> vertices[i].first >> vertices[i].second;\n\n    vector<Edge> edges(M);\n    vector<vector<int>> adj(N + 1);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) cin >> residents[k].first >> residents[k].second;\n\n    vector<vector<long long>> dist(N + 1, vector<long long>(N + 1, 1e15));\n    for (int i = 1; i <= N; ++i) dist[i][i] = 0;\n    for (int j = 0; j < M; ++j) {\n        dist[edges[j].u][edges[j].v] = min(dist[edges[j].u][edges[j].v], (long long)edges[j].w);\n        dist[edges[j].v][edges[j].u] = min(dist[edges[j].v][edges[j].u], (long long)edges[j].w);\n    }\n\n    for (int k = 1; k <= N; ++k)\n        for (int i = 1; i <= N; ++i)\n            for (int j = 1; j <= N; ++j)\n                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n\n    vector<int> path_edges[101][101];\n    for (int i = 1; i <= N; ++i) {\n        for (int j = 1; j <= N; ++j) {\n            if (i == j) continue;\n            int curr = i;\n            while (curr != j) {\n                bool found = false;\n                for (int e_idx : adj[curr]) {\n                    int next = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);\n                    if (edges[e_idx].w + dist[next][j] == dist[curr][j]) {\n                        path_edges[i][j].push_back(e_idx);\n                        curr = next;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n    }\n\n    vector<vector<long long>> dist2_v_r(N + 1, vector<long long>(K));\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dist2_v_r[i][k] = dist2_pts(vertices[i].first, vertices[i].second, residents[k].first, residents[k].second);\n        }\n    }\n\n    vector<vector<int>> sorted_v_for_r(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        iota(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), 1);\n        sort(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), [&](int a, int b) {\n            return dist2_v_r[a][k] < dist2_v_r[b][k];\n        });\n    }\n\n    vector<MetricEdge> all_metric_edges;\n    for (int i = 1; i <= N; ++i) {\n        for (int j = i + 1; j <= N; ++j) {\n            all_metric_edges.push_back({i, j, dist[i][j]});\n        }\n    }\n    sort(all_metric_edges.begin(), all_metric_edges.end(), [](const MetricEdge& a, const MetricEdge& b) {\n        return a.dist < b.dist;\n    });\n\n    vector<bool> is_active(N + 1, true);\n    vector<int> nearest_v(K);\n    for (int k = 0; k < K; ++k) nearest_v[k] = sorted_v_for_r[k][0];\n\n    auto start_time = chrono::steady_clock::now();\n    DSU dsu(N);\n    vector<long long> max_d2(N + 1);\n    vector<bool> in_V_req(N + 1);\n    vector<int> edge_used(M, 0);\n    int timestamp = 0;\n\n    auto get_total_cost = [&]() {\n        for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n        for (int k = 0; k < K; ++k) {\n            if (dist2_v_r[nearest_v[k]][k] > max_d2[nearest_v[k]]) {\n                max_d2[nearest_v[k]] = dist2_v_r[nearest_v[k]][k];\n            }\n        }\n\n        long long coverage_cost = 0;\n        int V_req_count = 0;\n        for (int i = 1; i <= N; ++i) {\n            if (i == 1 || (is_active[i] && max_d2[i] > 0)) {\n                in_V_req[i] = true;\n                V_req_count++;\n                if (max_d2[i] > 25000000LL) coverage_cost += PENALTY;\n                else {\n                    int p = (int)sqrt(max_d2[i]);\n                    while ((long long)p * p < max_d2[i]) p++;\n                    coverage_cost += (long long)p * p;\n                }\n            } else {\n                in_V_req[i] = false;\n            }\n        }\n\n        long long tree_cost = 0;\n        if (V_req_count > 1) {\n            dsu.reset(N);\n            int edges_found = 0;\n            timestamp++;\n            for (auto& me : all_metric_edges) {\n                if (in_V_req[me.u] && in_V_req[me.v]) {\n                    if (dsu.unite(me.u, me.v)) {\n                        for (int e_id : path_edges[me.u][me.v]) {\n                            if (edge_used[e_id] != timestamp) {\n                                edge_used[e_id] = timestamp;\n                                tree_cost += edges[e_id].w;\n                            }\n                        }\n                        if (++edges_found == V_req_count - 1) break;\n                    }\n                }\n            }\n        }\n        return coverage_cost + tree_cost;\n    };\n\n    long long cur_cost = get_total_cost();\n    long long best_cost = cur_cost;\n    vector<bool> best_is_active = is_active;\n\n    mt19937 rng(42);\n    uniform_real_distribution<double> dist_unif(0, 1);\n    uniform_int_distribution<int> dist_v(2, N);\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            if (elapsed > 1850) break;\n        }\n        iter++;\n\n        int v = dist_v(rng);\n        vector<pair<int, int>> changed_residents;\n        bool was_active = is_active[v];\n        is_active[v] = !was_active;\n\n        if (is_active[v]) {\n            for (int k = 0; k < K; ++k) {\n                if (dist2_v_r[v][k] < dist2_v_r[nearest_v[k]][k]) {\n                    changed_residents.push_back({k, nearest_v[k]});\n                    nearest_v[k] = v;\n                }\n            }\n        } else {\n            for (int k = 0; k < K; ++k) {\n                if (nearest_v[k] == v) {\n                    changed_residents.push_back({k, v});\n                    for (int nv : sorted_v_for_r[k]) {\n                        if (is_active[nv]) {\n                            nearest_v[k] = nv;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n\n        long long new_cost = get_total_cost();\n        double progress = (double)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() / 1850.0;\n        double T = 1e6 * pow(1e3 / 1e6, progress);\n\n        if (new_cost < cur_cost || (new_cost > cur_cost && dist_unif(rng) < exp((double)(cur_cost - new_cost) / T))) {\n            cur_cost = new_cost;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_is_active = is_active;\n            }\n        } else {\n            is_active[v] = was_active;\n            for (auto& p : changed_residents) nearest_v[p.first] = p.second;\n        }\n    }\n\n    is_active = best_is_active;\n    for (int k = 0; k < K; ++k) {\n        for (int nv : sorted_v_for_r[k]) {\n            if (is_active[nv]) { nearest_v[k] = nv; break; }\n        }\n    }\n    for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n    for (int k = 0; k < K; ++k) max_d2[nearest_v[k]] = max(max_d2[nearest_v[k]], dist2_v_r[nearest_v[k]][k]);\n    int V_req_count = 0;\n    for (int i = 1; i <= N; ++i) {\n        if (i == 1 || (is_active[i] && max_d2[i] > 0)) { in_V_req[i] = true; V_req_count++; }\n        else in_V_req[i] = false;\n    }\n\n    vector<int> final_B(M, 0);\n    vector<int> union_edges;\n    if (V_req_count > 1) {\n        dsu.reset(N);\n        int edges_found = 0;\n        timestamp++;\n        for (auto& me : all_metric_edges) {\n            if (in_V_req[me.u] && in_V_req[me.v]) {\n                if (dsu.unite(me.u, me.v)) {\n                    for (int e_id : path_edges[me.u][me.v]) {\n                        if (edge_used[e_id] != timestamp) {\n                            edge_used[e_id] = timestamp;\n                            union_edges.push_back(e_id);\n                        }\n                    }\n                    if (++edges_found == V_req_count - 1) break;\n                }\n            }\n        }\n    }\n\n    dsu.reset(N);\n    sort(union_edges.begin(), union_edges.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n    for (int e_id : union_edges) {\n        if (dsu.unite(edges[e_id].u, edges[e_id].v)) final_B[e_id] = 1;\n    }\n\n    vector<int> reachable;\n    vector<int> q = {1};\n    vector<bool> visited(N + 1, false);\n    visited[1] = true;\n    int head = 0;\n    while(head < (int)q.size()){\n        int u = q[head++];\n        reachable.push_back(u);\n        for(int e_idx : adj[u]){\n            if(final_B[e_idx]){\n                int v = (edges[e_idx].u == u ? edges[e_idx].v : edges[e_idx].u);\n                if(!visited[v]){ visited[v] = true; q.push_back(v); }\n            }\n        }\n    }\n\n    vector<long long> final_max_d2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        long long min_d2 = 8e18;\n        int best_v = -1;\n        for (int v : reachable) {\n            if (dist2_v_r[v][k] < min_d2) { min_d2 = dist2_v_r[v][k]; best_v = v; }\n        }\n        final_max_d2[best_v] = max(final_max_d2[best_v], min_d2);\n    }\n\n    vector<int> final_P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) {\n        if (final_max_d2[i] > 0) {\n            int p = (int)sqrt(final_max_d2[i]);\n            while ((long long)p * p < final_max_d2[i]) p++;\n            final_P[i] = p;\n        }\n    }\n\n    while (true) {\n        bool changed = false;\n        vector<int> deg(N + 1, 0);\n        for (int j = 0; j < M; ++j) if (final_B[j]) { deg[edges[j].u]++; deg[edges[j].v]++; }\n        for (int i = 2; i <= N; ++i) {\n            if (deg[i] == 1 && final_P[i] == 0) {\n                for (int j = 0; j < M; ++j) {\n                    if (final_B[j] && (edges[j].u == i || edges[j].v == i)) {\n                        final_B[j] = 0;\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    for (int i = 1; i <= N; ++i) cout << min(final_P[i], 5000) << (i == N ? \"\" : \" \");\n    cout << endl;\n    for (int j = 0; j < M; ++j) cout << final_B[j] << (j == M - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// The pyramid has N tiers, where N=30 for all inputs.\n// The total number of balls is num_balls = N*(N+1)/2 = 465.\nconst int N = 30;\nconst int num_balls = N * (N + 1) / 2;\n\nstruct Pos {\n    int x, y;\n};\n\nstruct Move {\n    int x1, y1, x2, y2;\n};\n\n// Global pyramid data to store the initial configuration.\nint initial_pyramid[N][N];\n\n// Check if a coordinate (x, y) is within the pyramid's triangular boundaries.\nbool isValid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y <= x;\n}\n\n// 6-directional adjacencies as defined in the problem.\nint dx[] = {-1, -1, 0, 0, 1, 1};\nint dy[] = {-1, 0, -1, 1, 0, 1};\n\n/**\n * A target position (x, y) for value v is an unsettled position whose ancestors\n * have all been settled with values from {0, ..., v-1}.\n * Settling values 0, 1, ..., v-1 first ensures the final pyramid satisfies\n * the required heap-like property.\n */\nbool is_target(int x, int y, const bool current_settled[N][N]) {\n    if (current_settled[x][y]) return false;\n    if (x == 0 && y == 0) return true;\n    if (y == 0) return current_settled[x - 1][0];\n    if (y == x) return current_settled[x - 1][x - 1];\n    return current_settled[x - 1][y - 1] && current_settled[x - 1][y];\n}\n\n// Global random engine to vary target and path selection across simulations.\nmt19937 rng(42);\n\nstruct SimulationResult {\n    int K;\n    vector<Move> moves;\n};\n\n/**\n * Runs a greedy simulation that settles values 0, 1, ..., 464 sequentially.\n * For each value v, it finds the nearest available target position using BFS\n * through unsettled positions and moves v there.\n */\nSimulationResult run_simulation() {\n    static int pyramid[N][N];\n    static Pos current_pos[num_balls];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            pyramid[i][j] = initial_pyramid[i][j];\n            current_pos[pyramid[i][j]] = {i, j};\n        }\n    }\n\n    static bool current_settled[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            current_settled[i][j] = false;\n        }\n    }\n\n    vector<Move> moves;\n    int total_K = 0;\n\n    for (int v = 0; v < num_balls; ++v) {\n        Pos start = current_pos[v];\n        // If the value is already at a target position, just settle it.\n        if (is_target(start.x, start.y, current_settled)) {\n            current_settled[start.x][start.y] = true;\n            continue;\n        }\n\n        // BFS to find all reachable target positions with minimum distance.\n        queue<Pos> q;\n        q.push(start);\n        static int d[N][N];\n        static Pos parent[N][N];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j <= i; ++j) {\n                d[i][j] = -1;\n            }\n        }\n        d[start.x][start.y] = 0;\n\n        int min_target_dist = 1e9;\n        vector<Pos> best_targets;\n\n        int indices[] = {0, 1, 2, 3, 4, 5};\n        while (!q.empty()) {\n            Pos curr = q.front();\n            q.pop();\n\n            // Once we have explored all nodes at min_target_dist, we can stop.\n            if (d[curr.x][curr.y] >= min_target_dist) break;\n\n            shuffle(indices, indices + 6, rng);\n            for (int i : indices) {\n                int nx = curr.x + dx[i];\n                int ny = curr.y + dy[i];\n                // Only move through unsettled positions.\n                if (isValid(nx, ny) && !current_settled[nx][ny] && d[nx][ny] == -1) {\n                    d[nx][ny] = d[curr.x][curr.y] + 1;\n                    parent[nx][ny] = curr;\n                    if (is_target(nx, ny, current_settled)) {\n                        if (d[nx][ny] < min_target_dist) {\n                            min_target_dist = d[nx][ny];\n                            best_targets = {{nx, ny}};\n                        } else if (d[nx][ny] == min_target_dist) {\n                            best_targets.push_back({nx, ny});\n                        }\n                    }\n                    // Continue BFS until we find at least one target.\n                    if (min_target_dist == 1e9) {\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n\n        if (best_targets.empty()) continue;\n\n        // Choose one of the closest target positions randomly.\n        Pos target = best_targets[rng() % best_targets.size()];\n        vector<Pos> path;\n        Pos temp = target;\n        while (temp.x != start.x || temp.y != start.y) {\n            path.push_back(temp);\n            temp = parent[temp.x][temp.y];\n        }\n        reverse(path.begin(), path.end());\n\n        // Perform the swaps along the shortest path.\n        for (Pos p : path) {\n            int v_other = pyramid[p.x][p.y];\n            moves.push_back({start.x, start.y, p.x, p.y});\n            swap(pyramid[start.x][start.y], pyramid[p.x][p.y]);\n            current_pos[v] = p;\n            current_pos[v_other] = start;\n            start = p;\n            total_K++;\n        }\n        current_settled[target.x][target.y] = true;\n    }\n\n    return {total_K, moves};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial pyramid configuration.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> initial_pyramid[i][j])) break;\n        }\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    SimulationResult best_res = {1000000, {}};\n\n    // Run as many simulations as possible within the 2.0s time limit.\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n        if (elapsed > 1.85) break;\n\n        SimulationResult res = run_simulation();\n        // Priority is to satisfy E=0 (satisfied by the algorithm) with minimal K.\n        if (res.K < best_res.K) {\n            best_res = res;\n        }\n    }\n\n    // Output the results of the best simulation found.\n    if (best_res.K <= 10000) {\n        cout << best_res.moves.size() << \"\\n\";\n        for (const auto& m : best_res.moves) {\n            cout << m.x1 << \" \" << m.y1 << \" \" << m.x2 << \" \" << m.y2 << \"\\n\";\n        }\n    } else {\n        // Fallback for safety (should not happen with given constraints).\n        cout << 0 << \"\\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// Warehouse dimensions and constants\nconst int D = 9;\nconst int ENTRANCE_I = 0;\nconst int ENTRANCE_J = 4; // Center of the northernmost row\n\n// Represents a square in the DxD warehouse grid\nstruct Square {\n    int i, j;\n    bool operator<(const Square& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Square& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint V[D][D];         // Storage/Removal priority rank (higher = deeper, remove later)\nbool obstacle[D][D]; // Grid status: true if square is an obstacle\nint grid[D][D];      // Current grid state: -3=entrance, -2=obstacle, -1=empty, >=0=container ID\n\n/**\n * Precalculates the ideal removal order (V ranks) for each storage square.\n * This simulation identifies squares that can be removed as \"leaves\" (not blocking others)\n * and assigns them higher ranks based on their distance from the entrance.\n */\nvoid precalculate_V(int M) {\n    int dist_bfs[D][D];\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) dist_bfs[i][j] = -1;\n\n    // Initial BFS to calculate minimal distance from the entrance for all squares\n    queue<Square> q;\n    q.push({ENTRANCE_I, ENTRANCE_J});\n    dist_bfs[ENTRANCE_I][ENTRANCE_J] = 0;\n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n    while (!q.empty()) {\n        Square curr = q.front(); q.pop();\n        for (int k = 0; k < 4; ++k) {\n            int ni = curr.i + di[k], nj = curr.j + dj[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && dist_bfs[ni][nj] == -1) {\n                dist_bfs[ni][nj] = dist_bfs[curr.i][curr.j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Determine the ideal sequence of retrieval using a greedy approach\n    set<Square> E_v;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j)\n            if (!obstacle[i][j] && !(i == ENTRANCE_I && j == ENTRANCE_J)) E_v.insert({i, j});\n\n    // We simulate retrieval in reverse order (M-1 down to 0) to assign ranks\n    for (int k = M - 1; k >= 0; --k) {\n        Square best_s = {-1, -1};\n        int max_score = -1;\n        for (auto const& s : E_v) {\n            // Check connectivity: removing square 's' shouldn't isolate any other empty square\n            int count = 0;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int ni = curr.i + di[d], nj = curr.j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && \n                        E_v.count({ni, nj}) && !visited[ni][nj] && !(ni == s.i && nj == s.j)) {\n                        visited[ni][nj] = true;\n                        q_safe.push({ni, nj});\n                        count++;\n                    }\n                }\n            }\n            if (count == (int)E_v.size() - 1) {\n                // Tie-breaker prioritizing deeper/further squares for higher ranks\n                int score = dist_bfs[s.i][s.j] * 1000 + abs(s.j - ENTRANCE_J) * 10 + s.i;\n                if (score > max_score) { max_score = score; best_s = s; }\n            }\n        }\n        if (best_s.i != -1) {\n            V[best_s.i][best_s.j] = k;\n            E_v.erase(best_s);\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) obstacle[i][j] = false;\n    for (int i = 0; i < N; ++i) {\n        int r, c; cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n\n    int M = D * D - 1 - N; // Total containers\n    precalculate_V(M);\n\n    vector<int> remaining_t;\n    for (int i = 0; i < M; ++i) remaining_t.push_back(i);\n\n    set<Square> E; // Set of currently empty storage squares\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == ENTRANCE_I && j == ENTRANCE_J) grid[i][j] = -3;\n            else if (obstacle[i][j]) grid[i][j] = -2;\n            else { grid[i][j] = -1; E.insert({i, j}); }\n        }\n    }\n\n    // 1. Online Storage Phase\n    for (int d = 0; d < M; ++d) {\n        int t_d; cin >> t_d;\n        int t_rank = 0;\n        for (int t : remaining_t) if (t < t_d) t_rank++;\n\n        // Find all reachable empty squares that are also \"safe\" (not blocking others)\n        vector<Square> safe_reachable;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n        for (auto const& s : E) {\n            int count = 0;\n            bool s_reachable = false;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int ni = curr.i + di[k], nj = curr.j + dj[k];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] != -2 && !visited[ni][nj]) {\n                        if (ni == s.i && nj == s.j) { s_reachable = true; visited[ni][nj] = true; }\n                        else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                            visited[ni][nj] = true; q_safe.push({ni, nj});\n                            if (grid[ni][nj] == -1) count++;\n                        }\n                    }\n                }\n            }\n            if (s_reachable && count == (int)E.size() - 1) safe_reachable.push_back(s);\n        }\n\n        // Match the current container's rank to the available storage square ranks\n        Square best_s = {-1, -1};\n        int min_diff = 1e9;\n        for (auto const& s : safe_reachable) {\n            int v_rank = 0;\n            for (auto const& other : E) if (V[other.i][other.j] < V[s.i][s.j]) v_rank++;\n            if (abs(v_rank - t_rank) < min_diff) { min_diff = abs(v_rank - t_rank); best_s = s; }\n            else if (abs(v_rank - t_rank) == min_diff) {\n                if (best_s.i == -1 || V[s.i][s.j] > V[best_s.i][best_s.j]) best_s = s;\n            }\n        }\n        if (best_s.i == -1) best_s = *E.begin(); // Safety fallback\n\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = t_d;\n        E.erase(best_s);\n        remaining_t.erase(find(remaining_t.begin(), remaining_t.end(), t_d));\n    }\n\n    // 2. Offline Removal Phase\n    for (int d = 0; d < M; ++d) {\n        vector<Square> reachable_containers;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<Square> q;\n        q.push({ENTRANCE_I, ENTRANCE_J});\n        visited[ENTRANCE_I][ENTRANCE_J] = true;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n        while (!q.empty()) {\n            Square curr = q.front(); q.pop();\n            for (int k = 0; k < 4; ++k) {\n                int ni = curr.i + di[k], nj = curr.j + dj[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] != -2) {\n                    if (grid[ni][nj] >= 0) {\n                        reachable_containers.push_back({ni, nj});\n                        visited[ni][nj] = true;\n                    } else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        Square best_s = {-1, -1};\n        int min_t = 1e9;\n        for (auto const& s : reachable_containers) {\n            if (grid[s.i][s.j] < min_t) { min_t = grid[s.i][s.j]; best_s = s; }\n        }\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = -1; // Mark square as empty for future retrieval paths\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// The grid size is 50x50 and number of wards is 100 according to problem description.\nconst int N_MAX = 50;\nconst int M_MAX = 100;\n\nint grid[N_MAX][N_MAX];\nbool adj[M_MAX + 1][M_MAX + 1];\nint count_adj[M_MAX + 1][M_MAX + 1];\nint dx[] = {0, 0, 1, -1};\nint dy[] = {1, -1, 0, 0};\n\nint visit_token = 0;\nint visited[N_MAX][N_MAX];\n\n// Check if a grid cell is on the boundary.\nbool is_on_boundary(int i, int j, int n) {\n    return i == 0 || i == n - 1 || j == 0 || j == n - 1;\n}\n\n// Check if a square can be safely changed to color 0 without violating the constraints.\nbool can_remove(int r, int c_col, int n, int m) {\n    int color = grid[r][c_col];\n    if (color == 0) return false;\n\n    int n_adj_c_square[M_MAX + 1] = {0};\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n            int d = grid[ni][nj];\n            // If any neighbor d is not adjacent to 0 originally, it cannot become adjacent now.\n            if (d > 0 && !adj[d][0]) return false;\n            n_adj_c_square[d]++;\n        } else {\n            // Outside the grid is considered color 0.\n            n_adj_c_square[0]++;\n        }\n    }\n\n    // Color 0 must remain connected. To ensure this, every component of color 0 squares\n    // must touch the boundary. Changing (r, c_col) to 0 only maintains this if it already \n    // touches the boundary or an existing 0-square.\n    if (n_adj_c_square[0] == 0) return false;\n\n    // Adjacency relationships between all pairs of colors (including color 0) must be identical.\n    for (int d = 0; d <= m; d++) {\n        if (d == color) continue;\n        if (adj[color][d]) {\n            int new_count_adj_color_d = count_adj[color][d] - n_adj_c_square[d];\n            // Adjacency between ward 'color' and color 0 is maintained if there's either \n            // another existing edge to 0, or if one of the ward's squares becomes adjacent\n            // to the new 0 at (r, c_col).\n            if (d == 0) new_count_adj_color_d += n_adj_c_square[color];\n            if (new_count_adj_color_d <= 0) return false;\n        }\n    }\n\n    // Ward 'color' must remain a single connected set of squares.\n    static vector<pair<int, int>> neighbors;\n    neighbors.clear();\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == color) {\n            neighbors.push_back({ni, nj});\n        }\n    }\n\n    if (neighbors.size() > 1) {\n        visit_token++;\n        static vector<pair<int, int>> q;\n        q.clear();\n        q.push_back(neighbors[0]);\n        visited[neighbors[0].first][neighbors[0].second] = visit_token;\n        visited[r][c_col] = visit_token; // Act as a barrier during BFS\n        int head = 0;\n        while(head < q.size()){\n            pair<int, int> curr = q[head++];\n            for(int k=0; k<4; k++){\n                int ni = curr.first + dx[k], nj = curr.second + dy[k];\n                if(ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == color && visited[ni][nj] != visit_token){\n                    visited[ni][nj] = visit_token;\n                    q.push_back({ni, nj});\n                }\n            }\n        }\n        // If not all same-color neighbors are reachable from one another, connectivity is broken.\n        for (size_t i = 1; i < neighbors.size(); i++) {\n            if (visited[neighbors[i].first][neighbors[i].second] != visit_token) return false;\n        }\n    }\n\n    return true;\n}\n\n// Perform the change and update the adjacency edge counts.\nvoid change_to_0(int r, int c_col, int n, int m) {\n    int color = grid[r][c_col];\n    int n_adj_c_square[M_MAX + 1] = {0};\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c_col + dy[k];\n        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n            n_adj_c_square[grid[ni][nj]]++;\n        } else {\n            n_adj_c_square[0]++;\n        }\n    }\n\n    for (int d = 0; d <= m; d++) {\n        if (n_adj_c_square[d] > 0) {\n            count_adj[color][d] -= n_adj_c_square[d];\n            count_adj[d][color] -= n_adj_c_square[d];\n            count_adj[0][d] += n_adj_c_square[d];\n            count_adj[d][0] += n_adj_c_square[d];\n        }\n    }\n    grid[r][c_col] = 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Record original adjacencies between colors.\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (is_on_boundary(i, j, n)) {\n                adj[grid[i][j]][0] = true;\n                adj[0][grid[i][j]] = true;\n            }\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k], nj = j + dy[k];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    if (grid[i][j] != grid[ni][nj]) {\n                        adj[grid[i][j]][grid[ni][nj]] = true;\n                        adj[grid[ni][nj]][grid[i][j]] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Pre-calculate the number of adjacent edges between color pairs.\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k], nj = j + dy[k];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    count_adj[grid[i][j]][grid[ni][nj]]++;\n                } else {\n                    count_adj[grid[i][j]][0]++;\n                    count_adj[0][grid[i][j]]++;\n                }\n            }\n        }\n    }\n\n    // Iteratively try to replace squares with color 0.\n    vector<int> square_indices(n * n);\n    iota(square_indices.begin(), square_indices.end(), 0);\n    mt19937 rng(42);\n\n    auto start_time = chrono::steady_clock::now();\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) break;\n\n        shuffle(square_indices.begin(), square_indices.end(), rng);\n        bool changed_in_this_pass = false;\n        for (int idx : square_indices) {\n            int r = idx / n;\n            int c = idx % n;\n            if (grid[r][c] > 0 && can_remove(r, c, n, m)) {\n                change_to_0(r, c, n, m);\n                changed_in_this_pass = true;\n            }\n        }\n        if (!changed_in_this_pass) break;\n    }\n\n    // Output final grid.\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 <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Strategy:\n * 1. Initial Sorting (Phase 1): Perform an initial partial or full sort of the items\n *    using MergeSort within a query limit. Each comparison provides a constraint \n *    on the relative weights of two items.\n * 2. Weight Estimation (Phase 2): Estimate the weights of items based on the\n *    order statistics of an exponential distribution. Refine these estimates iteratively.\n * 3. Set Balancing & Querying (Phase 3): Construct balanced sets using current weight estimates.\n *    Perform queries to compare sets. If a query contradicts the current estimates, \n *    adjust the estimated weights (hat_w) using an iterative relaxation method \n *    (similar to Isotonic Regression) to satisfy both set and item-level constraints.\n * 4. Final Partition: Output the best partition found using the refined weight estimates.\n */\n\nint N, D, Q;\nint q_count = 0;\n\nstruct Constraint {\n    vector<int> L, R;\n    int res; // 1 if weight(L) > weight(R), -1 if weight(L) < weight(R), 0 if equal\n};\n\nstruct ItemConstraint {\n    int small, large;\n};\n\nvector<Constraint> set_constraints;\nvector<ItemConstraint> item_constraints;\n\n// Wrapper for the balance query. Synchronizes output and input.\nchar query(const vector<int>& L, const vector<int>& R) {\n    if (q_count >= Q) return '=';\n    q_count++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res;\n    if (!(cin >> res)) exit(0);\n    return res;\n}\n\n// Partial MergeSort logic to build initial constraints and ordering.\nvoid merge(vector<int>& arr, int l, int m, int r, int Q_limit) {\n    vector<int> left(arr.begin() + l, arr.begin() + m);\n    vector<int> right(arr.begin() + m, arr.begin() + r);\n    int i = 0, j = 0, k = l;\n    while (i < (int)left.size() && j < (int)right.size()) {\n        if (q_count < Q_limit) {\n            char res = query({left[i]}, {right[j]});\n            if (res == '<') {\n                item_constraints.push_back({left[i], right[j]});\n                arr[k++] = left[i++];\n            } else if (res == '>') {\n                item_constraints.push_back({right[j], left[i]});\n                arr[k++] = right[j++];\n            } else {\n                arr[k++] = left[i++];\n            }\n        } else {\n            if (left[i] < right[j]) arr[k++] = left[i++];\n            else arr[k++] = right[j++];\n        }\n    }\n    while (i < (int)left.size()) arr[k++] = left[i++];\n    while (j < (int)right.size()) arr[k++] = right[j++];\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r, int Q_limit) {\n    if (r - l <= 1) return;\n    int m = l + (r - l) / 2;\n    merge_sort(arr, l, m, Q_limit);\n    merge_sort(arr, m, r, Q_limit);\n    merge(arr, l, m, r, Q_limit);\n}\n\n// Iterative weight adjustment algorithm to satisfy all recorded constraints.\nvoid update_weights(vector<double>& hat_w, const vector<int>& sorted_items) {\n    int n_constraints = (int)set_constraints.size() + (int)item_constraints.size() + N;\n    // Scale iterations based on constraint count to stay within time limit.\n    int iters = 40000 / n_constraints;\n    if (iters < 5) iters = 5;\n    if (iters > 100) iters = 100;\n\n    for (int iter = 0; iter < iters; iter++) {\n        // Enforce set-comparison constraints (L > R or L < R).\n        for (auto& c : set_constraints) {\n            double sumL = 0, sumR = 0;\n            for (int idx : c.L) sumL += hat_w[idx];\n            for (int idx : c.R) sumR += hat_w[idx];\n            if (c.res == 1 && sumL <= sumR) {\n                double delta = (sumR - sumL + 10.0) / (c.L.size() + c.R.size());\n                for (int idx : c.L) hat_w[idx] += delta;\n                for (int idx : c.R) hat_w[idx] -= delta;\n            } else if (c.res == -1 && sumL >= sumR) {\n                double delta = (sumL - sumR + 10.0) / (c.L.size() + c.R.size());\n                for (int idx : c.R) hat_w[idx] += delta;\n                for (int idx : c.L) hat_w[idx] -= delta;\n            }\n        }\n        // Enforce pairwise item comparison constraints discovered during sorting.\n        for (auto& ic : item_constraints) {\n            if (hat_w[ic.small] > hat_w[ic.large]) {\n                double avg = (hat_w[ic.small] + hat_w[ic.large]) / 2.0;\n                hat_w[ic.small] = hat_w[ic.large] = avg;\n            }\n        }\n        // Maintain a rough global ordering based on the MergeSort sequence.\n        for (int i = 0; i < N - 1; i++) {\n            if (hat_w[sorted_items[i]] > hat_w[sorted_items[i+1]]) {\n                double avg = (hat_w[sorted_items[i]] + hat_w[sorted_items[i+1]]) / 2.0;\n                hat_w[sorted_items[i]] = hat_w[sorted_items[i+1]] = avg;\n            }\n        }\n        for (int i = 0; i < N; i++) if (hat_w[i] < 1.0) hat_w[i] = 1.0;\n    }\n}\n\n// Heuristic multi-way partitioner (LPT + Hill Climbing refinement).\nvector<vector<int>> solve_partition(const vector<double>& hat_w) {\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    sort(indices.begin(), indices.end(), [&](int a, int b) {\n        return hat_w[a] > hat_w[b];\n    });\n\n    vector<vector<int>> sets(D);\n    vector<double> set_sums(D, 0);\n    for (int idx : indices) {\n        int best_s = 0;\n        for (int j = 1; j < D; j++) if (set_sums[j] < set_sums[best_s]) best_s = j;\n        sets[best_s].push_back(idx);\n        set_sums[best_s] += hat_w[idx];\n    }\n\n    mt19937 rng(123);\n    for (int i = 0; i < 2000; i++) {\n        int a = rng() % D, b = rng() % D;\n        if (a == b) continue;\n        \n        // Potential move\n        if (sets[a].size() > 1) {\n            int idx_in_a = rng() % sets[a].size();\n            int item = sets[a][idx_in_a];\n            double new_sum_a = set_sums[a] - hat_w[item];\n            double new_sum_b = set_sums[b] + hat_w[item];\n            if (abs(new_sum_a - new_sum_b) < abs(set_sums[a] - set_sums[b])) {\n                set_sums[a] = new_sum_a;\n                set_sums[b] = new_sum_b;\n                sets[b].push_back(item);\n                sets[a].erase(sets[a].begin() + idx_in_a);\n                continue;\n            }\n        }\n        // Potential swap\n        if (!sets[a].empty() && !sets[b].empty()) {\n            int ia = rng() % sets[a].size(), ib = rng() % sets[b].size();\n            int item_a = sets[a][ia], item_b = sets[b][ib];\n            double new_sum_a = set_sums[a] - hat_w[item_a] + hat_w[item_b];\n            double new_sum_b = set_sums[b] - hat_w[item_b] + hat_w[item_a];\n            if (abs(new_sum_a - new_sum_b) < abs(set_sums[a] - set_sums[b])) {\n                set_sums[a] = new_sum_a;\n                set_sums[b] = new_sum_b;\n                swap(sets[a][ia], sets[b][ib]);\n            }\n        }\n    }\n    return sets;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n\n    // Initial item sorting phase using a significant portion of Q.\n    int Q_sort = min(Q - D, 800);\n    if (Q_sort < 0) Q_sort = 0;\n    merge_sort(items, 0, N, Q_sort);\n\n    vector<double> hat_w(N);\n    double cur_h = 0;\n    // Initialization using expected order statistics of the exponential distribution.\n    for (int i = 0; i < N; i++) {\n        cur_h += 100000.0 / (N - i);\n        hat_w[items[i]] = cur_h;\n    }\n\n    mt19937 rng(456);\n    // Active query loop to refine weight estimates.\n    while (q_count < Q) {\n        auto sets = solve_partition(hat_w);\n        vector<int> s_idx(D);\n        iota(s_idx.begin(), s_idx.end(), 0);\n        sort(s_idx.begin(), s_idx.end(), [&](int a, int b) {\n            double sum_a = 0, sum_b = 0;\n            for (int x : sets[a]) sum_a += hat_w[x];\n            for (int x : sets[b]) sum_b += hat_w[x];\n            return sum_a < sum_b;\n        });\n\n        int a, b;\n        // Selection strategy: focus on adjacent sets to refine close estimates,\n        // or extreme sets to detect significant weight outliers.\n        if (rng() % 10 < 7) {\n            int i = rng() % (D - 1);\n            a = s_idx[i]; b = s_idx[i+1];\n        } else {\n            a = s_idx[0]; b = s_idx[D - 1];\n        }\n\n        char res_char = query(sets[a], sets[b]);\n        int res = (res_char == '>' ? 1 : (res_char == '<' ? -1 : 0));\n        set_constraints.push_back({sets[a], sets[b], res});\n        // Limit constraint memory to maintain performance.\n        if (set_constraints.size() > 250) set_constraints.erase(set_constraints.begin());\n        \n        update_weights(hat_w, items);\n    }\n\n    // Final result calculation.\n    auto final_sets = solve_partition(hat_w);\n    vector<int> d(N);\n    for (int i = 0; i < D; i++) {\n        for (int x : final_sets[i]) d[x] = i;\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 <algorithm>\n#include <climits>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * The problem involves moving cardboard boxes divided into several stacks to carry them out in \n * ascending order (1, 2, ..., n). Each move of k boxes costs k+1 energy. The objective is to\n * minimize the total energy expenditure within 5000 operations.\n * \n * Our refined approach uses a greedy simulation with varying heuristic parameters, exploring\n * the parameter space through randomized trials to find the sequence of operations with the \n * lowest energy.\n */\n\n// Move represents either a relocation of a block of boxes to another stack (i > 0)\n// or carrying out a box (i = 0).\nstruct Move {\n    int v, i;\n};\n\n// State stores the current configuration of boxes in stacks and handles simulation of operations.\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<int> box_to_stack;\n    vector<Move> moves;\n    long long energy;\n\n    State(int n, int m, const vector<vector<int>>& initial_stacks) \n        : n(n), m(m), stacks(initial_stacks), energy(0) {\n        box_to_stack.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            for (int v : stacks[i]) {\n                box_to_stack[v] = i;\n            }\n        }\n    }\n\n    // Moves box v and all boxes currently above it to the specified destination stack.\n    void move_block(int v, int dest_stack_idx) {\n        int src_stack_idx = box_to_stack[v];\n        if (src_stack_idx == dest_stack_idx) return;\n\n        auto& src_stack = stacks[src_stack_idx];\n        auto& dest_stack = stacks[dest_stack_idx];\n\n        int pos = -1;\n        for (int i = 0; i < (int)src_stack.size(); ++i) {\n            if (src_stack[i] == v) {\n                pos = i;\n                break;\n            }\n        }\n\n        int k = (int)src_stack.size() - pos;\n        energy += (k + 1);\n        moves.push_back({v, dest_stack_idx + 1});\n\n        for (int i = pos; i < (int)src_stack.size(); ++i) {\n            box_to_stack[src_stack[i]] = dest_stack_idx;\n            dest_stack.push_back(src_stack[i]);\n        }\n        src_stack.resize(pos);\n    }\n\n    // Carries out box v, which must be at the top of its stack.\n    void carry_out(int v) {\n        int s_idx = box_to_stack[v];\n        stacks[s_idx].pop_back();\n        moves.push_back({v, 0});\n    }\n};\n\n/**\n * Simulates carrying out all boxes for a set of heuristic parameters.\n * limit: Controls block splitting based on the gap between box numbers.\n * weight_future: Penalty weight for a box that will need future moves due to being blocked.\n * weight_size: Weight penalty based on the current height of the destination stack.\n * empty_val_offset: Heuristic virtual 'top box' value for empty stacks.\n */\nlong long simulate(int n, int m, const vector<vector<int>>& initial_stacks, \n                   int limit, int weight_future, int weight_size, int empty_val_offset, \n                   vector<Move>& out_moves) {\n    State state(n, m, initial_stacks);\n    for (int v = 1; v <= n; ++v) {\n        int s_idx = state.box_to_stack[v];\n        \n        // If box v is not at the top, we must clear the boxes sitting above it.\n        if (state.stacks[s_idx].back() != v) {\n            vector<int> B;\n            auto& s = state.stacks[s_idx];\n            int pos = -1;\n            for (int i = 0; i < (int)s.size(); ++i) {\n                if (s[i] == v) { pos = i; break; }\n            }\n            for (int i = pos + 1; i < (int)s.size(); ++i) {\n                B.push_back(s[i]);\n            }\n\n            // Split the boxes above v into sub-blocks that are \"well-ordered\" (decreasing order).\n            vector<vector<int>> sub_blocks;\n            if (!B.empty()) {\n                vector<int> current_S = {B[0]};\n                for (int i = 1; i < (int)B.size(); ++i) {\n                    // Split if order is violated (increasing) or gap is too large.\n                    if (B[i-1] < B[i] || B[i-1] - B[i] > limit) {\n                        sub_blocks.push_back(current_S);\n                        current_S = {B[i]};\n                    } else {\n                        current_S.push_back(B[i]);\n                    }\n                }\n                sub_blocks.push_back(current_S);\n            }\n\n            // Move each sub-block (top-to-bottom) to the stack with the lowest heuristic penalty.\n            for (int i = (int)sub_blocks.size() - 1; i >= 0; --i) {\n                const auto& S = sub_blocks[i];\n                int bottom_v = S[0];\n                int best_d = -1;\n                long long min_score = LLONG_MAX;\n                \n                for (int d = 0; d < m; ++d) {\n                    if (d == s_idx) continue;\n                    \n                    int top_v = state.stacks[d].empty() ? (n + empty_val_offset) : state.stacks[d].back();\n                    long long score = 0;\n                    \n                    // Prefer stacks where the top box is larger than the incoming block's bottom box.\n                    if (top_v > bottom_v) {\n                        score += (top_v - bottom_v);\n                    } else {\n                        score += 200; \n                    }\n                    \n                    // Penalty for boxes in the block that will eventually need to be moved again.\n                    for (int b : S) {\n                        for (int x : state.stacks[d]) {\n                            if (x < b) {\n                                score += weight_future;\n                                break;\n                            }\n                        }\n                    }\n                    score += (long long)state.stacks[d].size() * weight_size;\n                    \n                    if (score < min_score) {\n                        min_score = score;\n                        best_d = d;\n                    }\n                }\n                state.move_block(bottom_v, best_d);\n            }\n        }\n        state.carry_out(v);\n        if (state.moves.size() > 5000) return LLONG_MAX;\n    }\n    out_moves = state.moves;\n    return state.energy;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> initial_stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int b; cin >> b;\n            initial_stacks[i].push_back(b);\n        }\n    }\n\n    long long min_energy = LLONG_MAX;\n    vector<Move> best_moves;\n\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Heuristic parameter ranges for exploration.\n    uniform_int_distribution<int> dist_limit(10, 120);\n    uniform_int_distribution<int> dist_future(20, 100);\n    uniform_int_distribution<int> dist_size(1, 15);\n    uniform_int_distribution<int> dist_empty(0, 150);\n\n    // Initial trials with baseline parameters.\n    vector<int> initial_l = {20, 30, 40, 60, 100};\n    for (int l : initial_l) {\n        vector<Move> current_moves;\n        long long energy = simulate(n, m, initial_stacks, l, 50, 5, 50, current_moves);\n        if (energy < min_energy) {\n            min_energy = energy;\n            best_moves = current_moves;\n        }\n    }\n\n    // Run randomized simulations until just before the time limit.\n    while (true) {\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1900) {\n            break;\n        }\n        \n        int l = dist_limit(rng);\n        int wf = dist_future(rng);\n        int ws = dist_size(rng);\n        int eo = dist_empty(rng);\n        \n        vector<Move> current_moves;\n        long long energy = simulate(n, m, initial_stacks, l, wf, ws, eo, current_moves);\n        if (energy < min_energy) {\n            min_energy = energy;\n            best_moves = current_moves;\n        }\n    }\n\n    // Output the operation sequence with the lowest total energy.\n    for (const auto& move : best_moves) {\n        cout << move.v << \" \" << move.i << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n// Maximum size of the board as per problem description\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\n\nstruct Edge {\n    int u, v;\n};\n\n// Global structures to store the adjacency list and edges of the graph\nvector<Edge> all_edges;\nbool is_in_tree[MAXN * MAXN][MAXN * MAXN];\nint parent_in_tree[MAXN * MAXN];\nint subtree_size[MAXN * MAXN];\nvector<int> tree_adj[MAXN * MAXN];\n\n// Perform DFS to compute subtree sizes for each node in the spanning tree\nvoid dfs_size(int u, int p) {\n    parent_in_tree[u] = p;\n    subtree_size[u] = 1;\n    for (int next_u : tree_adj[u]) {\n        if (next_u != p) {\n            dfs_size(next_u, u);\n            subtree_size[u] += subtree_size[next_u];\n        }\n    }\n}\n\n// Calculate the quality score of the current spanning tree based on dirtiness and subtree distribution.\n// The average dirtiness S is related to the sum of squares of the gaps between visits to each square.\n// For a DFS tour on a spanning tree, the gaps between visits to node u are twice the sizes of the \n// components formed by removing u from the tree.\nlong long compute_total_score() {\n    long long total = 0;\n    int total_nodes = N * N;\n    for (int u = 0; u < total_nodes; ++u) {\n        long long node_sum_s2 = 0;\n        for (int next_u : tree_adj[u]) {\n            if (next_u == parent_in_tree[u]) {\n                // The size of the component \"above\" node u\n                int s = total_nodes - subtree_size[u];\n                node_sum_s2 += (long long)s * s;\n            } else {\n                // The size of the subtree rooted at node u\n                int s = subtree_size[next_u];\n                node_sum_s2 += (long long)s * s;\n            }\n        }\n        total += (long long)d[u / N][u % N] * node_sum_s2;\n    }\n    return total;\n}\n\n// Helper to find the path from a given node to the root (0,0) in the tree\nvector<int> get_path_to_root(int u) {\n    vector<int> path;\n    while (u != -1) {\n        path.push_back(u);\n        u = parent_in_tree[u];\n    }\n    return path;\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read problem input\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\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    // Identify all possible edges between grid squares not separated by a wall\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = (i + 1) * N + j;\n                all_edges.push_back({u, vv});\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = i * N + (j + 1);\n                all_edges.push_back({u, vv});\n            }\n        }\n    }\n\n    // Generate an initial random spanning tree using Kruskal's algorithm\n    mt19937 rng(42);\n    vector<Edge> edges = all_edges;\n    shuffle(edges.begin(), edges.end(), rng);\n    vector<int> dsu(N * N);\n    for (int i = 0; i < N * N; ++i) dsu[i] = i;\n    auto dsu_find = [&](auto self, int i) -> int {\n        return dsu[i] == i ? i : dsu[i] = self(self, dsu[i]);\n    };\n    for (auto& e : edges) {\n        int root_u = dsu_find(dsu_find, e.u);\n        int root_v = dsu_find(dsu_find, e.v);\n        if (root_u != root_v) {\n            dsu[root_u] = root_v;\n            is_in_tree[e.u][e.v] = is_in_tree[e.v][e.u] = true;\n            tree_adj[e.u].push_back(e.v);\n            tree_adj[e.v].push_back(e.u);\n        }\n    }\n\n    // Initial score of the spanning tree\n    dfs_size(0, -1);\n    long long current_score = compute_total_score();\n\n    // Simulated Annealing parameters\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    const double TIME_LIMIT = 1.9; // Target time limit for SA process\n    double start_temp = 1e7;\n    double end_temp = 1e3;\n\n    // Run Simulated Annealing to optimize the spanning tree structure\n    while (true) {\n        // Occasionally check elapsed time\n        if (iterations % 256 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n        }\n        iterations++;\n\n        // Select a non-tree edge and add it to form a cycle\n        int e_idx = uniform_int_distribution<int>(0, all_edges.size() - 1)(rng);\n        Edge e_in = all_edges[e_idx];\n        if (is_in_tree[e_in.u][e_in.v]) continue;\n\n        // Trace paths to find the cycle formed by adding e_in\n        vector<int> path_u = get_path_to_root(e_in.u);\n        vector<int> path_v = get_path_to_root(e_in.v);\n        int iu = path_u.size() - 1, iv = path_v.size() - 1;\n        while (iu >= 0 && iv >= 0 && path_u[iu] == path_v[iv]) {\n            iu--; iv--;\n        }\n        vector<Edge> cycle;\n        for (int i = 0; i <= iu; ++i) cycle.push_back({path_u[i], parent_in_tree[path_u[i]]});\n        for (int i = 0; i <= iv; ++i) cycle.push_back({path_v[i], parent_in_tree[path_v[i]]});\n        cycle.push_back({e_in.u, e_in.v});\n\n        // Select a random edge from the cycle to remove, maintaining a spanning tree\n        int e_out_idx = uniform_int_distribution<int>(0, cycle.size() - 2)(rng);\n        Edge e_out = cycle[e_out_idx];\n\n        // Perform the edge swap (Remove e_out, Add e_in)\n        is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = false;\n        tree_adj[e_out.u].erase(remove(tree_adj[e_out.u].begin(), tree_adj[e_out.u].end(), e_out.v), tree_adj[e_out.u].end());\n        tree_adj[e_out.v].erase(remove(tree_adj[e_out.v].begin(), tree_adj[e_out.v].end(), e_out.u), tree_adj[e_out.v].end());\n        is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = true;\n        tree_adj[e_in.u].push_back(e_in.v);\n        tree_adj[e_in.v].push_back(e_in.u);\n\n        // Recompute sizes and the new tree's score\n        dfs_size(0, -1);\n        long long next_score = compute_total_score();\n\n        // SA Acceptance Criteria\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n        double progress = min(1.0, elapsed / TIME_LIMIT);\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        if (next_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - next_score) / T)) {\n            current_score = next_score;\n        } else {\n            // Revert swap if not accepted\n            is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = false;\n            tree_adj[e_in.u].erase(remove(tree_adj[e_in.u].begin(), tree_adj[e_in.u].end(), e_in.v), tree_adj[e_in.u].end());\n            tree_adj[e_in.v].erase(remove(tree_adj[e_in.v].begin(), tree_adj[e_in.v].end(), e_in.u), tree_adj[e_in.v].end());\n            is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = true;\n            tree_adj[e_out.u].push_back(e_out.v);\n            tree_adj[e_out.v].push_back(e_out.u);\n            dfs_size(0, -1);\n        }\n    }\n\n    // Generate the final cleaning tour by performing a DFS on the optimized spanning tree.\n    string tour = \"\";\n    auto get_dir = [&](int u, int v) {\n        int r1 = u / N, c1 = u % N;\n        int r2 = v / N, c2 = v % N;\n        if (r1 < r2) return 'D';\n        if (r1 > r2) return 'U';\n        if (c1 < c2) return 'R';\n        return 'L';\n    };\n    auto dfs_tour_gen = [&](auto self, int u, int p) -> void {\n        for (int next_u : tree_adj[u]) {\n            if (next_u != p) {\n                tour += get_dir(u, next_u);\n                self(self, next_u, u);\n                tour += get_dir(next_u, u);\n            }\n        }\n    };\n    dfs_tour_gen(dfs_tour_gen, 0, -1);\n\n    // Output the resulting cleaning route\n    cout << tour << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We are typing on a 15x15 keyboard to form a superstring containing all 200 lucky words.\n * - Each operation (typing a key) costs Manhattan distance + 1.\n * - The number of operations is limited to 5000, and we want to minimize the total cost.\n * - This is essentially a variation of the Shortest Superstring Problem combined with a TSP-like distance cost.\n *\n * Algorithm Strategy:\n * 1. Precompute the maximum possible overlap between every pair of lucky strings.\n * 2. Precompute the minimum typing cost for suffixes of strings given starting key positions.\n * 3. Use these precomputed costs to define a TSP distance matrix that prioritizes string overlaps.\n * 4. Solve the TSP using a combination of a Greedy Initial Path and Simulated Annealing (2-opt).\n * 5. Construct the resulting superstring from the TSP order.\n * 6. Use dynamic programming to choose the optimal grid position for each character in the superstring to minimize total distance.\n */\n\nint N = 15, M = 200;\nint si, sj;\nvector<string> A;\nvector<string> T_str;\nvector<int> pos_of_char[26];\n\n// Distance function: Manhattan distance + 1\ninline int dist(int p1, int p2) {\n    return abs(p1 / 15 - p2 / 15) + abs(p1 % 15 - p2 % 15) + 1;\n}\n\n// Function to calculate the maximum overlap between string a and string b\nint get_overlap(const string& a, const string& b) {\n    for (int o = 4; o >= 1; --o) {\n        bool match = true;\n        for (int i = 0; i < o; ++i) {\n            if (a[5 - o + i] != b[i]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return o;\n    }\n    return 0;\n}\n\nint min_cost_table[6][200][225];\ndouble d[200][200];\ndouble d_start[200];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read Input\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    A.resize(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    T_str.resize(M);\n    for (int i = 0; i < M; ++i) cin >> T_str[i];\n\n    // Map each character to its positions on the 15x15 grid\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            pos_of_char[A[i][j] - 'A'].push_back(i * 15 + j);\n        }\n    }\n\n    // Precompute minimum typing cost for all possible suffixes starting from any grid position\n    for (int j = 0; j < M; ++j) {\n        for (int pos = 0; pos < 225; ++pos) min_cost_table[5][j][pos] = 0;\n        for (int k = 4; k >= 0; --k) {\n            int char_idx = T_str[j][k] - 'A';\n            for (int pos = 0; pos < 225; ++pos) {\n                int best = 1e9;\n                for (int next_pos : pos_of_char[char_idx]) {\n                    best = min(best, dist(pos, next_pos) + min_cost_table[k + 1][j][next_pos]);\n                }\n                min_cost_table[k][j][pos] = best;\n            }\n        }\n    }\n\n    // Precompute TSP distance matrix d[i][j] for transitions between strings\n    // d[i][j] prioritizes overlaps (using a large weight) and adds average Manhattan cost\n    for (int i = 0; i < M; ++i) {\n        int last_char_idx = T_str[i][4] - 'A';\n        for (int j = 0; j < M; ++j) {\n            int o = get_overlap(T_str[i], T_str[j]);\n            double avg = 0;\n            for (int pos : pos_of_char[last_char_idx]) {\n                avg += min_cost_table[o][j][pos];\n            }\n            avg /= pos_of_char[last_char_idx].size();\n            d[i][j] = (double)(5 - o) * 1000.0 + avg;\n        }\n        d_start[i] = min_cost_table[0][i][si * 15 + sj];\n    }\n\n    // Generate Greedy initial path for TSP\n    vector<int> p(M);\n    vector<bool> used(M, false);\n    int curr = -1;\n    double min_d_start = 1e18;\n    for (int i = 0; i < M; ++i) {\n        if (d_start[i] < min_d_start) {\n            min_d_start = d_start[i];\n            curr = i;\n        }\n    }\n    p[0] = curr;\n    used[curr] = true;\n    for (int i = 1; i < M; ++i) {\n        int next_v = -1;\n        double best_v = 1e18;\n        for (int j = 0; j < M; ++j) {\n            if (!used[j] && d[p[i - 1]][j] < best_v) {\n                best_v = d[p[i - 1]][j];\n                next_v = j;\n            }\n        }\n        p[i] = next_v;\n        used[next_v] = true;\n    }\n\n    // Scoring function for the current path\n    auto get_total_cost = [&](const vector<int>& path) {\n        double cost = d_start[path[0]];\n        for (int i = 0; i < M - 1; ++i) cost += d[path[i]][path[i + 1]];\n        return cost;\n    };\n\n    double current_cost = get_total_cost(p);\n    double best_ever_cost = current_cost;\n    vector<int> best_p = p;\n\n    // Simulated Annealing to optimize the TSP order\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    for (int iter = 0; ; ++iter) {\n        // Run until near the time limit (1.85 seconds)\n        if (iter % 1000 == 0) {\n            auto now = chrono::steady_clock::now();\n            long long elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > 1850) break;\n        }\n\n        int i = uniform_int_distribution<int>(0, M - 1)(rng);\n        int j = uniform_int_distribution<int>(0, M - 1)(rng);\n        if (i == j) continue;\n        if (i > j) swap(i, j);\n\n        // Calculate the new cost if segment p[i...j] is reversed\n        double new_cost = current_cost;\n        if (i == 0) {\n            new_cost -= d_start[p[0]];\n            new_cost += d_start[p[j]];\n        } else {\n            new_cost -= d[p[i - 1]][p[i]];\n            new_cost += d[p[i - 1]][p[j]];\n        }\n        if (j < M - 1) {\n            new_cost -= d[p[j]][p[j + 1]];\n            new_cost += d[p[i]][p[j + 1]];\n        }\n        // Transitions within the reversed segment\n        for (int k = i; k < j; ++k) {\n            new_cost -= d[p[k]][p[k + 1]];\n            new_cost += d[p[k + 1]][p[k]];\n        }\n\n        // Accept move if better, or with probability based on SA temperature\n        if (new_cost < current_cost) {\n            current_cost = new_cost;\n            reverse(p.begin() + i, p.begin() + j + 1);\n            if (current_cost < best_ever_cost) {\n                best_ever_cost = current_cost;\n                best_p = p;\n            }\n        } else {\n            auto now = chrono::steady_clock::now();\n            long long elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            double temp = 30.0 * (1.0 - (double)elapsed / 1850.0);\n            if (temp > 0 && uniform_real_distribution<double>(0, 1)(rng) < exp((current_cost - new_cost) / temp)) {\n                current_cost = new_cost;\n                reverse(p.begin() + i, p.begin() + j + 1);\n            }\n        }\n    }\n    p = best_p;\n\n    // Construct the superstring S using the optimized TSP order\n    string S = T_str[p[0]];\n    for (int i = 1; i < M; ++i) {\n        int o = get_overlap(T_str[p[i - 1]], T_str[p[i]]);\n        S += T_str[p[i]].substr(o);\n    }\n\n    // Map each character of S to its possible positions on the keyboard\n    vector<vector<int>> pos_list;\n    for (char c : S) pos_list.push_back(pos_of_char[c - 'A']);\n\n    // Dynamic Programming to find the path of grid coordinates that minimizes cost\n    int L = S.size();\n    vector<vector<int>> dp_vals(L);\n    vector<vector<int>> parent(L);\n    for (int k = 0; k < L; ++k) {\n        dp_vals[k].assign(pos_list[k].size(), 2000000000);\n        parent[k].assign(pos_list[k].size(), -1);\n    }\n\n    int start_pos_val = si * 15 + sj;\n    for (int i = 0; i < (int)pos_list[0].size(); ++i) {\n        dp_vals[0][i] = dist(start_pos_val, pos_list[0][i]);\n    }\n\n    for (int k = 1; k < L; ++k) {\n        for (int i = 0; i < (int)pos_list[k].size(); ++i) {\n            int curr_pos = pos_list[k][i];\n            for (int j = 0; j < (int)pos_list[k - 1].size(); ++j) {\n                int prev_pos = pos_list[k - 1][j];\n                int cost_val = dp_vals[k - 1][j] + dist(prev_pos, curr_pos);\n                if (cost_val < dp_vals[k][i]) {\n                    dp_vals[k][i] = cost_val;\n                    parent[k][i] = j;\n                }\n            }\n        }\n    }\n\n    // Reconstruct the optimal path from DP table\n    int best_idx = 0;\n    int min_total_cost = 2000000000;\n    for (int i = 0; i < (int)pos_list[L - 1].size(); ++i) {\n        if (dp_vals[L - 1][i] < min_total_cost) {\n            min_total_cost = dp_vals[L - 1][i];\n            best_idx = i;\n        }\n    }\n\n    vector<int> final_path(L);\n    for (int k = L - 1; k >= 0; --k) {\n        final_path[k] = pos_list[k][best_idx];\n        best_idx = parent[k][best_idx];\n    }\n\n    // Output the sequence of coordinates\n    for (int pos : final_path) {\n        cout << pos / 15 << \" \" << pos % 15 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int r, c;\n};\n\nstruct Polyomino {\n    int id;\n    int d;\n    vector<Point> ps;\n    vector<vector<Point>> positions;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<pair<vector<int>, int>> queries;\nvector<pair<Point, int>> drills;\nvector<vector<vector<int>>> W; // W[field_idx][pos_idx][query_idx]\n\ndouble normal_cdf(double x) {\n    return 0.5 * erfc(-x * M_SQRT1_2);\n}\n\ndouble get_prob(int k, int v_sum, int v_obs) {\n    if (k == 1) return (v_sum == v_obs) ? 1.0 : 1e-18;\n    double mu = (k - v_sum) * eps + v_sum * (1.0 - eps);\n    double sigma = sqrt((double)k * eps * (1.0 - eps));\n    if (v_obs == 0) {\n        return max(1e-18, normal_cdf((0.5 - mu) / sigma));\n    } else {\n        return max(1e-18, normal_cdf((v_obs + 0.5 - mu) / sigma) - normal_cdf((v_obs - 0.5 - mu) / sigma));\n    }\n}\n\ndouble get_log_prob(int k, int v_sum, int v_obs) {\n    return log(get_prob(k, v_sum, v_obs));\n}\n\nstruct Config {\n    vector<int> pos_idx;\n    vector<int> v_sums;\n    vector<vector<int>> grid_v;\n    double log_prob;\n\n    Config() : pos_idx(M), v_sums(), grid_v(N, vector<int>(N, 0)), log_prob(0) {}\n\n    void compute_all() {\n        for (int i = 0; i < N; ++i) fill(grid_v[i].begin(), grid_v[i].end(), 0);\n        for (int i = 0; i < M; ++i) {\n            for (const auto& p : oil_fields[i].positions[pos_idx[i]]) {\n                grid_v[p.r][p.c]++;\n            }\n        }\n        v_sums.assign(queries.size(), 0);\n        log_prob = 0;\n        for (size_t q = 0; q < queries.size(); ++q) {\n            for (int k = 0; k < M; ++k) {\n                v_sums[q] += W[k][pos_idx[k]][q];\n            }\n            log_prob += get_log_prob(queries[q].first.size(), v_sums[q], queries[q].second);\n        }\n        for (const auto& d : drills) {\n            if (grid_v[d.first.r][d.first.c] != d.second) log_prob -= 1e6;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> eps)) return 0;\n    oil_fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int d; cin >> d; oil_fields[i].d = d;\n        vector<Point> ps(d);\n        int max_r = 0, max_c = 0;\n        for (int j = 0; j < d; ++j) {\n            cin >> ps[j].r >> ps[j].c;\n            max_r = max(max_r, ps[j].r);\n            max_c = max(max_c, ps[j].c);\n        }\n        oil_fields[i].ps = ps;\n        for (int r = 0; r <= N - 1 - max_r; ++r) {\n            for (int c = 0; c <= N - 1 - max_c; ++c) {\n                vector<Point> pos;\n                for (const auto& p : ps) pos.push_back({p.r + r, p.c + c});\n                oil_fields[i].positions.push_back(pos);\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    for (int i = 0; i < 2 * N; ++i) {\n        vector<int> S;\n        for (int j = 0; j < N * N; ++j) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < 0.5) S.push_back(j);\n        }\n        if (S.size() < 2) { S.push_back(0); S.push_back(1); }\n        cout << \"q \" << S.size();\n        for (int idx : S) cout << \" \" << idx / N << \" \" << idx % N;\n        cout << endl;\n        int resp; cin >> resp;\n        queries.push_back({S, resp});\n    }\n\n    W.assign(M, vector<vector<int>>());\n    for (int i = 0; i < M; ++i) {\n        W[i].assign(oil_fields[i].positions.size(), vector<int>(queries.size(), 0));\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            vector<vector<bool>> is_in_pos(N, vector<bool>(N, false));\n            for (const auto& pt : oil_fields[i].positions[p]) is_in_pos[pt.r][pt.c] = true;\n            for (size_t q = 0; q < queries.size(); ++q) {\n                for (int idx : queries[q].first) {\n                    if (is_in_pos[idx / N][idx % N]) W[i][p][q]++;\n                }\n            }\n        }\n    }\n\n    const int num_samples = 400;\n    vector<Config> samples(num_samples);\n    for (int i = 0; i < num_samples; ++i) {\n        for (int j = 0; j < M; ++j) {\n            samples[i].pos_idx[j] = uniform_int_distribution<int>(0, (int)oil_fields[j].positions.size() - 1)(rng);\n        }\n        samples[i].compute_all();\n    }\n\n    for (int iter = 0; iter < 2 * N * N; ++iter) {\n        for (int i = 0; i < num_samples; ++i) {\n            for (int step = 0; step < 30; ++step) {\n                int m = uniform_int_distribution<int>(0, M - 1)(rng);\n                int old_pos = samples[i].pos_idx[m];\n                int new_pos = uniform_int_distribution<int>(0, (int)oil_fields[m].positions.size() - 1)(rng);\n                if (old_pos == new_pos) continue;\n\n                double old_lp = samples[i].log_prob;\n                for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]--;\n                for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]++;\n                \n                double new_lp = 0;\n                vector<int> old_v_sums = samples[i].v_sums;\n                for (size_t q = 0; q < queries.size(); ++q) {\n                    samples[i].v_sums[q] = samples[i].v_sums[q] - W[m][old_pos][q] + W[m][new_pos][q];\n                    new_lp += get_log_prob(queries[q].first.size(), samples[i].v_sums[q], queries[q].second);\n                }\n                for (const auto& d : drills) {\n                    if (samples[i].grid_v[d.first.r][d.first.c] != d.second) new_lp -= 1e6;\n                }\n                \n                if (new_lp > old_lp || uniform_real_distribution<double>(0, 1)(rng) < exp(new_lp - old_lp)) {\n                    samples[i].log_prob = new_lp;\n                    samples[i].pos_idx[m] = new_pos;\n                } else {\n                    for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]--;\n                    for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]++;\n                    samples[i].v_sums = old_v_sums;\n                }\n            }\n        }\n\n        vector<vector<double>> p(N, vector<double>(N, 0));\n        for (int i = 0; i < num_samples; ++i) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) if (samples[i].grid_v[r][c] > 0) p[r][c] += 1.0;\n            }\n        }\n\n        bool confident = true;\n        vector<Point> guess_set;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p[r][c] /= num_samples;\n                if (p[r][c] > 0.5) guess_set.push_back({r, c});\n                if (p[r][c] > 0.01 && p[r][c] < 0.99) confident = false;\n            }\n        }\n\n        if (confident || iter > N * N) {\n            cout << \"a \" << guess_set.size();\n            for (const auto& pt : guess_set) cout << \" \" << pt.r << \" \" << pt.c;\n            cout << endl;\n            int resp; if (!(cin >> resp)) break;\n            if (resp == 1) break;\n        }\n\n        double max_var = -1; Point best_p = {0, 0};\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                double var = p[r][c] * (1.0 - p[r][c]);\n                if (var > max_var) { max_var = var; best_p = {r, c}; }\n            }\n        }\n\n        cout << \"q 1 \" << best_p.r << \" \" << best_p.c << endl;\n        int resp; if (!(cin >> resp)) break;\n        drills.push_back({best_p, resp});\n        for (int i = 0; i < num_samples; ++i) samples[i].compute_all();\n    }\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <bitset>\n\nusing namespace std;\n\n// The size of the event hall grid.\nconst int MAXW = 1000;\n\n// Struct to hold rectangle coordinates: top-left (r1, c1) and bottom-right (r2, c2).\nstruct Rectangle {\n    int r1, c1, r2, c2;\n};\n\nint W, D, N;\nlong long a[50][50];\n\n// Bitset representing a line of segments to efficiently calculate changes in partitions.\ntypedef bitset<MAXW> BitLine;\n\nstruct DayConfig {\n    BitLine H[MAXW + 1]; // Horizontal partition segments\n    BitLine V[MAXW + 1]; // Vertical partition segments\n};\n\n// Calculates the length of partitions installed/removed between day d-1 and day d.\nlong long calculate_Ld(const DayConfig& prev, const DayConfig& curr) {\n    long long Ld = 0;\n    for (int i = 1; i < W; ++i) {\n        Ld += (prev.H[i] ^ curr.H[i]).count();\n    }\n    for (int i = 0; i < W; ++i) {\n        Ld += (prev.V[i] ^ curr.V[i]).count();\n    }\n    return Ld;\n}\n\n// Generates the partition configuration based on the rectangles assigned for the day.\nDayConfig get_config(const vector<Rectangle>& rects) {\n    DayConfig config;\n    for (const auto& rect : rects) {\n        // Only include horizontal segments that are not on the perimeter of the hall.\n        if (rect.r1 > 0) {\n            for (int j = rect.c1; j < rect.c2; ++j) config.H[rect.r1].set(j);\n        }\n        if (rect.r2 < W) {\n            for (int j = rect.c1; j < rect.c2; ++j) config.H[rect.r2].set(j);\n        }\n        // Only include vertical segments that are not on the perimeter of the hall.\n        if (rect.c1 > 0) {\n            for (int i = rect.r1; i < rect.r2; ++i) config.V[i].set(rect.c1);\n        }\n        if (rect.c2 < W) {\n            for (int i = rect.r1; i < rect.r2; ++i) config.V[i].set(rect.c2);\n        }\n    }\n    return config;\n}\n\n// Computes the total area deficit penalty for a given day.\nlong long calculate_penalty(int d, const vector<Rectangle>& rects) {\n    long long penalty = 0;\n    for (int k = 0; k < N; ++k) {\n        long long area = (long long)(rects[k].r2 - rects[k].r1) * (rects[k].c2 - rects[k].c1);\n        if (a[d][k] > area) {\n            penalty += 100 * (a[d][k] - area);\n        }\n    }\n    return penalty;\n}\n\nint main() {\n    // Standard I/O optimization.\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> W >> D >> N)) return 0;\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a[d][k];\n        }\n    }\n\n    // Precalculate the maximum height needed across all days for a range of consecutive reservations.\n    // This assumes we are dividing reservations into horizontal strips.\n    static int max_A_needed[51][51];\n    for (int p = 0; p < N; ++p) {\n        for (int i = p + 1; i <= N; ++i) {\n            long long max_sum = 0;\n            for (int d = 0; d < D; ++d) {\n                long long s = 0;\n                for (int k = p; k < i; ++k) s += a[d][k];\n                max_sum = max(max_sum, s);\n            }\n            max_A_needed[p][i] = (max_sum + W - 1) / W;\n        }\n    }\n\n    long long best_total_cost = -1;\n    vector<vector<Rectangle>> best_all_rects;\n\n    // Explore several values for the number of horizontal strips R.\n    vector<int> R_to_try;\n    for (int R = 1; R <= N; ++R) {\n        if (R <= 10 || R % 5 == 0 || R == N) R_to_try.push_back(R);\n    }\n\n    for (int R : R_to_try) {\n        // Dynamic programming to determine the best assignment of N reservations into R horizontal strips.\n        // We aim to minimize the sum of heights needed across all strips to handle peak area demand.\n        vector<vector<int>> dp(N + 1, vector<int>(R + 1, 1e9));\n        vector<vector<int>> best_p(N + 1, vector<int>(R + 1, -1));\n        dp[0][0] = 0;\n        for (int j = 1; j <= R; ++j) {\n            for (int i = 1; i <= N; ++i) {\n                for (int p = j - 1; p < i; ++p) {\n                    int h = max_A_needed[p][i];\n                    if (dp[p][j - 1] + h < dp[i][j]) {\n                        dp[i][j] = dp[p][j - 1] + h;\n                        best_p[i][j] = p;\n                    }\n                }\n            }\n        }\n\n        if (dp[N][R] > 1e8) continue;\n\n        // Reconstruct the strip assignments.\n        vector<vector<int>> strips(R);\n        int curr_i = N;\n        for (int j = R; j >= 1; --j) {\n            int p = best_p[curr_i][j];\n            for (int k = p; k < curr_i; ++k) strips[j - 1].push_back(k);\n            curr_i = p;\n        }\n\n        // Secondary DP to determine the actual height Hr for each strip, summing to exactly W,\n        // to minimize the total penalty incurred across all days for this strip configuration.\n        vector<vector<long long>> cost_h(R, vector<long long>(W + 1));\n        for (int r = 0; r < R; ++r) {\n            for (int h = 1; h <= W; ++h) {\n                long long penalty = 0;\n                for (int d = 0; d < D; ++d) {\n                    long long sum_a = 0;\n                    for (int k : strips[r]) sum_a += a[d][k];\n                    if (sum_a > (long long)h * W) {\n                        penalty += 100 * (sum_a - (long long)h * W);\n                    }\n                }\n                cost_h[r][h] = penalty;\n            }\n        }\n\n        vector<vector<long long>> dp2(R + 1, vector<long long>(W + 1, 1e18));\n        vector<vector<int>> best_h(R + 1, vector<int>(W + 1, -1));\n        dp2[0][0] = 0;\n        for (int r = 1; r <= R; ++r) {\n            for (int h = r; h <= W - (R - r); ++h) {\n                for (int hr = 1; h - hr >= r - 1; ++hr) {\n                    long long new_cost = dp2[r - 1][h - hr] + cost_h[r - 1][hr];\n                    if (new_cost < dp2[r][h]) {\n                        dp2[r][h] = new_cost;\n                        best_h[r][h] = hr;\n                    }\n                }\n            }\n        }\n\n        vector<int> Hr(R);\n        int curr_h = W;\n        for (int r = R; r >= 1; --r) {\n            Hr[r - 1] = best_h[r][curr_h];\n            curr_h -= Hr[r - 1];\n        }\n\n        // For the chosen strip height distribution, calculate optimal rectangle widths for each reservation.\n        vector<vector<Rectangle>> all_rects(D, vector<Rectangle>(N));\n        vector<int> y_coords(R + 1, 0);\n        for (int r = 0; r < R; ++r) y_coords[r + 1] = y_coords[r] + Hr[r];\n\n        for (int d = 0; d < D; ++d) {\n            for (int r = 0; r < R; ++r) {\n                int nr = strips[r].size();\n                vector<int> w(nr);\n                for (int k = 0; k < nr; ++k) {\n                    w[k] = max(1LL, (a[d][strips[r][k]] + Hr[r] - 1) / Hr[r]);\n                }\n                int current_sum_w = 0;\n                for (int val : w) current_sum_w += val;\n\n                // Greedy adjustment of widths to fit theHall's width exactly while minimizing penalty.\n                if (current_sum_w > W) {\n                    while (current_sum_w > W) {\n                        int best_k = -1;\n                        long long min_penalty_increase = 1e18;\n                        for (int k = 0; k < nr; ++k) {\n                            if (w[k] > 1) {\n                                long long increase = (long long)a[d][strips[r][k]] - (long long)Hr[r] * (w[k] - 1);\n                                if (increase < 0) increase = 0;\n                                long long current_p = (long long)a[d][strips[r][k]] - (long long)Hr[r] * w[k];\n                                if (current_p < 0) current_p = 0;\n                                long long diff = (increase - current_p) * 100;\n                                if (diff < min_penalty_increase) {\n                                    min_penalty_increase = diff;\n                                    best_k = k;\n                                }\n                            }\n                        }\n                        if (best_k == -1) break;\n                        w[best_k]--;\n                        current_sum_w--;\n                    }\n                } else if (current_sum_w < W) {\n                    while (current_sum_w < W) {\n                        int best_k = -1;\n                        long long max_penalty_reduction = -1;\n                        for (int k = 0; k < nr; ++k) {\n                            long long reduction = min((long long)Hr[r], max(0LL, (long long)a[d][strips[r][k]] - (long long)Hr[r] * w[k]));\n                            if (reduction > max_penalty_reduction) {\n                                max_penalty_reduction = reduction;\n                                best_k = k;\n                            }\n                        }\n                        if (max_penalty_reduction > 0) {\n                            w[best_k]++;\n                            current_sum_w++;\n                        } else {\n                            w[nr - 1] += (W - current_sum_w);\n                            current_sum_w = W;\n                        }\n                    }\n                }\n\n                int curr_x = 0;\n                for (int k = 0; k < nr; ++k) {\n                    all_rects[d][strips[r][k]] = {y_coords[r], curr_x, y_coords[r + 1], curr_x + w[k]};\n                    curr_x += w[k];\n                }\n            }\n        }\n\n        // Calculate the total cost (Penalty + Ld) for this R and Option.\n        long long total_cost = 0;\n        vector<DayConfig> configs(D);\n        for (int d = 0; d < D; ++d) {\n            configs[d] = get_config(all_rects[d]);\n            total_cost += calculate_penalty(d, all_rects[d]);\n            if (d > 0) total_cost += calculate_Ld(configs[d - 1], configs[d]);\n        }\n\n        if (best_total_cost == -1 || total_cost < best_total_cost) {\n            best_total_cost = total_cost;\n            best_all_rects = all_rects;\n        }\n    }\n\n    // Final output of determined rectangles for all days.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_all_rects[d][k].r1 << \" \" << best_all_rects[d][k].c1 << \" \" << best_all_rects[d][k].r2 << \" \" << best_all_rects[d][k].c2 << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <stdint.h>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\n\n// Struct to represent a combination of 0 to 3 stamps\nstruct Combination {\n    int k;                   // Number of stamps in the combination\n    vector<int> ms;          // Indices of the stamps\n    long long s00;           // Sum of values at position (0,0) modulo P\n    uint32_t s[3][3];        // 3x3 array of sums of stamp values modulo P\n};\n\n// State of the board and current search progress\nstruct State {\n    uint32_t board[N][N];\n    int total_k;             // Total number of operations (stamps) used\n    vector<tuple<int, int, int>> ops; // List of operations performed\n    long long current_score; // Sum of the board values modulo P\n\n    // Comparer to sort states by their scores (descending)\n    bool operator>(const State& other) const {\n        return current_score > other.current_score;\n    }\n};\n\n// Struct to store a potential next step for the beam search\nstruct Candidate {\n    int state_idx;           // Index of the parent state in the beam\n    int combi_idx;           // Index of the combination being applied\n    long long score;         // New score after applying the combination\n\n    // Comparer to sort candidates by their scores (descending)\n    bool operator>(const Candidate& other) const {\n        return score > other.score;\n    }\n};\n\n// Inline function to calculate the score of a new state without copying the board\ninline long long calculate_next_score(const State& state, const Combination& combi, int p, int q) {\n    long long next_score = state.current_score;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            uint32_t old_val = state.board[p + i][q + j];\n            uint32_t new_val = old_val + combi.s[i][j];\n            if (new_val >= P) new_val -= P;\n            next_score = next_score - (long long)old_val + (long long)new_val;\n        }\n    }\n    return next_score;\n}\n\nint main() {\n    // Speed up 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    uint32_t a[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    uint32_t s[M][3][3];\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    // Precompute combinations of 0 to 3 stamps\n    vector<Combination> all_combi;\n    \n    // k = 0\n    Combination c0;\n    c0.k = 0; c0.ms = {}; c0.s00 = 0;\n    for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c0.s[i][j] = 0;\n    all_combi.push_back(c0);\n\n    // k = 1\n    for (int m = 0; m < M; ++m) {\n        Combination c;\n        c.k = 1; c.ms = {m}; c.s00 = s[m][0][0];\n        for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c.s[i][j] = s[m][i][j];\n        all_combi.push_back(c);\n    }\n\n    // k = 2\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            Combination c;\n            c.k = 2; c.ms = {m1, m2};\n            c.s00 = (s[m1][0][0] + s[m2][0][0]) % P;\n            for (int i = 0; i < 3; ++i)\n                for (int j = 0; j < 3; ++j)\n                    c.s[i][j] = (s[m1][i][j] + s[m2][i][j]) % P;\n            all_combi.push_back(c);\n        }\n    }\n\n    // k = 3\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            for (int m3 = m2; m3 < M; ++m3) {\n                Combination c;\n                c.k = 3; c.ms = {m1, m2, m3};\n                c.s00 = ( (long long)s[m1][0][0] + s[m2][0][0] + s[m3][0][0] ) % P;\n                for (int i = 0; i < 3; ++i)\n                    for (int j = 0; j < 3; ++j)\n                        c.s[i][j] = ( (long long)s[m1][i][j] + s[m2][i][j] + s[m3][i][j] ) % P;\n                all_combi.push_back(c);\n            }\n        }\n    }\n\n    // Sort combinations by their (0,0) value to efficiently pick best ones\n    sort(all_combi.begin(), all_combi.end(), [](const Combination& a, const Combination& b) {\n        return a.s00 < b.s00;\n    });\n\n    // Beam search initialization\n    State initial_state;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.board[i][j] = a[i][j];\n    initial_state.total_k = 0;\n    initial_state.current_score = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.current_score += a[i][j];\n    initial_state.ops = {};\n\n    vector<State> beam;\n    beam.push_back(initial_state);\n\n    int B = 1000; // Beam size\n    int T = 100;  // Number of top combinations to consider per square per state\n\n    // Row-major iteration through all potential top-left stamp positions\n    for (int p = 0; p <= N - 3; ++p) {\n        for (int q = 0; q <= N - 3; ++q) {\n            vector<Candidate> candidates;\n            candidates.reserve(beam.size() * T);\n\n            for (int state_idx = 0; state_idx < (int)beam.size(); ++state_idx) {\n                const State& current_s = beam[state_idx];\n                uint32_t V = current_s.board[p][q];\n                long long target = P - 1 - V;\n\n                // Use binary search on pre-sorted combinations to find best candidates for the current board square\n                int it_idx = lower_bound(all_combi.begin(), all_combi.end(), target, [](const Combination& c, long long val) {\n                    return c.s00 < val;\n                }) - all_combi.begin();\n\n                int start = it_idx;\n                if (start == (int)all_combi.size() || all_combi[start].s00 > target) {\n                    start--;\n                }\n\n                int found = 0;\n                // Check combinations with s00 <= target in descending order\n                for (int i = start; i >= 0 && found < T; --i) {\n                    if (current_s.total_k + all_combi[i].k <= K) {\n                        candidates.push_back({state_idx, i, calculate_next_score(current_s, all_combi[i], p, q)});\n                        found++;\n                    }\n                }\n                // Check remaining best combinations from the end of the list (where V+s00-P is large)\n                for (int i = (int)all_combi.size() - 1; i > start && found < T; --i) {\n                    if (current_s.total_k + all_combi[i].k <= K) {\n                        candidates.push_back({state_idx, i, calculate_next_score(current_s, all_combi[i], p, q)});\n                        found++;\n                    }\n                }\n            }\n\n            // Keep top B candidates\n            int next_B = min((int)candidates.size(), B);\n            nth_element(candidates.begin(), candidates.begin() + next_B, candidates.end(), greater<Candidate>());\n            candidates.resize(next_B);\n\n            // Construct next beam from selected candidates\n            vector<State> next_beam;\n            next_beam.reserve(next_B);\n            for (const auto& cand : candidates) {\n                State ns = beam[cand.state_idx];\n                const Combination& combi = all_combi[cand.combi_idx];\n                for (int i = 0; i < 3; ++i) {\n                    for (int j = 0; j < 3; ++j) {\n                        uint32_t val = ns.board[p + i][q + j] + combi.s[i][j];\n                        if (val >= P) val -= P;\n                        ns.board[p + i][q + j] = val;\n                    }\n                }\n                ns.total_k += combi.k;\n                for (int m_idx : combi.ms) {\n                    ns.ops.emplace_back(m_idx, p, q);\n                }\n                ns.current_score = cand.score;\n                next_beam.push_back(std::move(ns));\n            }\n            beam = std::move(next_beam);\n        }\n    }\n\n    // Find and output the best solution found\n    long long best_final_score = -1;\n    int best_state_idx = -1;\n    for (int i = 0; i < (int)beam.size(); ++i) {\n        if (beam[i].current_score > best_final_score) {\n            best_final_score = beam[i].current_score;\n            best_state_idx = i;\n        }\n    }\n\n    const State& best_state = beam[best_state_idx];\n    cout << best_state.ops.size() << \"\\n\";\n    for (const auto& op : best_state.ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer's solution for the container terminal problem.\n *\n * Strategy:\n * 1. Bomb all small cranes (cranes 1-4) in Turn 0 to clear the grid.\n * 2. Use the large crane (crane 0) to handle all containers one by one.\n * 3. Crane 0 strategy:\n *    - Priority 1: If a container that is next in order for its dispatch gate is already on the grid,\n *                  pick it up and move it to its dispatch gate.\n *    - Priority 2: If no such container is on the grid, find the most urgent container (smallest index\n *                  that hasn't been dispatched) still in a receiving queue. Move the top container of\n *                  that queue to a buffer square to clear the way.\n * 4. This strategy ensures M1=0 (no inversions), M2=0 (all to correct gates), and M3=0 (all dispatched).\n *    The turns count M0 will be minimized by only moving what's necessary and using shortest paths.\n */\n\nvoid add_move_to_queue(vector<char>& q, int tr, int tc, int& r, int& c) {\n    while (r < tr) { q.push_back('D'); r++; }\n    while (r > tr) { q.push_back('U'); r--; }\n    while (c < tc) { q.push_back('R'); c++; }\n    while (c > tc) { q.push_back('L'); c--; }\n}\n\nint main() {\n    int N_in;\n    if (!(cin >> N_in)) return 0;\n    int N = 5;\n    vector<vector<int>> arrival_queue(5, vector<int>(5));\n    vector<int> gate_of(25);\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            cin >> arrival_queue[i][j];\n            gate_of[arrival_queue[i][j]] = i;\n        }\n    }\n\n    vector<int> current_gate_idx(5, 0);\n    vector<vector<int>> grid(5, vector<int>(5, -1));\n    vector<int> next_needed(5);\n    for (int i = 0; i < 5; i++) next_needed[i] = 5 * i;\n    vector<bool> is_dispatched(25, false);\n    int dispatched_count = 0;\n\n    int crane_r = 0, crane_c = 0;\n    int held = -1;\n    vector<string> actions(5, \"\");\n    vector<char> action_queue;\n\n    for (int t = 0; t < 10000; ++t) {\n        // Step 1: Arrival of containers\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][0] == -1 && current_gate_idx[i] < 5) {\n                // Containers arrive only if square is empty and no crane is holding there\n                if (!(crane_r == i && crane_c == 0 && held != -1)) {\n                    grid[i][0] = arrival_queue[i][current_gate_idx[i]];\n                    current_gate_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        char act0 = '.';\n        if (t == 0) {\n            // Initial moves: move Crane 0 out of (0,0) and bomb others\n            act0 = 'R';\n            for (int i = 1; i < 5; i++) actions[i] += 'B';\n        } else {\n            if (action_queue.empty()) {\n                // Determine next task for Crane 0\n                if (held == -1) {\n                    int target_r = -1, target_c = -1;\n                    // Check if a needed container is already on the grid (arrival gates or buffer)\n                    for (int r = 0; r < 5; ++r) {\n                        for (int c = 0; c < 4; ++c) {\n                            if (grid[r][c] != -1) {\n                                int val = grid[r][c];\n                                if (val == next_needed[val / 5]) {\n                                    target_r = r; target_c = c; break;\n                                }\n                            }\n                        }\n                        if (target_r != -1) break;\n                    }\n\n                    if (target_r != -1) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, target_r, target_c, r, c);\n                        action_queue.push_back('P');\n                    } else {\n                        // Find most urgent container still in a queue and clear its path\n                        int urgent_v = 100;\n                        int clear_gate = -1;\n                        for (int i = 0; i < 5; ++i) {\n                            if (next_needed[i] < 5 * (i + 1)) {\n                                int v = next_needed[i];\n                                bool is_av = !is_dispatched[v];\n                                if (is_av) {\n                                    for (int r1 = 0; r1 < 5; r1++)\n                                        for (int c1 = 0; c1 < 4; c1++)\n                                            if (grid[r1][c1] == v) is_av = false;\n                                }\n                                if (is_av && v < urgent_v) {\n                                    urgent_v = v;\n                                    clear_gate = gate_of[v];\n                                }\n                            }\n                        }\n                        if (clear_gate != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, clear_gate, 0, r, c);\n                            if (grid[clear_gate][0] != -1) action_queue.push_back('P');\n                            else action_queue.push_back('.'); // Wait for container arrival\n                        }\n                    }\n                } else {\n                    // Holding a container: either dispatch it or move it to a buffer\n                    if (held == next_needed[held / 5]) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, held / 5, 4, r, c);\n                        action_queue.push_back('Q');\n                    } else {\n                        int br = -1, bc = -1;\n                        for (int c = 1; c <= 3; ++c) {\n                            for (int r = 0; r < 5; ++r) {\n                                if (grid[r][c] == -1) { br = r; bc = c; break; }\n                            }\n                            if (br != -1) break;\n                        }\n                        if (br != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, br, bc, r, c);\n                            action_queue.push_back('Q');\n                        } else {\n                            action_queue.push_back('.');\n                        }\n                    }\n                }\n            }\n\n            if (!action_queue.empty()) {\n                act0 = action_queue.front();\n                action_queue.erase(action_queue.begin());\n            }\n            for (int i = 1; i < 5; i++) actions[i] += '.';\n        }\n\n        actions[0] += act0;\n        if (act0 == 'P') { held = grid[crane_r][crane_c]; grid[crane_r][crane_c] = -1; }\n        else if (act0 == 'Q') {\n            int val = held;\n            grid[crane_r][crane_c] = val;\n            if (crane_c == 4) next_needed[val / 5]++;\n            held = -1;\n        } else if (act0 == 'U') crane_r--;\n        else if (act0 == 'D') crane_r++;\n        else if (act0 == 'L') crane_c--;\n        else if (act0 == 'R') crane_c++;\n\n        // Step 3: Container dispatch\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][4] != -1) {\n                is_dispatched[grid[i][4]] = true;\n                grid[i][4] = -1;\n                dispatched_count++;\n            }\n        }\n\n        if (dispatched_count == 25) break;\n    }\n\n    // Output all actions, padding with '.' as necessary\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) max_len = max(max_len, (int)actions[i].length());\n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) actions[i] += '.';\n        cout << actions[i] << endl;\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nconst int N = 20;\n\n/**\n * State struct maintains the grid status, truck position, current load,\n * total cost, and the sequence of operations.\n */\nstruct State {\n    int h[N][N];\n    int r, c;\n    long long L;\n    long long cost;\n    vector<string> ops;\n\n    State(const int initial_h[N][N]) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                h[i][j] = initial_h[i][j];\n            }\n        }\n        r = 0; c = 0; L = 0; cost = 0;\n    }\n\n    void load(int d) {\n        if (d <= 0) return;\n        h[r][c] -= d;\n        L += d;\n        cost += d;\n        ops.push_back(\"+\" + to_string(d));\n    }\n\n    void unload(int d) {\n        if (d <= 0) return;\n        h[r][c] += d;\n        L -= d;\n        cost += d;\n        ops.push_back(\"-\" + to_string(d));\n    }\n\n    void move(char dir) {\n        if (dir == 'U') r--;\n        else if (dir == 'D') r++;\n        else if (dir == 'L') c--;\n        else if (dir == 'R') c++;\n        cost += (100 + L);\n        ops.push_back(string(1, dir));\n    }\n};\n\nstruct Target {\n    int r, c;\n};\n\n/**\n * Solve function runs a randomized greedy approach with heuristic parameters.\n */\nvoid solve(const int initial_h[N][N], double dist_pow, double soil_pow, double load_penalty, double sink_weight, vector<string>& best_ops, long long &best_score_overall, mt19937& rng) {\n    State s(initial_h);\n    vector<Target> targets;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (initial_h[i][j] != 0) targets.push_back({i, j});\n        }\n    }\n\n    double soil_pow_table[101];\n    for (int i = 1; i <= 100; ++i) soil_pow_table[i] = pow((double)i, soil_pow);\n\n    double dist_pow_table[41];\n    for (int i = 0; i <= 40; ++i) dist_pow_table[i] = pow((double)i, dist_pow);\n\n    while (!targets.empty() && s.ops.size() < 99990) {\n        // Load or unload at the current square if applicable\n        if (s.h[s.r][s.c] > 0) {\n            s.load(s.h[s.r][s.c]);\n        } else if (s.h[s.r][s.c] < 0 && s.L > 0) {\n            s.unload((int)min((long long)abs(s.h[s.r][s.c]), s.L));\n        }\n\n        // Clean up the list of squares that still need work\n        for (int k = 0; k < (int)targets.size(); ++k) {\n            if (s.h[targets[k].r][targets[k].c] == 0) {\n                targets[k] = targets.back();\n                targets.pop_back();\n                k--;\n            }\n        }\n\n        if (targets.empty()) break;\n\n        // Determine the next square to move towards using a heuristic score\n        int tr = -1, tc = -1;\n        double min_val = 1e25;\n        for (const auto& t : targets) {\n            int dist = abs(s.r - t.r) + abs(s.c - t.c);\n            double val;\n            if (s.h[t.r][t.c] > 0) {\n                val = (dist_pow_table[dist] * (100.0 + (double)s.L) / soil_pow_table[s.h[t.r][t.c]]) * (1.0 + (double)s.L * load_penalty);\n            } else {\n                int can_unload = (int)min((long long)abs(s.h[t.r][t.c]), s.L);\n                if (can_unload == 0) continue;\n                val = (dist_pow_table[dist] * (100.0 + (double)s.L) / soil_pow_table[can_unload]) * sink_weight;\n            }\n            if (val < min_val) {\n                min_val = val;\n                tr = t.r; tc = t.c;\n            }\n        }\n\n        // Safeguard for unreachable states (should not occur if sum of heights is 0)\n        if (tr == -1) {\n            const auto& t = targets[rng() % targets.size()];\n            tr = t.r; tc = t.c;\n        }\n\n        // Move one step toward the target square, preferring cells that need processing\n        int dr = tr - s.r;\n        int dc = tc - s.c;\n        vector<char> possible;\n        if (dr > 0) possible.push_back('D'); else if (dr < 0) possible.push_back('U');\n        if (dc > 0) possible.push_back('R'); else if (dc < 0) possible.push_back('L');\n\n        char move_dir = possible[0];\n        if (possible.size() > 1) {\n            bool found = false;\n            for (char m : possible) {\n                int nr = s.r + (m == 'D' ? 1 : (m == 'U' ? -1 : 0));\n                int nc = s.c + (m == 'R' ? 1 : (m == 'L' ? -1 : 0));\n                if (s.h[nr][nc] != 0) {\n                    move_dir = m; found = true; break;\n                }\n            }\n            if (!found) move_dir = possible[rng() % 2];\n        }\n        s.move(move_dir);\n    }\n\n    // Evaluate total cost including penalties for incomplete leveling\n    long long diff = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s.h[i][j] != 0) diff += 100LL * abs(s.h[i][j]) + 10000LL;\n        }\n    }\n    if (s.L > 0) diff += 10000LL;\n\n    if (s.cost + diff < best_score_overall) {\n        best_score_overall = s.cost + diff;\n        best_ops = s.ops;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n; cin >> n;\n    int h[N][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    auto start_time = chrono::steady_clock::now();\n    long long best_score_overall = 8e18;\n    vector<string> best_ops;\n    mt19937 rng(1337);\n\n    // Initial trials with several fixed parameter sets\n    solve(h, 1.5, 1.0, 0.0005, 0.5, best_ops, best_score_overall, rng);\n    solve(h, 2.0, 0.5, 0.0010, 0.8, best_ops, best_score_overall, rng);\n    solve(h, 1.2, 1.2, 0.0000, 1.0, best_ops, best_score_overall, rng);\n\n    // Iteratively run solve with randomized parameters within the time limit\n    uniform_real_distribution<double> dist_dist(1.0, 2.5);\n    uniform_real_distribution<double> soil_dist(0.1, 1.5);\n    uniform_real_distribution<double> load_dist(0.0, 0.002);\n    uniform_real_distribution<double> sink_dist(0.1, 1.5);\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1850) {\n        solve(h, dist_dist(rng), soil_dist(rng), load_dist(rng), sink_dist(rng), best_ops, best_score_overall, rng);\n    }\n\n    for (const string& op : best_ops) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We have an N x N grid (N=6). Initially 60 seeds, each with an M=15 vector of values.\n * T=10 turns. Each turn:\n * 1. Plant 36 seeds in the grid.\n * 2. 60 new seeds are generated from the 60 grid edges (horizontal and vertical).\n * 3. Each criterion in the new seed is randomly inherited from its two parent seeds.\n * \n * Objective: Maximize the maximum total sum of values in any seed after Turn 10.\n * \n * Strategy:\n * - Each turn, identify seeds with the highest potential to produce better offspring.\n * - Arrange the seeds on the grid such that adjacent seeds complement each other.\n * - Use Simulated Annealing (SA) to optimize the grid arrangement and seed selection.\n */\n\nconst int N = 6;\nconst int M = 15;\nconst int T_MAX = 10;\nconst int SEED_COUNT = 60;\nconst int PLANT_COUNT = 36;\nconst int UNUSED_COUNT = SEED_COUNT - PLANT_COUNT;\n\nstruct Seed {\n    int x[M];\n    int v;\n};\n\n// Potential matrix: P2[i][j] stores a heuristic for the quality of offspring from seeds i and j.\nlong long P2[SEED_COUNT][SEED_COUNT];\n\n/**\n * Precompute the heuristic potential of offspring from every pair of available seeds.\n * A good potential offspring is one that can inherit high values from either parent.\n */\nvoid precompute_potentials(const vector<Seed>& seeds) {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = 0; j < SEED_COUNT; ++j) {\n            if (i == j) {\n                P2[i][j] = 0;\n                continue;\n            }\n            long long potential_sum = 0;\n            for (int l = 0; l < M; ++l) {\n                potential_sum += max(seeds[i].x[l], seeds[j].x[l]);\n            }\n            // Use squared potential to favor pairs that can produce exceptionally strong offspring.\n            P2[i][j] = potential_sum * potential_sum;\n        }\n    }\n}\n\nint main() {\n    // Standard IO speedup.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, m_in, t_in;\n    if (!(cin >> n_in >> m_in >> t_in)) return 0;\n\n    vector<Seed> seeds(SEED_COUNT);\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    mt19937 rng(1337);\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    for (int t = 0; t < T_MAX; ++t) {\n        precompute_potentials(seeds);\n\n        // Initial selection: Ensure seeds with the best individual criteria and top total sums are considered.\n        vector<int> initial_selection;\n        vector<bool> is_sel(SEED_COUNT, false);\n        for (int l = 0; l < M; ++l) {\n            int best_s = -1, max_val = -1;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (seeds[i].x[l] > max_val) {\n                    max_val = seeds[i].x[l];\n                    best_s = i;\n                }\n            }\n            if (!is_sel[best_s]) {\n                is_sel[best_s] = true;\n                initial_selection.push_back(best_s);\n            }\n        }\n        vector<int> sorted_indices(SEED_COUNT);\n        iota(sorted_indices.begin(), sorted_indices.end(), 0);\n        sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n        for (int idx : sorted_indices) {\n            if (initial_selection.size() < PLANT_COUNT && !is_sel[idx]) {\n                is_sel[idx] = true;\n                initial_selection.push_back(idx);\n            }\n        }\n\n        // Sort squares by neighbor count (central squares first) to place best seeds.\n        vector<pair<int, int>> squares;\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) squares.push_back({r, c});\n        sort(squares.begin(), squares.end(), [](pair<int, int> a, pair<int, int> b) {\n            auto get_n = [](pair<int, int> p) {\n                return (p.first > 0) + (p.first < N - 1) + (p.second > 0) + (p.second < N - 1);\n            };\n            return get_n(a) > get_n(b);\n        });\n\n        int grid[N][N];\n        int off_grid[UNUSED_COUNT];\n        for (int i = 0; i < PLANT_COUNT; ++i) {\n            grid[squares[i].first][squares[i].second] = initial_selection[i];\n        }\n        int cur_off = 0;\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            bool used = false;\n            for (int s : initial_selection) if (s == i) used = true;\n            if (!used) off_grid[cur_off++] = i;\n        }\n\n        // Calculate initial score.\n        auto get_total_score = [&]() {\n            long long score = 0;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (r + 1 < N) score += P2[grid[r][c]][grid[r + 1][c]];\n                    if (c + 1 < N) score += P2[grid[r][c]][grid[r][c + 1]];\n                }\n            }\n            return score;\n        };\n\n        long long current_score = get_total_score();\n        long long best_overall_score = current_score;\n        int best_grid[N][N];\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n\n        // Simulated Annealing.\n        auto start_turn = chrono::steady_clock::now();\n        int iterations = 0;\n        const double TURN_TIME_LIMIT = 0.185; \n        while (true) {\n            if ((iterations & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - start_turn).count();\n                if (elapsed > TURN_TIME_LIMIT) break;\n                // Temperature schedule.\n                double temp = 12000.0 * (1.0 - elapsed / TURN_TIME_LIMIT);\n                \n                // Hill Climbing / SA loop.\n                for (int step = 0; step < 1024; ++step) {\n                    int move_type = rng() % 2;\n                    if (move_type == 0) {\n                        // Swap two seeds in the grid.\n                        int r1 = rng() % N, c1 = rng() % N;\n                        int r2 = rng() % N, c2 = rng() % N;\n                        if (r1 == r2 && c1 == c2) continue;\n\n                        long long old_l = 0;\n                        for (int i = 0; i < 4; ++i) {\n                            int nr1 = r1 + dr[i], nc1 = c1 + dc[i];\n                            if (nr1 >= 0 && nr1 < N && nc1 >= 0 && nc1 < N && !(nr1 == r2 && nc1 == c2))\n                                old_l += P2[grid[r1][c1]][grid[nr1][nc1]];\n                            int nr2 = r2 + dr[i], nc2 = c2 + dc[i];\n                            if (nr2 >= 0 && nr2 < N && nc2 >= 0 && nc2 < N && !(nr2 == r1 && nc2 == c1))\n                                old_l += P2[grid[r2][c2]][grid[nr2][nc2]];\n                        }\n\n                        swap(grid[r1][c1], grid[r2][c2]);\n\n                        long long new_l = 0;\n                        for (int i = 0; i < 4; ++i) {\n                            int nr1 = r1 + dr[i], nc1 = c1 + dc[i];\n                            if (nr1 >= 0 && nr1 < N && nc1 >= 0 && nc1 < N && !(nr1 == r2 && nc1 == c2))\n                                new_l += P2[grid[r1][c1]][grid[nr1][nc1]];\n                            int nr2 = r2 + dr[i], nc2 = c2 + dc[i];\n                            if (nr2 >= 0 && nr2 < N && nc2 >= 0 && nc2 < N && !(nr2 == r1 && nc2 == c1))\n                                new_l += P2[grid[r2][c2]][grid[nr2][nc2]];\n                        }\n\n                        long long diff = new_l - old_l;\n                        if (diff >= 0 || (temp > 0.1 && exp((double)diff / temp) > (double)rng() / rng.max())) {\n                            current_score += diff;\n                            if (current_score > best_overall_score) {\n                                best_overall_score = current_score;\n                                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n                            }\n                        } else {\n                            swap(grid[r1][c1], grid[r2][c2]);\n                        }\n                    } else {\n                        // Swap a grid seed with an unused seed.\n                        int r1 = rng() % N, c1 = rng() % N;\n                        int idx = rng() % UNUSED_COUNT;\n\n                        long long old_l = 0;\n                        for (int i = 0; i < 4; ++i) {\n                            int nr1 = r1 + dr[i], nc1 = c1 + dc[i];\n                            if (nr1 >= 0 && nr1 < N && nc1 >= 0 && nc1 < N)\n                                old_l += P2[grid[r1][c1]][grid[nr1][nc1]];\n                        }\n\n                        swap(grid[r1][c1], off_grid[idx]);\n\n                        long long new_l = 0;\n                        for (int i = 0; i < 4; ++i) {\n                            int nr1 = r1 + dr[i], nc1 = c1 + dc[i];\n                            if (nr1 >= 0 && nr1 < N && nc1 >= 0 && nc1 < N)\n                                new_l += P2[grid[r1][c1]][grid[nr1][nc1]];\n                        }\n\n                        long long diff = new_l - old_l;\n                        if (diff >= 0 || (temp > 0.1 && exp((double)diff / temp) > (double)rng() / rng.max())) {\n                            current_score += diff;\n                            if (current_score > best_overall_score) {\n                                best_overall_score = current_score;\n                                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n                            }\n                        } else {\n                            swap(grid[r1][c1], off_grid[idx]);\n                        }\n                    }\n                }\n            }\n            iterations++;\n        }\n\n        // Output optimized grid.\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                cout << best_grid[r][c] << (c == N - 1 ? \"\" : \" \");\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read offspring seeds for next turn.\n        for (int i = 0; i < SEED_COUNT; i++) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; j++) {\n                if (!(cin >> seeds[i].x[j])) return 0;\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 <cmath>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Takoyaki movement simulation using a robotic arm with multiple fingertips.\n * The arm is structured as a star with several fingers attached to a central root (vertex 0).\n * Each finger is an edge of fixed length. The root can move one square at a time,\n * and each finger can rotate independently.\n */\n\nstruct Takoyaki {\n    int id;\n    int sx, sy, tx, ty;\n    int state; // 0: unpicked, 1: holding, 2: delivered\n    int finger_id;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n\n    // Read the grid configurations\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Identify start and target squares for takoyakis\n    vector<pair<int, int>> S_positions, T_positions;\n    vector<vector<bool>> grid_has_takoyaki(N, vector<bool>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') S_positions.push_back({i, j});\n            if (t_grid[i][j] == '1') T_positions.push_back({i, j});\n            grid_has_takoyaki[i][j] = (s_grid[i][j] == '1');\n        }\n    }\n\n    // Match each initial takoyaki to a target square greedily\n    vector<Takoyaki> takoyakis(M);\n    vector<bool> target_assigned(M, false);\n    for (int i = 0; i < M; ++i) {\n        int best_j = -1, best_dist = 1e9;\n        for (int j = 0; j < M; ++j) {\n            if (!target_assigned[j]) {\n                int dist = abs(S_positions[i].first - T_positions[j].first) + abs(S_positions[i].second - T_positions[j].second);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_j = j;\n                }\n            }\n        }\n        takoyakis[i] = {i, S_positions[i].first, S_positions[i].second, T_positions[best_j].first, T_positions[best_j].second, 0, -1};\n        target_assigned[best_j] = true;\n    }\n\n    // Design the robotic arm: a star with V-1 fingers of various lengths\n    cout << V << \"\\n\";\n    vector<int> finger_lengths(V);\n    vector<int> finger_dirs(V, 0); // Absolute direction: 0:R, 1:D, 2:L, 3:U\n    vector<int> finger_holding(V, -1);\n    for (int i = 1; i < V; ++i) {\n        finger_lengths[i] = min(i, N - 1); // Length between 1 and N-1\n        cout << 0 << \" \" << finger_lengths[i] << \"\\n\";\n    }\n    int rx = 0, ry = 0; // Root current position\n    cout << rx << \" \" << ry << \"\\n\";\n\n    // Row and column changes for the 4 absolute directions\n    int dr[] = {0, 1, 0, -1};\n    int dc[] = {1, 0, -1, 0};\n\n    // Helper function to update direction via rotation\n    auto get_rot_char = [&](int& cur_d, int target_d) {\n        if (cur_d == target_d) return '.';\n        if ((cur_d + 1) % 4 == target_d) { cur_d = (cur_d + 1) % 4; return 'R'; }\n        if ((cur_d + 3) % 4 == target_d) { cur_d = (cur_d + 3) % 4; return 'L'; }\n        cur_d = (cur_d + 1) % 4; return 'R'; // Requires two steps, start with one\n    };\n\n    int delivered_count = 0;\n    int turns = 0;\n    while (delivered_count < M && turns < 100000) {\n        // Find a focal takoyaki and finger to move\n        int focus_j = -1, focus_f = -1;\n        // Check if any finger is already holding a takoyaki\n        for (int j = 0; j < M; ++j) {\n            if (takoyakis[j].state == 1) { // HOLDING\n                focus_j = j; focus_f = takoyakis[j].finger_id; break;\n            }\n        }\n        // If no finger is busy, find an unpicked takoyaki and a free finger\n        if (focus_j == -1) {\n            for (int j = 0; j < M; ++j) {\n                if (takoyakis[j].state == 0) { focus_j = j; break; }\n            }\n            if (focus_j == -1) break; // Everything moved\n            for (int f = 1; f < V; ++f) {\n                if (finger_holding[f] == -1) { focus_f = f; break; }\n            }\n        }\n        // If still no focus finger (all fingers busy), focus on any held takoyaki\n        if (focus_f == -1) {\n            for (int j = 0; j < M; ++j) {\n                if (takoyakis[j].state == 1) {\n                    focus_j = j; focus_f = takoyakis[j].finger_id; break;\n                }\n            }\n        }\n        if (focus_f == -1) break; // Should not happen in this logic\n\n        // Target coordinates for the focus fingertip\n        int tx = (takoyakis[focus_j].state == 0) ? takoyakis[focus_j].sx : takoyakis[focus_j].tx;\n        int ty = (takoyakis[focus_j].state == 0) ? takoyakis[focus_j].sy : takoyakis[focus_j].ty;\n\n        // Choose root target position and finger direction that minimizes root movement\n        int best_path_dist = 1e9, target_rx = -1, target_ry = -1, target_d = -1;\n        for (int d = 0; d < 4; ++d) {\n            int trx = tx - dr[d] * finger_lengths[focus_f];\n            int try_ = ty - dc[d] * finger_lengths[focus_f];\n            if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                int dist = abs(trx - rx) + abs(try_ - ry);\n                if (dist < best_path_dist) {\n                    best_path_dist = dist; target_rx = trx; target_ry = try_; target_d = d;\n                }\n            }\n        }\n\n        // Move the arm and operate fingers until focus takoyaki changes state\n        int focus_initial_state = takoyakis[focus_j].state;\n        while (takoyakis[focus_j].state == focus_initial_state && turns < 100000) {\n            string turn_op = \"\";\n            // 1. Determine root movement\n            if (rx < target_rx) { rx++; turn_op += 'D'; }\n            else if (rx > target_rx) { rx--; turn_op += 'U'; }\n            else if (ry < target_ry) { ry++; turn_op += 'R'; }\n            else if (ry > target_ry) { ry--; turn_op += 'L'; }\n            else turn_op += '.';\n\n            // 2. Determine rotations (rotate focus finger towards target direction)\n            for (int f = 1; f < V; ++f) {\n                if (f == focus_f && (rx != target_rx || ry != target_ry || finger_dirs[f] != target_d)) {\n                    turn_op += get_rot_char(finger_dirs[f], target_d);\n                } else turn_op += '.';\n            }\n\n            // 3. Perform actions (Pick or Drop) for all fingertips\n            string act_part = \".\"; // Action for vertex 0 (never a fingertip)\n            for (int f = 1; f < V; ++f) {\n                int fr = rx + dr[finger_dirs[f]] * finger_lengths[f];\n                int fc = ry + dc[finger_dirs[f]] * finger_lengths[f];\n                bool acted = false;\n                if (fr >= 0 && fr < N && fc >= 0 && fc < N) {\n                    if (finger_holding[f] == -1) {\n                        // Check if current fingertip position has an unpicked takoyaki\n                        for (int j = 0; j < M; ++j) {\n                            if (takoyakis[j].state == 0 && takoyakis[j].sx == fr && takoyakis[j].sy == fc) {\n                                takoyakis[j].state = 1; takoyakis[j].finger_id = f;\n                                finger_holding[f] = j; grid_has_takoyaki[fr][fc] = false;\n                                act_part += 'P'; acted = true; break;\n                            }\n                        }\n                    } else {\n                        // Check if current fingertip position matches the target square for its takoyaki\n                        int j = finger_holding[f];\n                        if (takoyakis[j].tx == fr && takoyakis[j].ty == fc && !grid_has_takoyaki[fr][fc]) {\n                            takoyakis[j].state = 2; finger_holding[f] = -1;\n                            grid_has_takoyaki[fr][fc] = true; delivered_count++;\n                            act_part += 'P'; acted = true;\n                        }\n                    }\n                }\n                if (!acted) act_part += '.';\n            }\n            cout << turn_op << act_part << \"\\n\";\n            turns++;\n            if (delivered_count == M) break;\n            \n            // Re-evaluate if focus is stuck (e.g., target square is occupied)\n            if (rx == target_rx && ry == target_ry && finger_dirs[focus_f] == target_d && takoyakis[focus_j].state == focus_initial_state) {\n                if (takoyakis[focus_j].state == 1 && grid_has_takoyaki[takoyakis[focus_j].tx][takoyakis[focus_j].ty]) break;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int W = 100000;\nconst int G = 101; // Grid size constant for memory management\n\nstruct Point {\n    int x, y;\n};\n\nstruct Result {\n    long long score;\n    vector<pair<int, int>> path;\n    int i_start;\n    bool swapped;\n    vector<int> xs, ys;\n};\n\n/**\n * Calculates the exact perimeter of the x-monotone rectilinear polygon \n * constructed from the given path of vertical intervals in the grid.\n */\nlong long get_perimeter(const vector<pair<int, int>>& path, int i_start, const vector<int>& xs, const vector<int>& ys) {\n    if (path.empty()) return 0;\n    int n = path.size();\n    long long p = 0;\n    // Horizontal edges along the top and bottom of the entire polygon.\n    p += 2LL * (xs[i_start + n] - xs[i_start]);\n    // The vertical edges at the leftmost and rightmost ends.\n    p += (ys[path[0].second + 1] - ys[path[0].first]);\n    p += (ys[path[n - 1].second + 1] - ys[path[n - 1].first]);\n    // Vertical segments needed to connect intervals of adjacent columns.\n    for (int i = 0; i < n - 1; ++i) {\n        p += abs(ys[path[i + 1].first] - ys[path[i].first]);\n        p += abs(ys[path[i + 1].second + 1] - ys[path[i].second + 1]);\n    }\n    return p;\n}\n\n/**\n * Solves the problem by finding an optimal x-monotone rectilinear polygon on a grid.\n * Uses coordinate compression and dynamic programming with connectivity constraints.\n */\nResult solve_with_params(int N, const vector<Point>& macks, const vector<Point>& sards, bool swap_xy, int grid_size, int d_limit) {\n    vector<Point> m = macks, s = sards;\n    // Solve the transposed problem if required to find a y-monotone polygon.\n    if (swap_xy) {\n        for (int i = 0; i < N; ++i) {\n            swap(m[i].x, m[i].y);\n            swap(s[i].x, s[i].y);\n        }\n    }\n\n    // Coordinate compression: select significant coordinates to form the grid.\n    vector<int> X, Y;\n    for (int i = 0; i < N; ++i) {\n        X.push_back(m[i].x); X.push_back(s[i].x);\n        Y.push_back(m[i].y); Y.push_back(s[i].y);\n    }\n    X.push_back(0); X.push_back(100000);\n    Y.push_back(0); Y.push_back(100000);\n    sort(X.begin(), X.end());\n    X.erase(unique(X.begin(), X.end()), X.end());\n    sort(Y.begin(), Y.end());\n    Y.erase(unique(Y.begin(), Y.end()), Y.end());\n\n    vector<int> xs, ys;\n    for (int i = 0; i <= grid_size; ++i) {\n        xs.push_back(X[i * (X.size() - 1) / grid_size]);\n        ys.push_back(Y[i * (Y.size() - 1) / grid_size]);\n    }\n\n    // Distribute fish into the compressed grid.\n    static int cell_score[G][G];\n    for (int i = 0; i < grid_size; ++i)\n        for (int j = 0; j < grid_size; ++j)\n            cell_score[i][j] = 0;\n\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), m[i].x) - xs.begin();\n        if (gx > 0 && (gx == grid_size || xs[gx] > m[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), m[i].y) - ys.begin();\n        if (gy > 0 && (gy == grid_size || ys[gy] > m[i].y)) gy--;\n        if (gx < grid_size && gy < grid_size) cell_score[gx][gy]++;\n    }\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), s[i].x) - xs.begin();\n        if (gx > 0 && (gx == grid_size || xs[gx] > s[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), s[i].y) - ys.begin();\n        if (gy > 0 && (gy == grid_size || ys[gy] > s[i].y)) gy--;\n        if (gx < grid_size && gy < grid_size) cell_score[gx][gy]--;\n    }\n\n    // Prepare vertical prefix sums for efficient column interval score calculation.\n    static int row_sum[G][G + 1];\n    for (int i = 0; i < grid_size; ++i) {\n        row_sum[i][0] = 0;\n        for (int j = 0; j < grid_size; ++j)\n            row_sum[i][j + 1] = row_sum[i][j] + cell_score[i][j];\n    }\n\n    // DP: dp[i][L][R] is the max score (a-b) ending at column i with vertical range [ys[L], ys[R+1]].\n    static long long dp[G][G][G];\n    static pair<short, short> p_table[G][G][G];\n    for (int i = 0; i < grid_size; ++i)\n        for (int L = 0; L < grid_size; ++L)\n            for (int R = L; R < grid_size; ++R)\n                dp[i][L][R] = -100000000;\n\n    for (int i = 0; i < grid_size; ++i) {\n        for (int L = 0; L < grid_size; ++L) {\n            for (int R = L; R < grid_size; ++R) {\n                int cur_col_score = row_sum[i][R + 1] - row_sum[i][L];\n                // Initial Case: A polygon can start as a rectangle in this column.\n                dp[i][L][R] = cur_col_score;\n                p_table[i][L][R] = { -1, -1 };\n                // Extension: Connect current column interval to an overlapping interval in the previous column.\n                if (i > 0) {\n                    for (int L1 = max(0, L - d_limit); L1 <= min(grid_size - 1, L + d_limit); ++L1) {\n                        for (int R1 = max(L1, R - d_limit); R1 <= min(grid_size - 1, R + d_limit); ++R1) {\n                            if (max(L, L1) <= min(R, R1)) { // Connectivity condition\n                                if (dp[i - 1][L1][R1] + cur_col_score > dp[i][L][R]) {\n                                    dp[i][L][R] = dp[i - 1][L1][R1] + cur_col_score;\n                                    p_table[i][L][R] = { (short)L1, (short)R1 };\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Evaluate the best found polygon while ensuring it satisfies the perimeter constraint.\n    long long best_total_score = -1;\n    int bi = -1, bl = -1, br = -1;\n    for (int i = 0; i < grid_size; ++i) {\n        for (int L = 0; L < grid_size; ++L) {\n            for (int R = L; R < grid_size; ++R) {\n                if (dp[i][L][R] > best_total_score) {\n                    vector<pair<int, int>> temp_path;\n                    int ci = i, cl = L, cr = R;\n                    while (ci >= 0 && cl != -1) {\n                        temp_path.push_back({ cl, cr });\n                        auto p = p_table[ci][cl][cr];\n                        cl = p.first; cr = p.second; ci--;\n                    }\n                    reverse(temp_path.begin(), temp_path.end());\n                    if (get_perimeter(temp_path, i - (int)temp_path.size() + 1, xs, ys) <= 400000) {\n                        best_total_score = dp[i][L][R];\n                        bi = i; bl = L; br = R;\n                    }\n                }\n            }\n        }\n    }\n\n    if (bi == -1) return { -1, {}, -1, false, {}, {} };\n\n    vector<pair<int, int>> final_path;\n    int ci = bi, cl = bl, cr = br;\n    while (ci >= 0 && cl != -1) {\n        final_path.push_back({ cl, cr });\n        auto p = p_table[ci][cl][cr];\n        cl = p.first; cr = p.second; ci--;\n    }\n    reverse(final_path.begin(), final_path.end());\n    return { best_total_score, final_path, bi - (int)final_path.size() + 1, swap_xy, xs, ys };\n}\n\n/**\n * Converts the path result into the standard vertex output format.\n */\nvoid output(const Result& res) {\n    if (res.score <= 0) {\n        cout << \"4\\n0 0\\n0 1\\n1 1\\n1 0\" << endl;\n        return;\n    }\n    int n = res.path.size();\n    vector<pair<int, int>> v;\n    // Clockwise construction of vertices from the sequence of y-intervals.\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].first] });\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].second + 1] });\n    for (int i = 0; i < n - 1; ++i) {\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i].second + 1] });\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i + 1].second + 1] });\n    }\n    v.push_back({ res.xs[res.i_start + n], res.ys[res.path[n - 1].second + 1] });\n    v.push_back({ res.xs[res.i_start + n], res.ys[res.path[n - 1].first] });\n    for (int i = n - 1; i > 0; --i) {\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i].first] });\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i - 1].first] });\n    }\n\n    // Invert swapping if the result came from the transposed problem.\n    if (res.swapped) {\n        for (auto& p : v) swap(p.first, p.second);\n    }\n    \n    // Clean up vertices for valid output.\n    vector<pair<int, int>> uv;\n    for (int i = 0; i < (int)v.size(); ++i)\n        if (i == 0 || v[i] != v[i - 1]) uv.push_back(v[i]);\n    if (uv.size() > 1 && uv.front() == uv.back()) uv.pop_back();\n\n    cout << uv.size() << endl;\n    for (auto p : uv) cout << p.first << \" \" << p.second << endl;\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    vector<Point> macks(N), sards(N);\n    for (int i = 0; i < N; ++i) cin >> macks[i].x >> macks[i].y;\n    for (int i = 0; i < N; ++i) cin >> sards[i].x >> sards[i].y;\n\n    Result best_res = { -1, {}, -1, false, {}, {} };\n    // Solve for both x-monotone and y-monotone cases and select the best result.\n    for (bool swap_xy : {false, true}) {\n        Result res = solve_with_params(N, macks, sards, swap_xy, 100, 5);\n        if (res.score > best_res.score) best_res = res;\n    }\n    output(best_res);\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Structure to represent a placed rectangle on the 2D plane\nstruct Rect {\n    long long x, y, w, h;\n    long long xw, yh; // Precalculated x+w and y+h for faster overlap checks\n};\n\n// Structure to represent a packing configuration for N rectangles\nstruct Config {\n    vector<int> r;     // Rotation: 0 (no rotation), 1 (90 degrees rotation)\n    vector<char> d;    // Direction: 'U' (Upward), 'L' (Leftward)\n    vector<int> b;     // Reference rectangle index (-1 or 0 to i-1)\n};\n\nint N, T;\ndouble sigma;\nvector<long long> w_obs, h_obs;\n\n// Timer utility to manage time budget within the 3.0-second limit\nauto start_time = chrono::steady_clock::now();\ndouble elapsed_time() {\n    auto now = chrono::steady_clock::now();\n    return chrono::duration<double>(now - start_time).count();\n}\n\n/**\n * Packs rectangles from index k to N-1 based on the configuration and current rectangle dimensions.\n * Previous placements (0 to k-1) are assumed to be fixed in the `placed` array.\n */\nlong long evaluate(const vector<long long>& w, const vector<long long>& h,\n                   const Config& config, Rect* placed, int k) {\n    for (int i = k; i < N; ++i) {\n        // Determine actual width and height based on rotation\n        long long cur_w = config.r[i] ? h[i] : w[i];\n        long long cur_h = config.r[i] ? w[i] : h[i];\n        long long cur_x, cur_y;\n\n        if (config.d[i] == 'U') {\n            // Place to the right of reference rectangle b[i]\n            cur_x = (config.b[i] == -1) ? 0 : placed[config.b[i]].xw;\n            cur_y = 0;\n            long long cur_x_plus_w = cur_x + cur_w;\n            // Move up until it hits another rectangle or y=0\n            for (int j = 0; j < i; ++j) {\n                if (cur_x < placed[j].xw && placed[j].x < cur_x_plus_w) {\n                    cur_y = max(cur_y, placed[j].yh);\n                }\n            }\n        } else {\n            // Place below the bottom edge of reference rectangle b[i]\n            cur_y = (config.b[i] == -1) ? 0 : placed[config.b[i]].yh;\n            cur_x = 0;\n            long long cur_y_plus_h = cur_y + cur_h;\n            // Move left until it hits another rectangle or x=0\n            for (int j = 0; j < i; ++j) {\n                if (cur_y < placed[j].yh && placed[j].y < cur_y_plus_h) {\n                    cur_x = max(cur_x, placed[j].xw);\n                }\n            }\n        }\n        // Update the placed information for the current rectangle\n        placed[i] = {cur_x, cur_y, cur_w, cur_h, cur_x + cur_w, cur_y + cur_h};\n    }\n\n    // Calculate the bounding box dimensions W and H\n    long long W = 0, H = 0;\n    for (int i = 0; i < N; ++i) {\n        W = max(W, placed[i].xw);\n        H = max(H, placed[i].yh);\n    }\n    return W + H; // We minimize W + H as a proxy for the perimeter-based shipping cost\n}\n\nint main() {\n    // Optimization for fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Initial input reading\n    if (!(cin >> N >> T >> sigma)) return 0;\n    w_obs.resize(N);\n    h_obs.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Random number generator with a fixed seed\n    mt19937 rng(42);\n    Config current_config;\n    current_config.r.assign(N, 0);\n    current_config.d.assign(N, 'U');\n    current_config.b.assign(N, -1);\n\n    // Initial random configuration\n    for (int i = 0; i < N; ++i) {\n        current_config.r[i] = rng() % 2;\n        current_config.d[i] = (rng() % 2) ? 'U' : 'L';\n        current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n    }\n\n    Rect placed[105];\n    long long current_score = evaluate(w_obs, h_obs, current_config, placed, 0);\n\n    // Main loop for T turns\n    for (int t = 0; t < T; ++t) {\n        double turn_start_time = elapsed_time();\n        // Allocate time fairly among remaining turns\n        double turn_time_limit = (2.85 - turn_start_time) / (T - t);\n\n        // Bayesian estimation approach: sample w, h from normal distribution based on measurements\n        vector<long long> w_sample(N), h_sample(N);\n        for (int i = 0; i < N; ++i) {\n            w_sample[i] = max(1LL, (long long)round(normal_distribution<double>((double)w_obs[i], sigma)(rng)));\n            h_sample[i] = max(1LL, (long long)round(normal_distribution<double>((double)h_obs[i], sigma)(rng)));\n        }\n\n        // Occasional random restart to escape local optima over turns\n        if (t > 0 && uniform_real_distribution<double>(0, 1)(rng) < 0.1) {\n            for (int i = 0; i < N; ++i) {\n                current_config.r[i] = rng() % 2;\n                current_config.d[i] = (rng() % 2) ? 'U' : 'L';\n                current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n            }\n        }\n        current_score = evaluate(w_sample, h_sample, current_config, placed, 0);\n\n        Config best_in_turn = current_config;\n        long long best_score_in_turn = current_score;\n\n        // Simulated Annealing parameters\n        double t_start = sigma * 2.0;\n        double t_end = 100.0;\n        \n        while (elapsed_time() - turn_start_time < turn_time_limit) {\n            // Select a random rectangle k and change its placement parameters\n            int k = rng() % N;\n            int old_r = current_config.r[k];\n            char old_d = current_config.d[k];\n            int old_b = current_config.b[k];\n            Rect backup_placed[105];\n            for (int i = k; i < N; ++i) backup_placed[i] = placed[i];\n\n            int type = rng() % 4;\n            if (type == 0) current_config.r[k] = 1 - current_config.r[k];\n            else if (type == 1) current_config.d[k] = (current_config.d[k] == 'U' ? 'L' : 'U');\n            else if (type == 2) current_config.b[k] = (int)(rng() % (k + 1)) - 1;\n            else {\n                current_config.r[k] = 1 - current_config.r[k];\n                current_config.d[k] = (current_config.d[k] == 'U' ? 'L' : 'U');\n                current_config.b[k] = (int)(rng() % (k + 1)) - 1;\n            }\n\n            // Partially re-evaluate the configuration starting from index k\n            long long new_score = evaluate(w_sample, h_sample, current_config, placed, k);\n            double time_ratio = (elapsed_time() - turn_start_time) / turn_time_limit;\n            double temp = t_start * pow(t_end / t_start, time_ratio);\n\n            // Accept or reject based on Metropolis criterion\n            if (new_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - new_score) / temp)) {\n                current_score = new_score;\n                if (new_score < best_score_in_turn) {\n                    best_score_in_turn = new_score;\n                    best_in_turn = current_config;\n                }\n            } else {\n                // Rollback changes if neighbor is rejected\n                current_config.r[k] = old_r;\n                current_config.d[k] = old_d;\n                current_config.b[k] = old_b;\n                for (int i = k; i < N; ++i) placed[i] = backup_placed[i];\n            }\n        }\n\n        // Final output for the current turn\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; ++i) {\n            cout << i << \" \" << best_in_turn.r[i] << \" \" << best_in_turn.d[i] << \" \" << best_in_turn.b[i] << \"\\n\";\n        }\n        cout.flush();\n\n        // Read measured feedback from the environment (W', H')\n        long long W_prime, H_prime;\n        if (!(cin >> W_prime >> H_prime)) break;\n\n        // Use the best found configuration as a starting point for the next turn\n        current_config = best_in_turn;\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// Maximum number of vertices as defined in the problem\nconst int MAXN = 1000;\nint N, M, H_limit;\nint A[MAXN];\nvector<int> adj[MAXN];\nint parent[MAXN];\nvector<int> children[MAXN];\nint depth[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_depth_rel[MAXN];\n\n/**\n * Checks if vertex u is an ancestor of vertex v.\n * Since the tree depth is at most 10, this check runs in O(H_limit).\n */\nbool is_ancestor(int u, int v) {\n    if (u == -1) return false;\n    if (depth[u] > depth[v]) return false;\n    int curr = v;\n    while (curr != -1) {\n        if (curr == u) return true;\n        if (depth[curr] <= depth[u]) break;\n        curr = parent[curr];\n    }\n    return false;\n}\n\n/**\n * Updates the depth of all vertices in the subtree of vertex v recursively.\n */\nvoid update_subtree_depth(int v, int diff) {\n    if (diff == 0) return;\n    depth[v] += diff;\n    for (int child : children[v]) {\n        update_subtree_depth(child, diff);\n    }\n}\n\n/**\n * Recomputes the subtree_sum_A and max_depth_rel for a vertex and its ancestors.\n * Limited to H_limit steps as the trees cannot be deeper than 10.\n */\nvoid update_ancestors(int curr) {\n    int count = 0;\n    while (curr != -1 && count <= 12) {\n        long long sum = A[curr];\n        int mx = 0;\n        for (int child : children[curr]) {\n            sum += subtree_sum_A[child];\n            mx = max(mx, max_depth_rel[child] + 1);\n        }\n        subtree_sum_A[curr] = sum;\n        max_depth_rel[curr] = mx;\n        curr = parent[curr];\n        count++;\n    }\n}\n\n/**\n * Moves vertex v to a new parent new_p. Handles subtree updates and ancestor recalculations.\n */\nvoid move_v(int v, int new_p) {\n    int old_p = parent[v];\n    if (old_p != -1) {\n        auto& cv = children[old_p];\n        for (size_t i = 0; i < cv.size(); ++i) {\n            if (cv[i] == v) {\n                cv[i] = cv.back();\n                cv.pop_back();\n                break;\n            }\n        }\n        update_ancestors(old_p);\n    }\n    \n    parent[v] = new_p;\n    if (new_p != -1) {\n        children[new_p].push_back(v);\n        update_ancestors(new_p);\n    }\n    \n    int old_depth = depth[v];\n    int new_depth = (new_p == -1 ? 0 : depth[new_p] + 1);\n    update_subtree_depth(v, new_depth - old_depth);\n}\n\nint main() {\n    // Standard fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> H_limit)) 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    // Read and ignore vertex coordinates, as they are not needed for the tree logic\n    int x_tmp, y_tmp;\n    for (int i = 0; i < N; ++i) cin >> x_tmp >> y_tmp;\n\n    // Initialization: each node starts as a root of its own tree\n    for (int i = 0; i < N; ++i) {\n        parent[i] = -1;\n        depth[i] = 0;\n        children[i].clear();\n        subtree_sum_A[i] = A[i];\n        max_depth_rel[i] = 0;\n    }\n\n    mt19937 mt(42);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    // Sort vertices by beauty value descending to give higher values more depth in greedy phase\n    sort(order.begin(), order.end(), [&](int i, int j){ return A[i] > A[j]; });\n\n    // Initial Greedy phase to create a better starting point for SA\n    for (int v : order) {\n        int best_p = -1;\n        int max_d = -1;\n        for (int u : adj[v]) {\n            if (!is_ancestor(v, u) && depth[u] + 1 + max_depth_rel[v] <= H_limit) {\n                if (depth[u] > max_d) {\n                    max_d = depth[u];\n                    best_p = u;\n                }\n            }\n        }\n        // If a deeper parent is found, move v there\n        if (best_p != -1 && depth[best_p] + 1 > depth[v]) {\n            move_v(v, best_p);\n        }\n    }\n\n    // Simulated Annealing setup\n    auto start_time = chrono::steady_clock::now();\n    double T_start = 500.0;\n    double T_end = 0.01;\n    double log_T_ratio = log(T_end / T_start);\n    long long iter = 0;\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    double T = T_start;\n\n    // Main SA Loop\n    while (true) {\n        if (iter % 2000 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double t = chrono::duration<double>(current_time - start_time).count();\n            if (t > 1.95) break; // Time limit: 2 seconds\n            T = T_start * exp(log_T_ratio * t / 1.95);\n        }\n        \n        // Randomly pick a vertex and a potential new parent from its neighbors or -1 (root)\n        int v = uniform_int_distribution<int>(0, N - 1)(mt);\n        int neighbor_idx = uniform_int_distribution<int>(0, adj[v].size())(mt);\n        int new_p = (neighbor_idx == (int)adj[v].size()) ? -1 : adj[v][neighbor_idx];\n        \n        if (new_p == parent[v]) {\n            iter++;\n            continue;\n        }\n\n        // Validate the move: cycle check and maximum height constraint\n        if (new_p != -1) {\n            if (is_ancestor(v, new_p)) {\n                iter++;\n                continue;\n            }\n            if (depth[new_p] + 1 + max_depth_rel[v] > H_limit) {\n                iter++;\n                continue;\n            }\n        }\n\n        // Calculate the score change: Delta = (new_h - old_h) * Sum(A_subtree)\n        int old_depth = depth[v];\n        int new_depth = (new_p == -1 ? 0 : depth[new_p] + 1);\n        long long delta = (long long)(new_depth - old_depth) * subtree_sum_A[v];\n\n        // Metropolis acceptance criterion\n        if (delta >= 0 || dist(mt) < exp((double)delta / T)) {\n            move_v(v, new_p);\n        }\n        iter++;\n    }\n\n    // Output the parent array of the constructed forest\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\nconst int N = 20;\n\nstruct Oni {\n    int r, c;\n    vector<int> safe_dirs; // 0:L, 1:R, 2:U, 3:D\n};\n\n// Calculates total operations for a given direction assignment for all Oni.\nint calculate_total_cost(const vector<Oni>& onis, const vector<int>& d, bool rows_last) {\n    int L[N] = {0}, R[N] = {0}, U[N] = {0}, D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        if (d[i] == 0) L[onis[i].r] = max(L[onis[i].r], onis[i].c + 1);\n        else if (d[i] == 1) R[onis[i].r] = max(R[onis[i].r], N - onis[i].c);\n        else if (d[i] == 2) U[onis[i].c] = max(U[onis[i].c], onis[i].r + 1);\n        else if (d[i] == 3) D[onis[i].c] = max(D[onis[i].c], N - onis[i].r);\n    }\n\n    int total_cost = 0;\n    if (rows_last) {\n        // Columns must return to preserve row integrity\n        for (int j = 0; j < N; ++j) {\n            total_cost += 2 * (U[j] + D[j]);\n        }\n        // Rows are last and don't need to return fully\n        for (int i = 0; i < N; ++i) {\n            if (L[i] > 0 && R[i] > 0) total_cost += min(2 * L[i] + R[i], 2 * R[i] + L[i]);\n            else total_cost += max(L[i], R[i]);\n        }\n    } else {\n        // Rows must return to preserve column integrity\n        for (int i = 0; i < N; ++i) {\n            total_cost += 2 * (L[i] + R[i]);\n        }\n        // Columns are last\n        for (int j = 0; j < N; ++j) {\n            if (U[j] > 0 && D[j] > 0) total_cost += min(2 * U[j] + D[j], 2 * D[j] + U[j]);\n            else total_cost += max(U[j], D[j]);\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_in;\n    if (!(cin >> n_in)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    vector<Oni> onis;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                Oni oni; oni.r = i; oni.c = j;\n                bool L_safe = true; for (int k = 0; k < j; ++k) if (board[i][k] == 'o') L_safe = false;\n                if (L_safe) oni.safe_dirs.push_back(0);\n                bool R_safe = true; for (int k = j + 1; k < N; ++k) if (board[i][k] == 'o') R_safe = false;\n                if (R_safe) oni.safe_dirs.push_back(1);\n                bool U_safe = true; for (int k = 0; k < i; ++k) if (board[k][j] == 'o') U_safe = false;\n                if (U_safe) oni.safe_dirs.push_back(2);\n                bool D_safe = true; for (int k = i + 1; k < N; ++k) if (board[k][j] == 'o') D_safe = false;\n                if (D_safe) oni.safe_dirs.push_back(3);\n                onis.push_back(oni);\n            }\n        }\n    }\n\n    if (onis.empty()) return 0;\n\n    mt19937 rng(42);\n    vector<int> current_d(onis.size());\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        current_d[i] = onis[i].safe_dirs[rng() % onis[i].safe_dirs.size()];\n    }\n\n    bool current_rows_last = true;\n    auto evaluate = [&](const vector<int>& d, bool& out_rows_last) {\n        int r_cost = calculate_total_cost(onis, d, true);\n        int c_cost = calculate_total_cost(onis, d, false);\n        if (r_cost <= c_cost) { out_rows_last = true; return r_cost; }\n        else { out_rows_last = false; return c_cost; }\n    };\n\n    int current_cost = evaluate(current_d, current_rows_last);\n    auto start_time = chrono::steady_clock::now();\n    long long iter = 0;\n\n    while (true) {\n        if ((iter & 511) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1900) break;\n        }\n        iter++;\n\n        int k = rng() % onis.size();\n        if (onis[k].safe_dirs.size() <= 1) continue;\n        int old_dir = current_d[k];\n        current_d[k] = onis[k].safe_dirs[rng() % onis[k].safe_dirs.size()];\n        if (current_d[k] == old_dir) continue;\n\n        bool next_rows_last;\n        int next_cost = evaluate(current_d, next_rows_last);\n        if (next_cost <= current_cost) {\n            current_cost = next_cost;\n            current_rows_last = next_rows_last;\n        } else {\n            current_d[k] = old_dir;\n        }\n    }\n\n    int L[N] = {0}, R[N] = {0}, U[N] = {0}, D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        if (current_d[i] == 0) L[onis[i].r] = max(L[onis[i].r], onis[i].c + 1);\n        else if (current_d[i] == 1) R[onis[i].r] = max(R[onis[i].r], N - onis[i].c);\n        else if (current_d[i] == 2) U[onis[i].c] = max(U[onis[i].c], onis[i].r + 1);\n        else if (current_d[i] == 3) D[onis[i].c] = max(D[onis[i].c], N - onis[i].r);\n    }\n\n    if (current_rows_last) {\n        for (int j = 0; j < N; ++j) {\n            if (U[j] > 0 && D[j] > 0) {\n                for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                for (int k = 0; k < U[j] + D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                for (int k = 0; k < D[j]; ++k) cout << \"U \" << j << \"\\n\";\n            } else if (U[j] > 0) {\n                for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                for (int k = 0; k < U[j]; ++k) cout << \"D \" << j << \"\\n\";\n            } else if (D[j] > 0) {\n                for (int k = 0; k < D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                for (int k = 0; k < D[j]; ++k) cout << \"U \" << j << \"\\n\";\n            }\n        }\n        for (int i = 0; i < N; ++i) {\n            if (L[i] > 0 && R[i] > 0) {\n                if (2 * L[i] + R[i] < 2 * R[i] + L[i]) {\n                    for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                    for (int k = 0; k < L[i] + R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                } else {\n                    for (int k = 0; k < R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                    for (int k = 0; k < R[i] + L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                }\n            } else if (L[i] > 0) { for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\"; }\n            else if (R[i] > 0) { for (int k = 0; k < R[i]; ++k) cout << \"R \" << i << \"\\n\"; }\n        }\n    } else {\n        for (int i = 0; i < N; ++i) {\n            if (L[i] > 0 && R[i] > 0) {\n                for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                for (int k = 0; k < L[i] + R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                for (int k = 0; k < R[i]; ++k) cout << \"L \" << i << \"\\n\";\n            } else if (L[i] > 0) {\n                for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                for (int k = 0; k < L[i]; ++k) cout << \"R \" << i << \"\\n\";\n            } else if (R[i] > 0) {\n                for (int k = 0; k < R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                for (int k = 0; k < R[i]; ++k) cout << \"L \" << i << \"\\n\";\n            }\n        }\n        for (int j = 0; j < N; ++j) {\n            if (U[j] > 0 && D[j] > 0) {\n                if (2 * U[j] + D[j] < 2 * D[j] + U[j]) {\n                    for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                    for (int k = 0; k < U[j] + D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                } else {\n                    for (int k = 0; k < D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                    for (int k = 0; k < D[j] + U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                }\n            } else if (U[j] > 0) { for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\"; }\n            else if (D[j] > 0) { for (int k = 0; k < D[j]; ++k) cout << \"D \" << j << \"\\n\"; }\n        }\n    }\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We need to determine two integers a_i and b_i for each employee i (0 to N-1).\n * Weekly cleaners are decided by the previous cleaner's visit parity.\n * Objective: Minimize sum |actual_visit_count_i - target_T_i| over L weeks.\n *\n * Strategy:\n * 1. Proxy Cost Optimization:\n *    Use the flow balance equations based on parity:\n *    t_j \u2248 delta_{j,0} + sum_{i} (ceil(T_i/2) * [a_i=j] + floor(T_i/2) * [b_i=j])\n *    Minimize sum |t_j - target_T_j| using Simulated Annealing.\n *    This ensures the overall network structure supports the target counts.\n * 2. Fine-Tuning:\n *    Use Hill Climbing based on actual 500,000-week simulations to account for\n *    transient behavior and the exact L-week limit.\n */\n\nconst int N = 100;\nlong long target_T[N];\nint best_final_a[N], best_final_b[N];\nlong long min_actual_err = -1;\n\nlong long U_calls[N], V_calls[N];\n\n// Buffers for proxy cost calculation\nbool reachable[N];\nlong long cur_t_arr[N];\nint bfs_q[N];\nint sim_counts[N];\n\n/**\n * Calculates a proxy error based on target transitions.\n * If target_T[i] visits to node i occur, it sends ceil(target_T[i]/2) to a_i\n * and floor(target_T[i]/2) to b_i.\n */\nlong long get_proxy_cost(const int* a, const int* b) {\n    fill(reachable, reachable + N, false);\n    fill(cur_t_arr, cur_t_arr + N, 0);\n    \n    // Check reachability from starting node 0\n    int head = 0, tail = 0;\n    bfs_q[tail++] = 0;\n    reachable[0] = true;\n    while (head < tail) {\n        int u = bfs_q[head++];\n        int na = a[u];\n        if (!reachable[na]) {\n            reachable[na] = true;\n            bfs_q[tail++] = na;\n        }\n        int nb = b[u];\n        if (!reachable[nb]) {\n            reachable[nb] = true;\n            bfs_q[tail++] = nb;\n        }\n    }\n    \n    // Start count for week 1\n    cur_t_arr[0] = 1;\n    // Calculate expected inflows from reachable nodes\n    for (int i = 0; i < N; ++i) {\n        if (reachable[i]) {\n            cur_t_arr[a[i]] += U_calls[i];\n            cur_t_arr[b[i]] += V_calls[i];\n        }\n    }\n    \n    long long err = 0;\n    for (int i = 0; i < N; ++i) {\n        // Heavy penalty for unreachable nodes that should have cleanings\n        if (!reachable[i] && target_T[i] > 0) {\n            err += 1000000LL + target_T[i];\n        }\n        err += abs(cur_t_arr[i] - target_T[i]);\n    }\n    return err;\n}\n\n/**\n * Performs a full L-week simulation to calculate exact visit counts.\n * Complexity: O(L), where L = 500,000.\n */\nlong long get_actual_err(const int* a, const int* b, int L) {\n    fill(sim_counts, sim_counts + N, 0);\n    int curr = 0;\n    for (int w = 0; w < L; ++w) {\n        sim_counts[curr]++;\n        if (sim_counts[curr] & 1) curr = a[curr];\n        else curr = b[curr];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; ++i) err += abs((long long)sim_counts[i] - target_T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, l_in;\n    if (!(cin >> n_in >> l_in)) return 0;\n    for (int i = 0; i < N; ++i) cin >> target_T[i];\n\n    // Precompute call distributions for each node's target visit count\n    for (int i = 0; i < N; ++i) {\n        U_calls[i] = (target_T[i] + 1) / 2;\n        V_calls[i] = target_T[i] / 2;\n    }\n\n    mt19937 mt(1337);\n    int cur_a[N], cur_b[N];\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = mt() % N;\n        cur_b[i] = mt() % N;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Step 1: Simulated Annealing for proxy error optimization\n    long long cur_proxy_err = get_proxy_cost(cur_a, cur_b);\n    long long best_step1_err = cur_proxy_err;\n    int best_step1_a[N], best_step1_b[N];\n    for(int i=0; i<N; ++i) { best_step1_a[i] = cur_a[i]; best_step1_b[i] = cur_b[i]; }\n\n    const double duration_step1 = 1.0;\n    const double t_start = 2500.0, t_end = 0.1;\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > duration_step1) break;\n        }\n        iters++;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long next_proxy_err = get_proxy_cost(cur_a, cur_b);\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double temp = t_start * pow(t_end / t_start, elapsed / duration_step1);\n        \n        if (next_proxy_err <= cur_proxy_err || \n            (double)mt() / mt.max() < exp((double)(cur_proxy_err - next_proxy_err) / temp)) {\n            cur_proxy_err = next_proxy_err;\n            if (cur_proxy_err < best_step1_err) {\n                best_step1_err = cur_proxy_err;\n                for(int k=0; k<N; ++k) { best_step1_a[k] = cur_a[k]; best_step1_b[k] = cur_b[k]; }\n            }\n        } else {\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Initialize current state with the best found in Step 1\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = best_step1_a[i];\n        cur_b[i] = best_step1_b[i];\n        best_final_a[i] = cur_a[i];\n        best_final_b[i] = cur_b[i];\n    }\n    min_actual_err = get_actual_err(cur_a, cur_b, l_in);\n    \n    // Step 2: Hill Climbing with Actual Simulation for fine-tuning\n    const double duration_total = 1.95;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > duration_total) break;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long actual_err = get_actual_err(cur_a, cur_b, l_in);\n        if (actual_err <= min_actual_err) {\n            min_actual_err = actual_err;\n            for (int i = 0; i < N; ++i) {\n                best_final_a[i] = cur_a[i];\n                best_final_b[i] = cur_b[i];\n            }\n        } else {\n            // Revert on worse score\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Output the final optimal cleaning plan transitions\n    for (int i = 0; i < N; ++i) {\n        cout << best_final_a[i] << \" \" << best_final_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Standard Edge structure for MST with tie-breaking\nstruct Edge {\n    int u, v;\n    long long d;\n    bool operator<(const Edge& other) const {\n        if (d != other.d) return d < other.d;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<double> hat_x, hat_y;\nint est_dist[800][800];\nbool is_query_edge[800][800];\n\n// Returns a distance value that incorporates tie-breaking as specified by the problem.\n// Distance d first, then lexicographical order (u, v) with u < v.\nlong long get_unique_dist(int u, int v) {\n    if (u > v) swap(u, v);\n    return (long long)est_dist[u][v] * 1000000LL + (long long)u * 1000LL + (long long)v;\n}\n\n// Prim's algorithm for finding the MST length of a group in O(V^2).\n// Used as the objective function in simulated annealing.\nint mst_prim(const vector<int>& group) {\n    int n = (int)group.size();\n    if (n <= 1) return 0;\n    static int min_d[800];\n    static bool visited[800];\n    for (int i = 0; i < n; i++) {\n        min_d[i] = est_dist[group[0]][group[i]];\n        visited[i] = false;\n    }\n    visited[0] = true;\n    int total = 0;\n    for (int i = 0; i < n - 1; i++) {\n        int u = -1;\n        int best_d = 2000000000;\n        for (int j = 0; j < n; j++) {\n            if (!visited[j] && min_d[j] < best_d) {\n                best_d = min_d[j];\n                u = j;\n            }\n        }\n        if (u == -1) break;\n        visited[u] = true;\n        total += best_d;\n        int gu = group[u];\n        for (int j = 0; j < n; j++) {\n            if (!visited[j]) {\n                int d = est_dist[gu][group[j]];\n                if (d < min_d[j]) min_d[j] = d;\n            }\n        }\n    }\n    return total;\n}\n\n// Helper for query generation: DFS order to traverse MST edges linearly.\nvoid get_dfs_order(int u, int p, const vector<vector<int>>& adj, vector<int>& order) {\n    order.push_back(u);\n    for (int v : adj[u]) {\n        if (v != p) {\n            get_dfs_order(v, u, adj, order);\n        }\n    }\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial input reading\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    hat_x.resize(N); hat_y.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        hat_x[i] = (lx[i] + rx[i]) / 2.0;\n        hat_y[i] = (ly[i] + ry[i]) / 2.0;\n    }\n\n    // Precompute estimated integer distances using bounding box centers\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) est_dist[i][j] = 0;\n            else {\n                double dx = hat_x[i] - hat_x[j];\n                double dy = hat_y[i] - hat_y[j];\n                est_dist[i][j] = (int)floor(sqrt(dx * dx + dy * dy) + 1e-9);\n            }\n        }\n    }\n\n    // Heuristic initial grouping: simple spatial sort\n    vector<int> cities(N);\n    for (int i = 0; i < N; i++) cities[i] = i;\n    sort(cities.begin(), cities.end(), [&](int a, int b) {\n        if (hat_x[a] + hat_y[a] != hat_x[b] + hat_y[b])\n            return hat_x[a] + hat_y[a] < hat_x[b] + hat_y[b];\n        return a < b;\n    });\n\n    vector<vector<int>> groups(M);\n    int city_cursor = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(cities[city_cursor++]);\n        }\n    }\n\n    // Grouping optimization via Simulated Annealing\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    auto get_time = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    double current_total_mst = 0;\n    vector<int> group_mst_lengths(M);\n    for (int i = 0; i < M; i++) {\n        group_mst_lengths[i] = mst_prim(groups[i]);\n        current_total_mst += group_mst_lengths[i];\n    }\n\n    while (get_time() < 1.0) {\n        int idxA = rng() % M;\n        int idxB = rng() % M;\n        if (idxA == idxB || groups[idxA].empty() || groups[idxB].empty()) continue;\n\n        int posA = rng() % (int)groups[idxA].size();\n        int posB = rng() % (int)groups[idxB].size();\n\n        swap(groups[idxA][posA], groups[idxB][posB]);\n        int new_mstA = mst_prim(groups[idxA]);\n        int new_mstB = mst_prim(groups[idxB]);\n        double new_total = current_total_mst - group_mst_lengths[idxA] - group_mst_lengths[idxB] + new_mstA + new_mstB;\n\n        double progress = get_time() / 1.0;\n        double T = 100.0 * (1.0 - progress);\n\n        if (new_total < current_total_mst || (T > 0 && exp((current_total_mst - new_total) / T) > (double)rng() / rng.max())) {\n            current_total_mst = new_total;\n            group_mst_lengths[idxA] = new_mstA;\n            group_mst_lengths[idxB] = new_mstB;\n        } else {\n            swap(groups[idxA][posA], groups[idxB][posB]);\n        }\n    }\n\n    // Perform queries to obtain true MST information\n    int queries_made = 0;\n    for (int i = 0; i < M; i++) {\n        if (groups[i].size() <= 1) continue;\n        int gn = (int)groups[i].size();\n        \n        // Find a representative path of the estimated MST for the current group\n        vector<Edge> candidate_mst_edges;\n        for (int u_idx = 0; u_idx < gn; u_idx++) {\n            for (int v_idx = u_idx + 1; v_idx < gn; v_idx++) {\n                candidate_mst_edges.push_back({u_idx, v_idx, get_unique_dist(groups[i][u_idx], groups[i][v_idx])});\n            }\n        }\n        sort(candidate_mst_edges.begin(), candidate_mst_edges.end());\n        vector<vector<int>> adj(gn);\n        vector<int> parent(gn);\n        for (int j = 0; j < gn; j++) parent[j] = j;\n        auto find_root = [&](auto self, int node) -> int {\n            return (parent[node] == node) ? node : (parent[node] = self(self, parent[node]));\n        };\n        int count_edges = 0;\n        for (auto& e : candidate_mst_edges) {\n            int rootU = find_root(find_root, e.u), rootV = find_root(find_root, e.v);\n            if (rootU != rootV) {\n                adj[e.u].push_back(e.v); adj[e.v].push_back(e.u);\n                parent[rootU] = rootV;\n                if (++count_edges == gn - 1) break;\n            }\n        }\n\n        vector<int> dfs_order;\n        get_dfs_order(0, -1, adj, dfs_order);\n        \n        // Use overlapping subset queries along the DFS path to ensure connectivity\n        for (int j = 0; j + 1 < gn; j += (L - 1)) {\n            if (queries_made >= Q) break;\n            int l_size = min(gn - j, L);\n            cout << \"? \" << l_size;\n            for (int k = 0; k < l_size; k++) cout << \" \" << groups[i][dfs_order[j + k]];\n            cout << endl;\n            queries_made++;\n            for (int k = 0; k < l_size - 1; k++) {\n                int u, v; cin >> u >> v;\n                is_query_edge[u][v] = is_query_edge[v][u] = true;\n            }\n        }\n    }\n\n    // Exhaust remaining queries on random subsets of valid groups\n    while (queries_made < Q) {\n        int target_grp = rng() % M;\n        if (groups[target_grp].size() <= 1) {\n            bool found = false;\n            for (int k = 0; k < M; k++) if (groups[k].size() > 1) { target_grp = k; found = true; break; }\n            if (!found) break;\n        }\n        int gn = (int)groups[target_grp].size();\n        int l_size = min(gn, L);\n        vector<int> subset = groups[target_grp];\n        shuffle(subset.begin(), subset.end(), rng);\n        cout << \"? \" << l_size;\n        for (int k = 0; k < l_size; k++) cout << \" \" << subset[k];\n        cout << endl;\n        queries_made++;\n        for (int k = 0; k < l_size - 1; k++) {\n            int u, v; cin >> u >> v;\n            is_query_edge[u][v] = is_query_edge[v][u] = true;\n        }\n    }\n\n    // Output final results\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        int gn = (int)groups[i].size();\n        for (int j = 0; j < gn; j++) cout << groups[i][j] << (j == gn - 1 ? \"\" : \" \");\n        cout << endl;\n        if (gn > 1) {\n            // Find MST using true query edges where possible, falling back to estimated distances\n            vector<Edge> group_candidate_edges;\n            for (int u_idx = 0; u_idx < gn; u_idx++) {\n                for (int v_idx = u_idx + 1; v_idx < gn; v_idx++) {\n                    int u = groups[i][u_idx], v = groups[i][v_idx];\n                    long long ud = get_unique_dist(u, v);\n                    // Use a large offset to prioritize query-returned edges\n                    if (is_query_edge[u][v]) ud -= 1000000000000LL; \n                    group_candidate_edges.push_back({u, v, ud});\n                }\n            }\n            sort(group_candidate_edges.begin(), group_candidate_edges.end());\n            vector<int> dsu_parent(N);\n            for (int j = 0; j < N; j++) dsu_parent[j] = j;\n            auto find_dsu = [&](auto self, int node) -> int {\n                return (dsu_parent[node] == node) ? node : (dsu_parent[node] = self(self, dsu_parent[node]));\n            };\n            int edges_constructed = 0;\n            for (auto& e : group_candidate_edges) {\n                int rootU = find_dsu(find_dsu, e.u), rootV = find_dsu(find_dsu, e.v);\n                if (rootU != rootV) {\n                    cout << e.u << \" \" << e.v << endl;\n                    dsu_parent[rootU] = rootV;\n                    if (++edges_constructed == gn - 1) break;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 20;\nconst int M = 40;\nconst int INF = 1e9;\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dchar[] = {'U', 'D', 'L', 'R'};\n\nstruct Target {\n    int r, c;\n};\n\nstruct Action {\n    char type;\n    char dir;\n};\n\nstruct Result {\n    int cost;\n    vector<Action> actions;\n};\n\nstruct Node {\n    int r, c, h, cost;\n    bool operator>(const Node& other) const {\n        return cost > other.cost;\n    }\n};\n\nbool in_bounds(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Pre-allocate memory for Dijkstra to avoid repeated allocation\nint dists[N][N][2];\nstruct Parent {\n    int r, c, h;\n    char type, dir;\n} parents[N][N][2];\n\n// Dijkstra's algorithm to find the shortest path from start to target.\n// Optionally allows adding one block at (br, bc) during the path.\nResult dijkstra(int start_r, int start_c, int target_r, int target_c, const vector<vector<bool>>& grid, int br, int bc) {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dists[i][j][0] = dists[i][j][1] = INF;\n        }\n    }\n\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dists[start_r][start_c][0] = 0;\n    pq.push({start_r, start_c, 0, 0});\n\n    while (!pq.empty()) {\n        Node curr = pq.top(); pq.pop();\n        if (curr.cost > dists[curr.r][curr.c][curr.h]) continue;\n        if (curr.r == target_r && curr.c == target_c) break;\n\n        // 1. Move action: cost 1 if empty, cost 2 if it requires 'Alter' to remove a block.\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i], nc = curr.c + dc[i];\n            if (in_bounds(nr, nc)) {\n                bool is_block = grid[nr][nc] || (curr.h && nr == br && nc == bc);\n                int cost = is_block ? 2 : 1;\n                // If we move into the added block (br, bc), it gets removed.\n                int next_h = (curr.h && (nr != br || nc != bc)) ? 1 : 0;\n                if (dists[nr][nc][next_h] > curr.cost + cost) {\n                    dists[nr][nc][next_h] = curr.cost + cost;\n                    parents[nr][nc][next_h] = {curr.r, curr.c, curr.h, 'M', dchar[i]};\n                    pq.push({nr, nc, next_h, dists[nr][nc][next_h]});\n                }\n            }\n        }\n\n        // 2. Slide action: cost 1 regardless of distance.\n        for (int i = 0; i < 4; ++i) {\n            int sr = curr.r, sc = curr.c;\n            while (true) {\n                int nr = sr + dr[i], nc = sc + dc[i];\n                if (!in_bounds(nr, nc) || grid[nr][nc] || (curr.h && nr == br && nc == bc)) break;\n                sr = nr; sc = nc;\n            }\n            if (sr != curr.r || sc != curr.c) {\n                if (dists[sr][sc][curr.h] > curr.cost + 1) {\n                    dists[sr][sc][curr.h] = curr.cost + 1;\n                    parents[sr][sc][curr.h] = {curr.r, curr.c, curr.h, 'S', dchar[i]};\n                    pq.push({sr, sc, curr.h, dists[sr][sc][curr.h]});\n                }\n            }\n        }\n\n        // 3. Place block (only if br, bc provided and h=0)\n        if (br != -1 && curr.h == 0) {\n            for (int i = 0; i < 4; ++i) {\n                if (curr.r + dr[i] == br && curr.c + dc[i] == bc) {\n                    if (dists[curr.r][curr.c][1] > curr.cost + 1) {\n                        dists[curr.r][curr.c][1] = curr.cost + 1;\n                        parents[curr.r][curr.c][1] = {curr.r, curr.c, 0, 'A', dchar[i]};\n                        pq.push({curr.r, curr.c, 1, dists[curr.r][curr.c][1]});\n                    }\n                }\n            }\n        }\n    }\n\n    int best_h = (dists[target_r][target_c][1] < dists[target_r][target_c][0]) ? 1 : 0;\n    if (dists[target_r][target_c][best_h] == INF) return {INF, {}};\n\n    // Path reconstruction\n    vector<Action> actions;\n    int cr = target_r, cc = target_c, ch = best_h;\n    while (cr != start_r || cc != start_c || ch != 0) {\n        Parent p = parents[cr][cc][ch];\n        if (p.type == 'M') {\n            bool was_block = grid[cr][cc] || (p.h && cr == br && cc == bc);\n            if (was_block) actions.push_back({'A', p.dir});\n            actions.push_back({'M', p.dir});\n        } else if (p.type == 'S') {\n            actions.push_back({'S', p.dir});\n        } else if (p.type == 'A') {\n            actions.push_back({'A', p.dir});\n        }\n        cr = p.r; cc = p.c; ch = p.h;\n    }\n    reverse(actions.begin(), actions.end());\n    return {dists[target_r][target_c][best_h], actions};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::steady_clock::now();\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    vector<Target> targets(m_in);\n    for (int i = 0; i < m_in; ++i) cin >> targets[i].r >> targets[i].c;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    int curr_r = targets[0].r, curr_c = targets[0].c;\n\n    for (int k = 1; k < m_in; ++k) {\n        int tr = targets[k].r, tc = targets[k].c;\n        Result best_res = dijkstra(curr_r, curr_c, tr, tc, grid, -1, -1);\n        \n        // Try all possible block placements that could assist in reaching the target via 'Slide'.\n        bool timeout = false;\n        for (int br = 0; br < N; ++br) {\n            for (int bc = 0; bc < N; ++bc) {\n                // Adaptive timeout management\n                auto current_time = chrono::steady_clock::now();\n                if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1850) {\n                    timeout = true; break;\n                }\n                if (grid[br][bc] || (br == tr && bc == tc) || (br == curr_r && bc == curr_c)) continue;\n                \n                // Heuristic skip: only consider blocks near target or curr pos, or in line with them\n                if (abs(br - tr) + abs(bc - tc) > 3 && br != tr && bc != tc && br != curr_r && bc != curr_c) continue;\n                \n                Result res = dijkstra(curr_r, curr_c, tr, tc, grid, br, bc);\n                if (res.cost < best_res.cost) {\n                    best_res = res;\n                }\n            }\n            if (timeout) break;\n        }\n\n        // Output actions and update the state of the rink\n        for (auto& act : best_res.actions) {\n            cout << act.type << \" \" << act.dir << \"\\n\";\n            int dr_val = (act.dir == 'U' ? -1 : act.dir == 'D' ? 1 : 0);\n            int dc_val = (act.dir == 'L' ? -1 : act.dir == 'R' ? 1 : 0);\n            if (act.type == 'A') {\n                grid[curr_r + dr_val][curr_c + dc_val] = !grid[curr_r + dr_val][curr_c + dc_val];\n            } else if (act.type == 'M') {\n                curr_r += dr_val; curr_c += dc_val;\n            } else if (act.type == 'S') {\n                int d_idx = (act.dir == 'U' ? 0 : act.dir == 'D' ? 1 : act.dir == 'L' ? 2 : 3);\n                while (true) {\n                    int nr = curr_r + dr[d_idx], nc = curr_c + dc[d_idx];\n                    if (!in_bounds(nr, nc) || grid[nr][nc]) break;\n                    curr_r = nr; curr_c = nc;\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <numeric>\n\nusing namespace std;\n\n// Structure for axis-parallel rectangles\nstruct Rect {\n    int a, b, c, d; // (a, b) is bottom-left, (c, d) is top-right\n};\n\n// Structure for company data\nstruct Company {\n    int x, y, r;\n    Rect rect;\n    double p;\n};\n\n// Calculate satisfaction p_i\ninline double get_p(int a, int b, int c, int d, int r) {\n    long long s = (long long)(c - a) * (d - b);\n    if (s <= 0) return 0.0;\n    double ratio = (s < (long long)r) ? (double)s / r : (double)r / s;\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Check if two rectangles overlap with positive area\ninline bool overlaps(const Rect& r1, const Rect& r2) {\n    return max(r1.a, r2.a) < min(r1.c, r2.c) &&\n           max(r1.b, r2.b) < min(r1.d, r2.d);\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<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        // Start with 1x1 rectangles containing the required points\n        companies[i].rect = {companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1};\n        companies[i].p = get_p(companies[i].rect.a, companies[i].rect.b, companies[i].rect.c, companies[i].rect.d, companies[i].r);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    // Phase 1: Initial Greedy Expansion (fast way to get a solid starting layout)\n    for (int iter = 0; iter < 150; ++iter) {\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3}; // 0:L, 1:B, 2:R, 3:T\n            shuffle(dirs, dirs + 4, rng);\n            for (int dir : dirs) {\n                Rect next = companies[i].rect;\n                if (dir == 0 && next.a > 0) next.a--;\n                else if (dir == 1 && next.b > 0) next.b--;\n                else if (dir == 2 && next.c < 10000) next.c++;\n                else if (dir == 3 && next.d < 10000) next.d++;\n                else continue;\n\n                // Ensure target point stays inside\n                if (next.a > companies[i].x || next.c <= companies[i].x ||\n                    next.b > companies[i].y || next.d <= companies[i].y) continue;\n\n                bool ok = true;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next, companies[j].rect)) { ok = false; break; }\n                }\n                if (ok) {\n                    companies[i].rect = next;\n                    companies[i].p = get_p(next.a, next.b, next.c, next.d, companies[i].r);\n                }\n            }\n        }\n    }\n\n    // Phase 2: Simulated Annealing with \"Push\" Moves\n    double current_total_p = 0;\n    for (int i = 0; i < n; ++i) current_total_p += companies[i].p;\n\n    double T_start = 0.01; // Initial temperature\n    double T_end = 0.0001;  // Final temperature\n    const double TIME_LIMIT = 4.8;\n\n    long long iter = 0;\n    vector<pair<int, Rect>> changes;\n    changes.reserve(n);\n\n    while (true) {\n        if ((iter & 1023) == 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            double progress = elapsed / TIME_LIMIT;\n            double T = T_start + (T_end - T_start) * progress; // Linear cooling\n\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            int side = uniform_int_distribution<int>(0, 3)(rng);\n            \n            int old_val;\n            if (side == 0) old_val = companies[i].rect.a;\n            else if (side == 1) old_val = companies[i].rect.b;\n            else if (side == 2) old_val = companies[i].rect.c;\n            else old_val = companies[i].rect.d;\n\n            int new_val;\n            int r_move = uniform_int_distribution<int>(0, 99)(rng);\n            if (r_move < 70) new_val = old_val + uniform_int_distribution<int>(-100, 100)(rng);\n            else if (r_move < 90) new_val = old_val + uniform_int_distribution<int>(-500, 500)(rng);\n            else if (r_move < 95) { // Try to reach target area\n                int current_w = companies[i].rect.c - companies[i].rect.a;\n                int current_h = companies[i].rect.d - companies[i].rect.b;\n                if (side == 0) new_val = companies[i].rect.c - (companies[i].r / max(1, current_h));\n                else if (side == 1) new_val = companies[i].rect.d - (companies[i].r / max(1, current_w));\n                else if (side == 2) new_val = companies[i].rect.a + (companies[i].r / max(1, current_h));\n                else new_val = companies[i].rect.b + (companies[i].r / max(1, current_w));\n            } else new_val = uniform_int_distribution<int>(0, 10000)(rng);\n\n            new_val = max(0, min(10000, new_val));\n            if (new_val == old_val) { iter++; continue; }\n\n            Rect next_i = companies[i].rect;\n            if (side == 0) next_i.a = new_val;\n            else if (side == 1) next_i.b = new_val;\n            else if (side == 2) next_i.c = new_val;\n            else next_i.d = new_val;\n\n            bool can_move = true;\n            // Validate basic rectangle properties and point inclusion\n            if (next_i.a >= next_i.c || next_i.b >= next_i.d ||\n                !(next_i.a <= companies[i].x && companies[i].x < next_i.c) ||\n                !(next_i.b <= companies[i].y && companies[i].y < next_i.d)) {\n                can_move = false;\n            }\n\n            changes.clear();\n            if (can_move) {\n                changes.push_back({i, next_i});\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next_i, companies[j].rect)) {\n                        Rect next_j = companies[j].rect;\n                        // Resolve overlap by shrinking j\n                        if (side == 0) next_j.c = next_i.a;\n                        else if (side == 1) next_j.d = next_i.b;\n                        else if (side == 2) next_j.a = next_i.c;\n                        else next_j.b = next_i.d;\n\n                        if (next_j.a >= next_j.c || next_j.b >= next_j.d ||\n                            !(next_j.a <= companies[j].x && companies[j].x < next_j.c) ||\n                            !(next_j.b <= companies[j].y && companies[j].y < next_j.d)) {\n                            can_move = false;\n                            break;\n                        }\n                        changes.push_back({j, next_j});\n                    }\n                }\n            }\n\n            if (can_move) {\n                double new_p_sum = current_total_p;\n                for (auto& ch : changes) {\n                    new_p_sum -= companies[ch.first].p;\n                    new_p_sum += get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                }\n\n                double delta = new_p_sum - current_total_p;\n                if (delta >= 0 || uniform_real_distribution<double>(0, 1)(rng) < exp(delta / T)) {\n                    current_total_p = new_p_sum;\n                    for (auto& ch : changes) {\n                        companies[ch.first].rect = ch.second;\n                        companies[ch.first].p = get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                    }\n                }\n            }\n        }\n        iter++;\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << companies[i].rect.a << \" \" << companies[i].rect.b << \" \"\n             << companies[i].rect.c << \" \" << companies[i].rect.d << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <bitset>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to find a path on a 50x50 grid with tile constraints.\n * - Each square belongs to a tile (1x1, 1x2, or 2x1).\n * - Each tile can be visited at most once.\n * - The goal is to maximize the sum of values p[i][j] of visited squares.\n * \n * Algorithm Improvement:\n * - Use Beam Search with a larger beam width (K=10000).\n * - Diversity constraint: keep at most B=10 paths per square at each step.\n * - Optimize bitset operations and state memory management.\n * - Use a history pointer system to reconstruct the path after the search.\n */\n\n// Grid and maximum tile constants\nconst int GRID_SIZE = 50;\nconst int MAX_TILES = 2500;\n\n// PathNode for reconstructing the final path from the search history\nstruct PathNode {\n    int parent_idx;\n    short r, c;\n    char move;\n};\n\n// State representing a partial path in the beam search\nstruct State {\n    int score;\n    int history_idx;\n    short r, c;\n    bitset<MAX_TILES> visited;\n};\n\n// Candidate for the next step of the path\nstruct Candidate {\n    int score;\n    int parent_beam_idx;\n    short ni, nj;\n    char move;\n\n    // Comparator for sorting candidates by total score in descending order.\n    // Ties are broken using coordinate values to ensure deterministic results.\n    bool operator>(const Candidate& other) const {\n        if (score != other.score) return score > other.score;\n        if (ni != other.ni) return ni > other.ni;\n        return nj > other.nj;\n    }\n};\n\nint main() {\n    // Fast I/O for better performance\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    // Read initial position\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    // Read tile configurations\n    int t[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> t[i][j];\n\n    // Read square scores\n    int p[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> p[i][j];\n\n    // Beam search configuration\n    const int K = 10000; // Maximum number of states to maintain in the beam\n    const int B = 10;    // Diversity: max number of paths allowed to end at the same grid square\n\n    // Store the history of path expansions to reconstruct the final path\n    // Using a flat vector for history to optimize memory allocation and access speed\n    vector<PathNode> history;\n    history.reserve(15000000);\n\n    // Current beam of states representing paths of the current length\n    vector<State> current_beam;\n    current_beam.reserve(K);\n\n    // Initial state: Takahashi starts at (si, sj)\n    bitset<MAX_TILES> initial_visited;\n    initial_visited.set(t[si][sj]);\n    current_beam.push_back({p[si][sj], 0, (short)si, (short)sj, initial_visited});\n    history.push_back({-1, (short)si, (short)sj, ' '});\n\n    int best_score = p[si][sj];\n    int best_history_idx = 0;\n\n    // Movement directions\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    // Candidate list for the next beam expansion\n    vector<Candidate> candidates;\n    candidates.reserve(K * 4);\n\n    // Array to track diversity per cell\n    int counts[GRID_SIZE * GRID_SIZE];\n\n    // Main Beam Search loop\n    while (true) {\n        // Exit search if time limit (2s) is nearing (leaving some margin)\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        candidates.clear();\n        // For each state in the current beam, explore all 4 adjacent moves\n        for (int i = 0; i < (int)current_beam.size(); ++i) {\n            const auto& s = current_beam[i];\n            for (int d = 0; d < 4; ++d) {\n                int ni = s.r + dr[d];\n                int nj = s.c + dc[d];\n                // Check grid boundaries\n                if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE) {\n                    // Check if the tile at the destination has already been visited\n                    if (!s.visited.test(t[ni][nj])) {\n                        candidates.push_back({s.score + p[ni][nj], i, (short)ni, (short)nj, move_chars[d]});\n                    }\n                }\n            }\n        }\n\n        // If no more valid expansions are found, stop the search\n        if (candidates.empty()) break;\n\n        // Sort all possible next moves by score to select the best states for the next beam\n        sort(candidates.begin(), candidates.end(), greater<Candidate>());\n\n        vector<State> next_beam;\n        next_beam.reserve(K);\n        memset(counts, 0, sizeof(counts));\n\n        // Fill the next beam with the top K candidates, respecting the diversity constraint B\n        for (const auto& cand : candidates) {\n            int pos = cand.ni * GRID_SIZE + cand.nj;\n            if (counts[pos] < B) {\n                if (next_beam.size() >= K) break;\n\n                State next_s;\n                next_s.score = cand.score;\n                next_s.r = cand.ni;\n                next_s.c = cand.nj;\n                // Inherit visited bitset from parent and mark the new tile\n                next_s.visited = current_beam[cand.parent_beam_idx].visited;\n                next_s.visited.set(t[cand.ni][cand.nj]);\n                next_s.history_idx = (int)history.size();\n                \n                // Track expansion history\n                history.push_back({current_beam[cand.parent_beam_idx].history_idx, cand.ni, cand.nj, cand.move});\n                \n                // Update overall best path found\n                if (next_s.score > best_score) {\n                    best_score = next_s.score;\n                    best_history_idx = next_s.history_idx;\n                }\n\n                next_beam.push_back(std::move(next_s));\n                counts[pos]++;\n            }\n        }\n\n        // Move to the next step\n        if (next_beam.empty()) break;\n        current_beam = std::move(next_beam);\n    }\n\n    // Trace back through history to reconstruct the sequence of moves for the best path\n    string result_path = \"\";\n    int curr_node_idx = best_history_idx;\n    while (history[curr_node_idx].parent_idx != -1) {\n        result_path += history[curr_node_idx].move;\n        curr_node_idx = history[curr_node_idx].parent_idx;\n    }\n    // Reverse moves as we traced from finish to start\n    reverse(result_path.begin(), result_path.end());\n    \n    // Output the resulting path string\n    cout << result_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 * Strategy Analysis & Refinement:\n * 1. Grid structure: 30x30 vertices with hidden edge lengths.\n * 2. Structural pattern: For M=1 or M=2, edges in the same row/column are very similar.\n * 3. Feedback: Noisy path length (~10% error), more important in later queries (exponential weight).\n * 4. Refinement:\n *    - Use Dijkstra's algorithm for pathfinding based on current edge weight estimates.\n *    - Incorporate exploration bias early in the contest (first 150 queries) to probe less-visited edges.\n *    - Apply kernel-based weight updates (smoothing) to exploit the row/column similarity pattern.\n *    - Implement a decaying learning rate to stabilize estimates as more data is gathered.\n *    - Constrain weights within the known possible range [1000, 9000].\n */\n\n// Grid size constant.\nconst int N = 30;\n// Edge weight range constraints from the generation rules.\nconst double MIN_WEIGHT = 1000.0;\nconst double MAX_WEIGHT = 9000.0;\n// Initial weight estimate based on expected average.\nconst double INIT_WEIGHT = 5000.0;\n\n// Struct to store identifying information for an edge on a path.\nstruct EdgeInfo {\n    int type; // 0 for horizontal (h_weights), 1 for vertical (v_weights)\n    int i, j;\n};\n\n// Global arrays for weight estimates and path statistics.\ndouble h_weights[N][N - 1];\ndouble v_weights[N - 1][N];\nint h_counts[N][N - 1];\nint v_counts[N - 1][N];\ndouble gamma_pow[N + 1];\n\n/**\n * Initialize starting values and precompute smoothing weights.\n */\nvoid init() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            h_weights[i][j] = INIT_WEIGHT;\n            h_counts[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = INIT_WEIGHT;\n            v_counts[i][j] = 0;\n        }\n    }\n    // gamma controls the spread of information across a row/column.\n    double gamma = 0.90;\n    gamma_pow[0] = 1.0;\n    for (int i = 1; i <= N; ++i) {\n        gamma_pow[i] = gamma_pow[i - 1] * gamma;\n    }\n}\n\n/**\n * Provides the edge weight for Dijkstra's shortest path algorithm.\n * Early on, it introduces a bias to encourage exploration of less-visited edges.\n */\ndouble get_dijkstra_weight(int type, int i, int j, int k) {\n    double w = (type == 0) ? h_weights[i][j] : v_weights[i][j];\n    if (k < 150) {\n        int count = (type == 0) ? h_counts[i][j] : v_counts[i][j];\n        // Factor that decreases with both query index and usage count.\n        double factor = 0.20 * (1.0 - (double)k / 150.0) / (1.0 + (double)count);\n        return w * (1.0 - factor);\n    }\n    return w;\n}\n\n/**\n * Standard Dijkstra implementation to find the shortest path under current estimates.\n * Also tracks which edges are used to update estimates later.\n */\nstring find_path(int si, int sj, int ti, int tj, int k, vector<EdgeInfo>& path_edges) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<pair<int, int>, char>>> parent(N, vector<pair<pair<int, int>, char>>(N, {{-1, -1}, ' '}));\n    using P = pair<double, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int i = pq.top().second.first;\n        int j = pq.top().second.second;\n        pq.pop();\n\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        // Traverse edges: Down, Up, Right, Left.\n        if (i < N - 1) { // Down\n            double w = get_dijkstra_weight(1, i, j, k);\n            if (dist[i + 1][j] > d + w) {\n                dist[i + 1][j] = d + w;\n                parent[i + 1][j] = {{i, j}, 'D'};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (i > 0) { // Up\n            double w = get_dijkstra_weight(1, i - 1, j, k);\n            if (dist[i - 1][j] > d + w) {\n                dist[i - 1][j] = d + w;\n                parent[i - 1][j] = {{i, j}, 'U'};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (j < N - 1) { // Right\n            double w = get_dijkstra_weight(0, i, j, k);\n            if (dist[i][j + 1] > d + w) {\n                dist[i][j + 1] = d + w;\n                parent[i][j + 1] = {{i, j}, 'R'};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n        if (j > 0) { // Left\n            double w = get_dijkstra_weight(0, i, j - 1, k);\n            if (dist[i][j - 1] > d + w) {\n                dist[i][j - 1] = d + w;\n                parent[i][j - 1] = {{i, j}, 'L'};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n    }\n\n    // Trace the path from target to source.\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char dir = parent[ci][cj].second;\n        path += dir;\n        int pi = parent[ci][cj].first.first;\n        int pj = parent[ci][cj].first.second;\n        if (dir == 'U') {\n            path_edges.push_back({1, ci, cj});\n            v_counts[ci][cj]++;\n        } else if (dir == 'D') {\n            path_edges.push_back({1, pi, pj});\n            v_counts[pi][pj]++;\n        } else if (dir == 'L') {\n            path_edges.push_back({0, ci, cj});\n            h_counts[ci][cj]++;\n        } else if (dir == 'R') {\n            path_edges.push_back({0, pi, pj});\n            h_counts[pi][pj]++;\n        }\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/**\n * Updates the estimated weight of edges using the measured length provided by the judge.\n * Kernel smoothing propagates information to neighbors in the same row or column.\n */\nvoid update_weights(const vector<EdgeInfo>& path_edges, int result, int k) {\n    double predicted_len = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) predicted_len += h_weights[e.i][e.j];\n        else predicted_len += v_weights[e.i][e.j];\n    }\n\n    double error = (double)result - predicted_len;\n    // Decaying learning rate for stability over time.\n    double lr = 0.5 * pow(0.999, (double)k);\n\n    vector<vector<double>> coeff_h(N, vector<double>(N - 1, 0.0));\n    vector<vector<double>> coeff_v(N - 1, vector<double>(N, 0.0));\n\n    // Distribute measurement information along rows and columns using the smoothing kernel.\n    for (const auto& e : path_edges) {\n        if (e.type == 0) {\n            for (int jp = 0; jp < N - 1; ++jp) {\n                coeff_h[e.i][jp] += gamma_pow[abs(e.j - jp)];\n            }\n        } else {\n            for (int ip = 0; ip < N - 1; ++ip) {\n                coeff_v[ip][e.j] += gamma_pow[abs(e.i - ip)];\n            }\n        }\n    }\n\n    // Normalization to ensure the update step size aligns with the intended learning rate.\n    double total_path_coeff = 0;\n    for (const auto& e : path_edges) {\n        if (e.type == 0) total_path_coeff += coeff_h[e.i][e.j];\n        else total_path_coeff += coeff_v[e.i][e.j];\n    }\n\n    if (total_path_coeff > 0) {\n        double step = (error * lr) / total_path_coeff;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                if (coeff_h[i][j] > 0) {\n                    h_weights[i][j] += step * coeff_h[i][j];\n                    h_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, h_weights[i][j]));\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (coeff_v[i][j] > 0) {\n                    v_weights[i][j] += step * coeff_v[i][j];\n                    v_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, v_weights[i][j]));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    init();\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        vector<EdgeInfo> path_edges;\n        string path = find_path(si, sj, ti, tj, k, path_edges);\n        cout << path << endl; // Output path and flush.\n\n        int result;\n        if (!(cin >> result)) break;\n        update_weights(path_edges, result, k);\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <cmath>\n#include <cstring>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Fast xorshift random number generator for performance\nuint32_t xorshift() {\n    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t t = x ^ (x << 11);\n    x = y; y = z; z = w;\n    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n}\n\nconst int N = 20;\nint M;\nint A[N][N];\nint best_A[N][N];\nint current_c = 0;\nint current_d = 0;\nint count_in_matrix[1000];\nint weights[1000];\nbool length_exists[13];\n\n// Hash table for mapping packed strings to unique internal IDs\nstruct HashTable {\n    static const int SIZE = 16384;\n    long long keys[SIZE];\n    int values[SIZE];\n    HashTable() { memset(keys, -1, sizeof(keys)); }\n    void insert(long long key, int val) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return;\n            h = (h + 1) & (SIZE - 1);\n        }\n        keys[h] = key;\n        values[h] = val;\n    }\n    int query(long long key) {\n        unsigned int h = (unsigned int)((key ^ (key >> 32)) * 0x45d9f3b) & (SIZE - 1);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return values[h];\n            h = (h + 1) & (SIZE - 1);\n        }\n        return -1;\n    }\n} id_map;\n\n// Pack a string into a 64-bit integer (max 40 bits)\nlong long pack(const string& str) {\n    uint64_t res = 0;\n    for (char ch : str) res = (res << 3) | (ch - 'A');\n    return (long long)((res << 4) | (uint64_t)str.length());\n}\n\n// Optimized modify function for SA updates\nvoid modify(int r, int c, int delta, int& c_val) {\n    // Horizontal substrings covering (r,c)\n    for (int k_idx = 0; k_idx < 12; ++k_idx) {\n        int start_c = (c - k_idx + N) % N;\n        uint64_t val = 0;\n        for (int k = 0; k < 12; ++k) {\n            int v = A[r][(start_c + k) % N];\n            if (v == 0) break;\n            val = (val << 3) | (v - 1);\n            int len = k + 1;\n            if (k >= k_idx && len >= 2 && length_exists[len]) {\n                int id = id_map.query((long long)((val << 4) | (uint64_t)len));\n                if (id != -1) {\n                    if (delta == -1) {\n                        if (count_in_matrix[id] == 1) c_val -= weights[id];\n                        count_in_matrix[id]--;\n                    } else {\n                        if (count_in_matrix[id] == 0) c_val += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n            }\n        }\n    }\n    // Vertical substrings covering (r,c)\n    for (int k_idx = 0; k_idx < 12; ++k_idx) {\n        int start_r = (r - k_idx + N) % N;\n        uint64_t val = 0;\n        for (int k = 0; k < 12; ++k) {\n            int v = A[(start_r + k) % N][c];\n            if (v == 0) break;\n            val = (val << 3) | (v - 1);\n            int len = k + 1;\n            if (k >= k_idx && len >= 2 && length_exists[len]) {\n                int id = id_map.query((long long)((val << 4) | (uint64_t)len));\n                if (id != -1) {\n                    if (delta == -1) {\n                        if (count_in_matrix[id] == 1) c_val -= weights[id];\n                        count_in_matrix[id]--;\n                    } else {\n                        if (count_in_matrix[id] == 0) c_val += weights[id];\n                        count_in_matrix[id]++;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Scoring function for SA\ndouble get_score(int c, int d) {\n    if (c < M) return (double)c;\n    return (double)M + 1.0 + (double)d / (N * N + 1.0);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n_input;\n    if (!(cin >> n_input >> M)) return 0;\n\n    vector<string> all_strings(M);\n    map<string, int> string_counts;\n    memset(length_exists, false, sizeof(length_exists));\n    for (int i = 0; i < M; ++i) {\n        cin >> all_strings[i];\n        string_counts[all_strings[i]]++;\n        length_exists[all_strings[i].length()] = true;\n    }\n\n    int k_unique = 0;\n    for (auto const& [str, weight] : string_counts) {\n        weights[k_unique] = weight;\n        id_map.insert(pack(str), k_unique);\n        k_unique++;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n\n    // Greedy initialization\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) A[i][j] = 0;\n    vector<string> sorted_s = all_strings;\n    sort(sorted_s.begin(), sorted_s.end(), [](const string& a, const string& b) {\n        return a.length() > b.length();\n    });\n\n    for (const string& s : sorted_s) {\n        int best_r = -1, best_c = -1, best_dir = -1, best_score = -1e9;\n        for (int dir = 0; dir < 2; ++dir) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    int score = 0;\n                    for (int k = 0; k < (int)s.length(); ++k) {\n                        int rr = (dir == 0 ? r : (r + k) % N);\n                        int cc = (dir == 0 ? (c + k) % N : c);\n                        if (A[rr][cc] == 0) score += 2;\n                        else if (A[rr][cc] == s[k] - 'A' + 1) score += 3;\n                        else score -= 50;\n                    }\n                    if (score > best_score) {\n                        best_score = score;\n                        best_r = r; best_c = c; best_dir = dir;\n                    }\n                }\n            }\n        }\n        if (best_score > 0) {\n            for (int k = 0; k < (int)s.length(); ++k) {\n                int rr = (best_dir == 0 ? best_r : (best_r + k) % N);\n                int cc = (best_dir == 0 ? (best_c + k) % N : best_c);\n                A[rr][cc] = s[k] - 'A' + 1;\n            }\n        }\n    }\n\n    // Fill remaining empty cells for SA Stage 1\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (A[i][j] == 0) A[i][j] = (xorshift() % 8) + 1;\n\n    // Evaluate initial matrix state\n    memset(count_in_matrix, 0, sizeof(count_in_matrix));\n    current_c = 0; current_d = 0;\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (A[r][c] == 0) current_d++;\n            uint64_t val = 0;\n            for (int k = 0; k < 12; ++k) {\n                int v = A[r][(c + k) % N];\n                if (v == 0) break;\n                val = (val << 3) | (v - 1);\n                if (k + 1 >= 2 && length_exists[k + 1]) {\n                    int id = id_map.query((long long)((val << 4) | (uint64_t)(k + 1)));\n                    if (id != -1) { if (count_in_matrix[id] == 0) current_c += weights[id]; count_in_matrix[id]++; }\n                }\n            }\n            val = 0;\n            for (int k = 0; k < 12; ++k) {\n                int v = A[(r + k) % N][c];\n                if (v == 0) break;\n                val = (val << 3) | (v - 1);\n                if (k + 1 >= 2 && length_exists[k + 1]) {\n                    int id = id_map.query((long long)((val << 4) | (uint64_t)(k + 1)));\n                    if (id != -1) { if (count_in_matrix[id] == 0) current_c += weights[id]; count_in_matrix[id]++; }\n                }\n            }\n        }\n    }\n\n    double old_score = get_score(current_c, current_d);\n    double best_total_score = old_score;\n    memcpy(best_A, A, sizeof(A));\n\n    // Simulated Annealing\n    double T_start = 2.0, T_end = 0.001;\n    long long iter_total = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.85) break;\n        double T = T_start * pow(T_end / T_start, elapsed / 2.85);\n\n        for (int sub = 0; sub < 100; ++sub) {\n            iter_total++;\n            int r = xorshift() % N, c = xorshift() % N;\n            int old_v = A[r][c], new_v = xorshift() % 9;\n            if (new_v == old_v) continue;\n\n            int old_c = current_c, old_d = current_d;\n            modify(r, c, -1, current_c);\n            A[r][c] = new_v;\n            modify(r, c, 1, current_c);\n            if (old_v == 0) current_d--;\n            if (new_v == 0) current_d++;\n\n            double new_score = get_score(current_c, current_d);\n            if (new_score >= old_score || (T > 1e-9 && exp((new_score - old_score) / T) > (double)xorshift() / 4294967295.0)) {\n                old_score = new_score;\n                if (new_score > best_total_score) {\n                    best_total_score = new_score;\n                    memcpy(best_A, A, sizeof(A));\n                }\n            } else {\n                modify(r, c, -1, current_c);\n                A[r][c] = old_v;\n                modify(r, c, 1, current_c);\n                current_c = old_c;\n                current_d = old_d;\n            }\n        }\n    }\n\n    // Output final best matrix found\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (best_A[i][j] == 0) cout << '.';\n            else cout << (char)('A' + best_A[i][j] - 1);\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 <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXR = 5000;\nint N, SI, SJ;\nvector<string> grid;\nstruct Road { int r, c, cost; };\nvector<Road> roads;\nint road_idx_map[70][70];\nvector<pair<int, int>> adj[MAXR];\nint dists[MAXR][MAXR];\nshort parents[MAXR][MAXR];\n\n// Standard Dial's algorithm for grid edge weights 5-9\nvoid dial(int start, int* d, short* p, int R) {\n    for (int i = 0; i < R; ++i) d[i] = INF;\n    d[start] = 0;\n    p[start] = -1;\n    static vector<int> buckets[10];\n    for (int i = 0; i < 10; ++i) buckets[i].clear();\n    buckets[0].push_back(start);\n    int cur_dist = 0, num_visited = 0;\n    while (num_visited < R) {\n        int b_idx = cur_dist % 10;\n        while (!buckets[b_idx].empty()) {\n            int u = buckets[b_idx].back();\n            buckets[b_idx].pop_back();\n            if (d[u] < cur_dist) continue;\n            num_visited++;\n            for (auto& edge : adj[u]) {\n                int v = edge.first, w = edge.second;\n                if (d[v] > cur_dist + w) {\n                    d[v] = cur_dist + w;\n                    p[v] = (short)u;\n                    buckets[d[v] % 10].push_back(v);\n                }\n            }\n        }\n        cur_dist++;\n        if (cur_dist > 70000) break; \n    }\n}\n\n// Simple bipartite matching implementation\nbool match_dfs(int u, const vector<vector<int>>& b_adj, vector<int>& match_v, vector<bool>& vis) {\n    for (int v : b_adj[u]) {\n        if (vis[v]) continue;\n        vis[v] = true;\n        if (match_v[v] == -1 || match_dfs(match_v[v], b_adj, match_v, vis)) {\n            match_v[v] = u;\n            return true;\n        }\n    }\n    return false;\n}\n\nstruct VisitTask {\n    int current_sq;\n    bool is_flexible;\n    int seg_id;\n};\n\n// Calculate total travel distance for a given task tour\nint calculate_tour_dist(const vector<VisitTask>& tour) {\n    int d = 0;\n    int K = (int)tour.size();\n    for (int i = 0; i < K; ++i) {\n        d += dists[tour[i].current_sq][tour[(i + 1) % K].current_sq];\n    }\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read grid size and starting point\n    if (!(cin >> N >> SI >> SJ)) return 0;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // Identify and index road squares\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_idx_map[i][j] = (int)roads.size();\n                roads.push_back({i, j, grid[i][j] - '0'});\n            } else road_idx_map[i][j] = -1;\n        }\n    }\n    int R = (int)roads.size();\n    for (int i = 0; i < R; ++i) {\n        int r = roads[i].r, c = roads[i].c;\n        int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != '#') {\n                adj[i].push_back({road_idx_map[nr][nc], grid[nr][nc] - '0'});\n            }\n        }\n    }\n\n    // Precalculate all-pairs shortest paths\n    for (int i = 0; i < R; ++i) dial(i, dists[i], parents[i], R);\n\n    // Group road squares into maximal horizontal and vertical segments\n    vector<vector<int>> h_segs, v_segs;\n    vector<int> h_seg_of(R), v_seg_of(R);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                if (j == 0 || grid[i][j - 1] == '#') {\n                    int sid = (int)h_segs.size();\n                    h_segs.push_back({});\n                    for (int k = j; k < N && grid[i][k] != '#'; ++k) {\n                        h_segs[sid].push_back(road_idx_map[i][k]);\n                        h_seg_of[road_idx_map[i][k]] = sid;\n                    }\n                }\n                if (i == 0 || grid[i - 1][j] == '#') {\n                    int sid = (int)v_segs.size();\n                    v_segs.push_back({});\n                    for (int k = i; k < N && grid[k][j] != '#'; ++k) {\n                        v_segs[sid].push_back(road_idx_map[k][j]);\n                        v_seg_of[road_idx_map[k][j]] = sid;\n                    }\n                }\n            }\n        }\n    }\n\n    // Minimum Vertex Cover using K\u00f6nig's Theorem\n    int n_h = (int)h_segs.size(), n_v = (int)v_segs.size();\n    vector<vector<int>> b1_adj(n_h);\n    for (int i = 0; i < R; ++i) b1_adj[h_seg_of[i]].push_back(v_seg_of[i]);\n    for (int i = 0; i < n_h; ++i) {\n        sort(b1_adj[i].begin(), b1_adj[i].end());\n        b1_adj[i].erase(unique(b1_adj[i].begin(), b1_adj[i].end()), b1_adj[i].end());\n    }\n\n    vector<int> match1_v(n_v, -1), match1_h(n_h, -1);\n    for (int i = 0; i < n_h; ++i) {\n        vector<bool> vis(n_v, false);\n        match_dfs(i, b1_adj, match1_v, vis);\n    }\n    for (int i = 0; i < n_v; ++i) if (match1_v[i] != -1) match1_h[match1_v[i]] = i;\n\n    vector<bool> vis_l(n_h, false), vis_r(n_v, false);\n    vector<int> q;\n    for (int i = 0; i < n_h; ++i) if (match1_h[i] == -1) { vis_l[i] = true; q.push_back(i); }\n    int head = 0;\n    while (head < (int)q.size()) {\n        int u = q[head++];\n        for (int v : b1_adj[u]) {\n            if (!vis_r[v]) {\n                vis_r[v] = true;\n                int next_u = match1_v[v];\n                if (next_u != -1 && !vis_l[next_u]) { vis_l[next_u] = true; q.push_back(next_u); }\n            }\n        }\n    }\n    vector<int> MVC_H, MVC_V;\n    for (int i = 0; i < n_h; ++i) if (!vis_l[i]) MVC_H.push_back(i);\n    for (int i = 0; i < n_v; ++i) if (vis_r[i]) MVC_V.push_back(i);\n\n    // Identify segments not already covered by the starting position\n    int start_node = road_idx_map[SI][SJ];\n    int h_start_node = h_seg_of[start_node], v_start_node = v_seg_of[start_node];\n    vector<int> M_rem_H, M_rem_V;\n    for (int h : MVC_H) if (h != h_start_node) M_rem_H.push_back(h);\n    for (int v : MVC_V) if (v != v_start_node) M_rem_V.push_back(v);\n\n    // Maximize \"double coverage\" with a matching in the segment graph\n    vector<vector<int>> b2_adj(n_h);\n    for (int h : M_rem_H) {\n        for (int v : M_rem_V) {\n            bool intersect = false;\n            for (int r_idx : h_segs[h]) if (v_seg_of[r_idx] == v) { intersect = true; break; }\n            if (intersect) b2_adj[h].push_back(v);\n        }\n    }\n    vector<int> match2_v(n_v, -1), match2_h(n_h, -1);\n    for (int h : M_rem_H) {\n        vector<bool> vis(n_v, false);\n        match_dfs(h, b2_adj, match2_v, vis);\n    }\n    for (int i = 0; i < n_v; ++i) if (match2_v[i] != -1) match2_h[match2_v[i]] = i;\n\n    // Create tasks for the TSP tour\n    vector<VisitTask> tasks;\n    tasks.push_back({start_node, false, -1});\n    vector<bool> h_covered(n_h, false), v_covered(n_v, false);\n    h_covered[h_start_node] = v_covered[v_start_node] = true;\n\n    for (int h : M_rem_H) {\n        if (match2_h[h] != -1) {\n            int v = match2_h[h];\n            int sq = -1;\n            for (int r_idx : h_segs[h]) if (v_seg_of[r_idx] == v) { sq = r_idx; break; }\n            tasks.push_back({sq, false, -1});\n            h_covered[h] = v_covered[v] = true;\n        }\n    }\n    for (int h : M_rem_H) if (!h_covered[h]) tasks.push_back({h_segs[h][0], true, h});\n    for (int v : M_rem_V) if (!v_covered[v]) tasks.push_back({v_segs[v][0], true, n_h + v});\n\n    int K = (int)tasks.size();\n    vector<VisitTask> tour = tasks;\n    int current_dist = calculate_tour_dist(tour);\n\n    // Simulated Annealing to optimize the visit order and square choices\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    double duration = 2.4; \n    int iterations = 0;\n    vector<VisitTask> best_tour = tour;\n    int best_dist = current_dist;\n\n    while (true) {\n        if (iterations % 2000 == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > duration) break;\n        }\n        iterations++;\n        double t_norm = (double)chrono::duration<double>(chrono::steady_clock::now() - start_time).count() / duration;\n        double temp = 50.0 * (1.0 - t_norm);\n\n        int move_type = uniform_int_distribution<>(0, 2)(rng);\n        vector<VisitTask> next_tour = tour;\n        int next_dist = 0;\n\n        if (move_type == 0) { // 2-opt edge swap\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i >= j) continue;\n            reverse(next_tour.begin() + i, next_tour.begin() + j + 1);\n            next_dist = calculate_tour_dist(next_tour);\n        } else if (move_type == 1) { // Node relocation\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i == j) continue;\n            VisitTask task = next_tour[i];\n            next_tour.erase(next_tour.begin() + i);\n            next_tour.insert(next_tour.begin() + j, task);\n            next_dist = calculate_tour_dist(next_tour);\n        } else { // Optimize choice of square within a segment\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            if (!next_tour[i].is_flexible) continue;\n            int seg = next_tour[i].seg_id;\n            const vector<int>& opts = (seg < n_h ? h_segs[seg] : v_segs[seg - n_h]);\n            next_tour[i].current_sq = opts[uniform_int_distribution<>(0, (int)opts.size() - 1)(rng)];\n            next_dist = calculate_tour_dist(next_tour);\n        }\n\n        if (next_dist < current_dist || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((current_dist - next_dist) / temp))) {\n            tour = next_tour;\n            current_dist = next_dist;\n            if (current_dist < best_dist) {\n                best_dist = current_dist;\n                best_tour = tour;\n            }\n        }\n    }\n\n    // Output the final path string\n    string final_path = \"\";\n    for (int i = 0; i < K; ++i) {\n        int u = best_tour[i].current_sq, v = best_tour[(i + 1) % K].current_sq;\n        vector<int> path;\n        int cur = v;\n        while (cur != u) { path.push_back(cur); cur = parents[u][cur]; }\n        reverse(path.begin(), path.end());\n        int pre = u;\n        for (int node : path) {\n            if (roads[node].r < roads[pre].r) final_path += 'U';\n            else if (roads[node].r > roads[pre].r) final_path += 'D';\n            else if (roads[node].c < roads[pre].c) final_path += 'L';\n            else final_path += 'R';\n            pre = node;\n        }\n    }\n    cout << final_path << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\n// Configuration based on problem statement\nconst int MAX_DAYS = 2000;\nconst int N_TASKS = 1000;\nconst int M_MEMBERS = 20;\n\nstruct History {\n    vector<int> d;\n    int t;\n};\n\nstruct Task {\n    int id;\n    vector<int> d;\n    vector<int> deps;\n    vector<int> rev_deps;\n    double height;\n    int descendants;\n    int status; // -1: not ready, 0: ready, 1: ongoing, 2: completed\n};\n\nstruct Member {\n    int id;\n    vector<double> s;\n    int current_task;\n    int start_day;\n    vector<History> history;\n};\n\nint N, M, K, R;\nvector<Task> tasks;\nvector<Member> members;\n\n// Calculate the difficulty term w_i,j = sum(max(0, d_i,k - s_j,k))\ndouble get_w(const vector<double>& s, const vector<int>& d) {\n    double w = 0;\n    for (int k = 0; k < K; ++k) {\n        if ((double)d[k] > s[k]) w += (double)d[k] - s[k];\n    }\n    return w;\n}\n\n// Calculate the expected number of days for completion based on w_i,j and the random integer r\ndouble expected_duration(double w) {\n    if (w <= 0.0) return 1.0;\n    double sum = 0;\n    for (int r = -3; r <= 3; ++r) {\n        sum += max(1.0, w + (double)r);\n    }\n    return sum / 7.0;\n}\n\n// Re-calculate task heights for critical path prioritization\nvoid calculate_heights() {\n    double avg_s_val = 32.0 / sqrt((double)K);\n    vector<double> avg_s(K, avg_s_val);\n    \n    vector<double> duration_ests(N);\n    for (int i = 0; i < N; ++i) {\n        duration_ests[i] = expected_duration(get_w(avg_s, tasks[i].d));\n    }\n\n    for (int i = 0; i < N; ++i) tasks[i].height = 0;\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; ++i) out_degree[i] = (int)tasks[i].rev_deps.size();\n    \n    vector<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (out_degree[i] == 0) {\n            q.push_back(i);\n            tasks[i].height = duration_ests[i];\n        }\n    }\n    \n    int head = 0;\n    while(head < (int)q.size()){\n        int v = q[head++];\n        for(int u : tasks[v].deps){\n            tasks[u].height = max(tasks[u].height, tasks[v].height + duration_ests[u]);\n            if(--out_degree[u] == 0) q.push_back(u);\n        }\n    }\n}\n\n// Calculate total task descendants for secondary prioritization\nvoid calculate_descendants() {\n    for (int i = 0; i < N; ++i) {\n        vector<bool> visited(N, false);\n        vector<int> q_d;\n        q_d.push_back(i);\n        visited[i] = true;\n        int count = 0;\n        int head = 0;\n        while(head < (int)q_d.size()){\n            int v = q_d[head++];\n            for(int next_v : tasks[v].rev_deps){\n                if(!visited[next_v]){\n                    visited[next_v] = true;\n                    q_d.push_back(next_v);\n                    count++;\n                }\n            }\n        }\n        tasks[i].descendants = count;\n    }\n}\n\n// Update skill estimates using gradient descent based on task completion history\nvoid update_skills(int m_idx) {\n    auto& m = members[m_idx];\n    if (m.history.empty()) return;\n    \n    for (int iter = 0; iter < 400; ++iter) {\n        double eta = 0.1 / (1.0 + iter * 0.01);\n        vector<double> grad(K, 0.0);\n        for (const auto& h : m.history) {\n            double w = get_w(m.s, h.d);\n            double target_w = (h.t == 1) ? 0.0 : (double)h.t;\n            double diff = w - target_w;\n            // For t=1, we only know w is small, so we don't penalize if w is already 0\n            if (h.t == 1 && diff < 0) diff = 0;\n            for (int k = 0; k < K; ++k) {\n                if ((double)h.d[k] > m.s[k]) grad[k] -= diff;\n            }\n        }\n        for (int k = 0; k < K; ++k) {\n            m.s[k] -= eta * grad[k] / (double)m.history.size();\n            m.s[k] = max(0.0, m.s[k]);\n        }\n        // Project onto norm constraints [20, 60]\n        double norm2 = 0;\n        for (int k = 0; k < K; ++k) norm2 += m.s[k] * m.s[k];\n        double norm = sqrt(norm2);\n        if (norm < 20.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 20.0 / (norm + 1e-9);\n        } else if (norm > 60.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 60.0 / norm;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    tasks.resize(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].id = i;\n        tasks[i].d.resize(K);\n        for (int k = 0; k < K; ++k) cin >> tasks[i].d[k];\n        tasks[i].status = -1;\n    }\n    \n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        tasks[v].deps.push_back(u);\n        tasks[u].rev_deps.push_back(v);\n    }\n    \n    calculate_heights();\n    calculate_descendants();\n    \n    members.resize(M);\n    for (int j = 0; j < M; ++j) {\n        members[j].id = j;\n        members[j].s.assign(K, 32.0 / sqrt((double)K));\n        members[j].current_task = -1;\n    }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        \n        for (int i = 0; i < N; ++i) {\n            if (tasks[i].status == -1) {\n                bool ok = true;\n                for (int dep : tasks[i].deps) {\n                    if (tasks[dep].status != 2) { ok = false; break; }\n                }\n                if (ok) tasks[i].status = 0;\n            }\n        }\n        \n        vector<int> idle_members, ready_tasks;\n        for (int j = 0; j < M; ++j) if (members[j].current_task == -1) idle_members.push_back(j);\n        for (int i = 0; i < N; ++i) if (tasks[i].status == 0) ready_tasks.push_back(i);\n        \n        vector<pair<int, int>> assignments;\n        while (!idle_members.empty() && !ready_tasks.empty()) {\n            double best_score = -1e18;\n            int best_m_idx = -1, best_t_idx = -1, best_mi = -1, best_ti = -1;\n\n            for (int mi = 0; mi < (int)idle_members.size(); ++mi) {\n                int j = idle_members[mi];\n                for (int ti = 0; ti < (int)ready_tasks.size(); ++ti) {\n                    int i = ready_tasks[ti];\n                    double w_est = get_w(members[j].s, tasks[i].d);\n                    double dur = expected_duration(w_est);\n                    // Standard scheduling priority: (critical_path_importance) * (efficiency)\n                    double score = (tasks[i].height * 100.0 + (double)tasks[i].descendants) / dur;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m_idx = j;\n                        best_t_idx = i;\n                        best_mi = mi;\n                        best_ti = ti;\n                    }\n                }\n            }\n            \n            if (best_m_idx != -1) {\n                assignments.push_back({best_m_idx, best_t_idx});\n                tasks[best_t_idx].status = 1;\n                members[best_m_idx].current_task = best_t_idx;\n                members[best_m_idx].start_day = current_day;\n                idle_members.erase(idle_members.begin() + best_mi);\n                ready_tasks.erase(ready_tasks.begin() + best_ti);\n            } else break;\n        }\n        \n        cout << (int)assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        cout << endl;\n        \n        int n_completed;\n        if (!(cin >> n_completed) || n_completed == -1) break;\n        for (int i = 0; i < n_completed; ++i) {\n            int m_id; cin >> m_id; --m_id;\n            int t_idx = members[m_id].current_task;\n            int duration = current_day - members[m_id].start_day + 1;\n            members[m_id].history.push_back({tasks[t_idx].d, duration});\n            tasks[t_idx].status = 2;\n            members[m_id].current_task = -1;\n            update_skills(m_id);\n        }\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// Order information and state arrays\nint orders_a[1000], orders_b[1000], orders_c[1000], orders_d[1000];\nint order_in_s[50];\nbool in_s[1000];\nint route[102];\nint pos[101]; // position of point index 0-99 in route\nint cur_x[101], cur_y[101]; // coords of point 0-99, and point 100 is the office (400, 400)\n\n// Calculate Manhattan distance between two points by their index in cur_x/cur_y\ninline int dist_points(int p1, int p2) {\n    return abs(cur_x[p1] - cur_x[p2]) + abs(cur_y[p1] - cur_y[p2]);\n}\n\n// Calculate Manhattan distance between a route index and specific coordinates\ninline int dist_to_coord(int r_idx, int x, int y) {\n    return abs(cur_x[route[r_idx]] - x) + abs(cur_y[route[r_idx]] - y);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read 1000 orders\n    for (int i = 0; i < 1000; i++) {\n        if (!(cin >> orders_a[i] >> orders_b[i] >> orders_c[i] >> orders_d[i])) break;\n    }\n\n    // Heuristic: Pick a pool of candidates closest to the office center (400, 400)\n    vector<pair<int, int>> pool_candidates;\n    for (int i = 0; i < 1000; i++) {\n        int d = abs(orders_a[i] - 400) + abs(orders_b[i] - 400) + abs(orders_c[i] - 400) + abs(orders_d[i] - 400);\n        pool_candidates.push_back({d, i});\n    }\n    sort(pool_candidates.begin(), pool_candidates.end());\n\n    // Use a subset of size 400 for selection\n    int pool_size = 400;\n    vector<int> pool;\n    for (int i = 0; i < pool_size; i++) {\n        pool.push_back(pool_candidates[i].second);\n    }\n\n    // Initialize chosen orders S with the first 50 closest orders\n    for (int i = 0; i < 50; i++) {\n        int order_idx = pool[i];\n        order_in_s[i] = order_idx;\n        in_s[order_idx] = true;\n        cur_x[i] = orders_a[order_idx];      // Pickup coordinate x\n        cur_y[i] = orders_b[order_idx];      // Pickup coordinate y\n        cur_x[i + 50] = orders_c[order_idx]; // Delivery coordinate x\n        cur_y[i + 50] = orders_d[order_idx]; // Delivery coordinate y\n    }\n    cur_x[100] = 400; cur_y[100] = 400; // Office coordinate\n\n    // Build an initial route using a Greedy Pickup-Delivery heuristic\n    int current_x = 400, current_y = 400;\n    vector<bool> visited_p(100, false);\n    route[0] = 100; route[101] = 100;\n    for (int step = 1; step <= 100; step++) {\n        int best_dist = 1e9, best_p = -1;\n        for (int p = 0; p < 100; p++) {\n            if (visited_p[p]) continue;\n            if (p >= 50 && !visited_p[p - 50]) continue; // Cannot deliver before pickup\n            int d = abs(current_x - cur_x[p]) + abs(current_y - cur_y[p]);\n            if (d < best_dist) { best_dist = d; best_p = p; }\n        }\n        route[step] = best_p;\n        pos[best_p] = step;\n        visited_p[best_p] = true;\n        current_x = cur_x[best_p]; current_y = cur_y[best_p];\n    }\n\n    // Initial total travel time\n    int current_t = 0;\n    for (int i = 0; i <= 100; i++) {\n        current_t += dist_points(route[i], route[i+1]);\n    }\n\n    // Simulated Annealing setup\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double t_start = 30.0, t_end = 0.1;\n    long long total_iter = 0;\n\n    while (true) {\n        // Limit total execution time to 1.96 seconds\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.96) break;\n\n        double progress = elapsed / 1.96;\n        double temp = t_start * pow(t_end / t_start, progress);\n\n        // Perform chunks of iterations\n        for (int j = 0; j < 2000; j++) {\n            int move_type = rng() % 100;\n\n            if (move_type < 45) { // Relocate point Move\n                int i = 1 + rng() % 100;\n                int k_pos = 1 + rng() % 100;\n                if (i == k_pos) continue;\n\n                int vi = route[i];\n                // Precedence Constraint Check\n                if (vi < 50) { if (i < k_pos && k_pos >= pos[vi + 50]) continue; }\n                else { if (i > k_pos && k_pos <= pos[vi - 50]) continue; }\n\n                // Distance Delta Calculation\n                int d_before, d_after;\n                if (i < k_pos) {\n                    d_before = dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]) + dist_points(route[k_pos], route[k_pos+1]);\n                    d_after = dist_points(route[i-1], route[i+1]) + dist_points(route[k_pos], route[i]) + dist_points(route[i], route[k_pos+1]);\n                } else {\n                    d_before = dist_points(route[k_pos-1], route[k_pos]) + dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]);\n                    d_after = dist_points(route[k_pos-1], route[i]) + dist_points(route[i], route[k_pos]) + dist_points(route[i-1], route[i+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    int v = route[i];\n                    if (i < k_pos) {\n                        for (int k = i; k < k_pos; k++) { route[k] = route[k+1]; pos[route[k]] = k; }\n                    } else {\n                        for (int k = i; k > k_pos; k--) { route[k] = route[k-1]; pos[route[k]] = k; }\n                    }\n                    route[k_pos] = v; pos[v] = k_pos;\n                }\n            } else if (move_type < 90) { // Swap two points Move\n                int i = 1 + rng() % 100;\n                int j = 1 + rng() % 100;\n                if (i == j) continue;\n                int vi = route[i], vj = route[j];\n\n                // Precedence Constraint Check\n                if (vi < 50) { if (j >= pos[vi + 50]) continue; }\n                else { if (j <= pos[vi - 50]) continue; }\n                if (vj < 50) { if (i >= pos[vj + 50]) continue; }\n                else { if (i <= pos[vj - 50]) continue; }\n\n                int d_before, d_after;\n                int i_low = min(i, j), i_high = max(i, j);\n                if (i_high == i_low + 1) {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                } else {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_low+1]) +\n                               dist_points(route[i_high-1], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low+1]) +\n                              dist_points(route[i_high-1], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    swap(route[i], route[j]);\n                    pos[route[i]] = i; pos[route[j]] = j;\n                }\n            } else { // Replace one order in S Move\n                int k = rng() % 50;\n                int old_idx = order_in_s[k];\n                int new_idx = pool[rng() % pool_size];\n                if (in_s[new_idx]) continue;\n\n                int pk_pos = pos[k], dk_pos = pos[k+50];\n                int nax = orders_a[new_idx], nay = orders_b[new_idx], ncx = orders_c[new_idx], ncy = orders_d[new_idx];\n\n                int d_before = dist_points(route[pk_pos-1], k) + dist_points(k, route[pk_pos+1]) +\n                               dist_points(route[dk_pos-1], k+50) + dist_points(k+50, route[dk_pos+1]);\n                if (pk_pos + 1 == dk_pos) {\n                    d_before = dist_points(route[pk_pos-1], k) + dist_points(k, k+50) + dist_points(k+50, route[dk_pos+1]);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_before = dist_points(route[dk_pos-1], k+50) + dist_points(k+50, k) + dist_points(k, route[pk_pos+1]);\n                }\n\n                int d_after = dist_to_coord(pk_pos-1, nax, nay) + dist_to_coord(pk_pos+1, nax, nay) +\n                              dist_to_coord(dk_pos-1, ncx, ncy) + dist_to_coord(dk_pos+1, ncx, ncy);\n                if (pk_pos + 1 == dk_pos) {\n                    d_after = dist_to_coord(pk_pos-1, nax, nay) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(dk_pos+1, ncx, ncy);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_after = dist_to_coord(dk_pos-1, ncx, ncy) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(pk_pos+1, nax, nay);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    in_s[old_idx] = false; in_s[new_idx] = true;\n                    order_in_s[k] = new_idx;\n                    cur_x[k] = nax; cur_y[k] = nay;\n                    cur_x[k+50] = ncx; cur_y[k+50] = ncy;\n                }\n            }\n        }\n        total_iter++;\n    }\n\n    // Final Output: Number of orders and their 1-indexed IDs\n    cout << 50;\n    for (int i = 0; i < 50; i++) cout << \" \" << order_in_s[i] + 1;\n    cout << \"\\n\";\n\n    // Final Output: Route coordinates (start office, pickups/deliveries, end office)\n    cout << 102;\n    for (int i = 0; i <= 101; i++) {\n        int x, y;\n        if (i == 0 || i == 101) { x = 400; y = 400; }\n        else {\n            int p = route[i];\n            if (p < 50) { x = orders_a[order_in_s[p]]; y = orders_b[order_in_s[p]]; }\n            else { x = orders_c[order_in_s[p - 50]]; y = orders_d[order_in_s[p - 50]]; }\n        }\n        cout << \" \" << x << \" \" << y;\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * We have an online minimum spanning tree (MST) problem where edge weights are revealed one by one.\n * The goal is to minimize the total weight of the selected edges while ensuring connectivity.\n * Since we must decide whether to pick an edge before seeing the weights of future edges,\n * this is a classic scenario for a Monte Carlo (MC) heuristic.\n *\n * Algorithm Strategy:\n * 1. Maintain a current set of adopted edges using a Disjoint Set Union (DSU) to track connectivity.\n * 2. For each edge (u_i, v_i) with revealed weight l_i:\n *    a. If u_i and v_i are already connected, reject the edge (it's redundant).\n *    b. Mandatory Check: Check if edge i is absolutely necessary to keep the graph connected.\n *       If the vertices cannot be connected using any of the remaining edges, we MUST pick it.\n *    c. Monte Carlo Simulation: Perform multiple simulations where future edge weights are\n *       sampled from their known distributions [d_j, 3*d_j]. For each scenario, check if\n *       edge i would be part of the MST.\n *    d. If the edge is \"mandatory\" or appears in the MST in more than 50% of the simulated\n *       scenarios, we adopt it.\n */\n\n// Fast DSU implementation for maintaining the base connectivity.\nstruct FastDSU {\n    int parent[400];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    int find(int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]]; // Path halving for performance\n            i = parent[i];\n        }\n        return i;\n    }\n    void unite(int i, int j) {\n        int r1 = find(i);\n        int r2 = find(j);\n        if (r1 != r2) parent[r1] = r2;\n    }\n};\n\n// Simplified DSU structure for simulations, optimized for speed.\nstruct SimDSU {\n    int parent[400];\n    inline int find(int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]];\n            i = parent[i];\n        }\n        return i;\n    }\n    inline void unite(int i, int j) {\n        int r1 = find(i);\n        int r2 = find(j);\n        if (r1 != r2) parent[r1] = r2;\n    }\n};\n\nint main() {\n    // Fast I/O for competitive programming.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> x[i] >> y[i])) break;\n    }\n\n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; ++i) {\n        if (!(cin >> u[i] >> v[i])) break;\n        double dx = (double)x[u[i]] - x[v[i]];\n        double dy = (double)y[u[i]] - y[v[i]];\n        // Distance is the rounded Euclidean distance between endpoints.\n        d[i] = (int)round(sqrt(dx * dx + dy * dy));\n    }\n\n    FastDSU dsu_base;\n    dsu_base.init(N);\n\n    // Seeded random engine for consistent Monte Carlo simulations.\n    mt19937 rng(1337);\n    // Number of scenarios. Higher values improve accuracy but take more time.\n    // 60 simulations is a good balance for the 2.0s time limit.\n    const int K = 60; \n    \n    // Pre-sample weights for all simulations to maintain consistency and optimize speed.\n    vector<vector<int>> sampled_l(K, vector<int>(M));\n    for (int k = 0; k < K; ++k) {\n        for (int j = 0; j < M; ++j) {\n            // Weights are uniformly distributed between d_j and 3*d_j.\n            sampled_l[k][j] = d[j] + (int)(rng() % (2 * d[j] + 1));\n        }\n    }\n\n    SimDSU sim;\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n\n        int r_u = dsu_base.find(u[i]);\n        int r_v = dsu_base.find(v[i]);\n\n        // If the nodes are already connected by previously adopted lines, discard this line.\n        if (r_u == r_v) {\n            cout << 0 << endl;\n            continue;\n        }\n\n        // Filtering: Only consider remaining edges that actually connect different components.\n        // This drastically speeds up the simulation logic as the graph gets more connected.\n        vector<int> root_u_list, root_v_list, rel_idx;\n        root_u_list.reserve(M - i);\n        root_v_list.reserve(M - i);\n        rel_idx.reserve(M - i);\n\n        for (int j = i + 1; j < M; ++j) {\n            int ru_j = dsu_base.find(u[j]);\n            int rv_j = dsu_base.find(v[j]);\n            if (ru_j != rv_j) {\n                root_u_list.push_back(ru_j);\n                root_v_list.push_back(rv_j);\n                rel_idx.push_back(j);\n            }\n        }\n\n        bool pick = false;\n        \n        // 1. Mandatory Check:\n        // Use a temporary simulation DSU to see if (r_u, r_v) can be connected \n        // by ANY of the future candidate lines.\n        for (int n = 0; n < N; ++n) sim.parent[n] = n;\n        for (size_t j = 0; j < root_u_list.size(); ++j) {\n            sim.unite(root_u_list[j], root_v_list[j]);\n        }\n        \n        if (sim.find(r_u) != sim.find(r_v)) {\n            // No other future edge can connect these components; adoption is mandatory.\n            pick = true;\n        } else {\n            // 2. Monte Carlo Logic:\n            // For K scenarios, calculate if edge i belongs to the MST.\n            // Edge i is in the MST if no path exists between its endpoints \n            // using only edges with lower weights than l_i.\n            int count = 0;\n            for (int k = 0; k < K; ++k) {\n                for (int n = 0; n < N; ++n) sim.parent[n] = n;\n                for (size_t j = 0; j < root_u_list.size(); ++j) {\n                    if (sampled_l[k][rel_idx[j]] < l_i) {\n                        int r1 = sim.find(root_u_list[j]);\n                        int r2 = sim.find(root_v_list[j]);\n                        if (r1 != r2) {\n                            sim.parent[r1] = r2;\n                            // Optimization: Stop once endpoints are connected.\n                            if (sim.find(r_u) == sim.find(r_v)) break;\n                        }\n                    }\n                }\n                if (sim.find(r_u) != sim.find(r_v)) count++;\n            }\n            // Adopt the edge if it is statistically likely to be optimal.\n            if (count > K / 2) pick = true;\n        }\n\n        if (pick) {\n            dsu_base.unite(r_u, r_v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int TURNS = 300;\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y; };\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool is_blocked[GRID_SIZE + 1][GRID_SIZE + 1];\n\n// Check if any pet is at or adjacent to (x, y) at the beginning of the turn\nbool is_pet_near(int x, int y) {\n    for (int i = 0; i < N; i++) {\n        if (abs(pets[i].x - x) + abs(pets[i].y - y) <= 1) return true;\n    }\n    return false;\n}\n\n// Check if any human is currently at (x, y)\nbool is_human_at_start(int x, int y) {\n    for (const auto& h : humans) if (h.x == x && h.y == y) return true;\n    return false;\n}\n\n// BFS to find the first move in the shortest path while avoiding blocked squares and other humans\nstring bfs_move(int sx, int sy, int tx, int ty, const vector<Human>& current_humans, const vector<Human>& next_humans, int human_idx, const vector<pair<int, int>>& planned_blocks) {\n    if (sx == tx && sy == ty) return \".\";\n    \n    struct Node { int x, y; string path; };\n    queue<Node> q;\n    q.push({sx, sy, \"\"});\n    vector<vector<int>> dist(GRID_SIZE + 1, vector<int>(GRID_SIZE + 1, -1));\n    dist[sx][sy] = 0;\n    \n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    char mc[] = {'U', 'D', 'L', 'R'};\n\n    while (!q.empty()) {\n        Node curr = q.front(); q.pop();\n        if (curr.x == tx && curr.y == ty) return curr.path.substr(0, 1);\n\n        for (int i = 0; i < 4; i++) {\n            int nx = curr.x + dx[i], ny = curr.y + dy[i];\n            if (nx < 1 || nx > GRID_SIZE || ny < 1 || ny > GRID_SIZE || is_blocked[nx][ny]) continue;\n            \n            bool forbidden = false;\n            // Avoid squares currently being blocked by other humans in the same turn\n            for (auto& pb : planned_blocks) if (nx == pb.first && ny == pb.second) forbidden = true;\n            // Avoid other humans' positions (next positions for already moved humans, current positions for others)\n            for (int j = 0; j < human_idx; j++) if (nx == next_humans[j].x && ny == next_humans[j].y) forbidden = true;\n            for (int j = human_idx + 1; j < M; j++) if (nx == current_humans[j].x && ny == current_humans[j].y) forbidden = true;\n\n            if (!forbidden && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[curr.x][curr.y] + 1;\n                q.push({nx, ny, curr.path + mc[i]});\n            }\n        }\n    }\n    return \".\";\n}\n\nint main() {\n    ios::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].x >> pets[i].y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) cin >> humans[i].x >> humans[i].y;\n\n    // Define vertical walls at column multiples of 3\n    vector<int> wall_cols = {3, 6, 9, 12, 15, 18, 21, 24, 27};\n\n    for (int t = 0; t < TURNS; t++) {\n        string turn_actions(M, '.');\n        vector<Human> next_humans = humans;\n        vector<pair<int, int>> planned_blocks;\n\n        for (int i = 0; i < M; i++) {\n            int hx = humans[i].x, hy = humans[i].y;\n            int best_tx = -1, best_ty = -1, min_dist = 1000;\n\n            // Strategy: Build vertical columns and then close them if no pets are inside\n            for (int y : wall_cols) {\n                // Prioritize building column segments (except the gate at row 15)\n                for (int x = 1; x <= 30; x++) {\n                    if (x == 15) continue;\n                    if (is_blocked[x][y]) continue;\n                    int d = abs(hx - x) + abs(hy - y);\n                    if (d < min_dist) { min_dist = d; best_tx = x; best_ty = y; }\n                }\n                // Check if the wall is complete and the gate can be closed\n                bool wall_done = true;\n                for (int x = 1; x <= 30; x++) if (x != 15 && !is_blocked[x][y]) wall_done = false;\n                if (wall_done && !is_blocked[15][y]) {\n                    bool pet_in_section = false;\n                    for (int p = 0; p < N; p++) {\n                        // Section to the left of the wall\n                        if (pets[p].y == y - 1 || pets[p].y == y - 2) pet_in_section = true;\n                    }\n                    if (!pet_in_section) {\n                        int d = abs(hx - 15) + abs(hy - y);\n                        if (d < min_dist) { min_dist = d; best_tx = 15; best_ty = y; }\n                    }\n                }\n            }\n\n            if (best_tx != -1) {\n                if (min_dist == 1) {\n                    // Try to perform a blocking action\n                    if (!is_pet_near(best_tx, best_ty) && !is_human_at_start(best_tx, best_ty)) {\n                        bool human_will_be_there = false;\n                        for (int j = 0; j < i; j++) if (next_humans[j].x == best_tx && next_humans[j].y == best_ty) human_will_be_there = true;\n                        for (int j = i + 1; j < M; j++) if (humans[j].x == best_tx && humans[j].y == best_ty) human_will_be_there = true;\n                        \n                        if (!human_will_be_there) {\n                            planned_blocks.push_back({best_tx, best_ty});\n                            if (best_tx < hx) turn_actions[i] = 'u';\n                            else if (best_tx > hx) turn_actions[i] = 'd';\n                            else if (best_ty < hy) turn_actions[i] = 'l';\n                            else turn_actions[i] = 'r';\n                            continue;\n                        }\n                    }\n                }\n                // Try to move to a square adjacent to the target\n                int adj_x = -1, adj_y = -1, adj_min_d = 1000;\n                int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n                for (int k = 0; k < 4; k++) {\n                    int nx = best_tx + dx[k], ny = best_ty + dy[k];\n                    if (nx >= 1 && nx <= GRID_SIZE && ny >= 1 && ny <= GRID_SIZE && !is_blocked[nx][ny]) {\n                        bool blocked_by_other = false;\n                        for (auto& pb : planned_blocks) if (nx == pb.first && ny == pb.second) blocked_by_other = true;\n                        if (!blocked_by_other) {\n                            int d = abs(hx - nx) + abs(hy - ny);\n                            if (d < adj_min_d) { adj_min_d = d; adj_x = nx; adj_y = ny; }\n                        }\n                    }\n                }\n                if (adj_x != -1) {\n                    string mv = bfs_move(hx, hy, adj_x, adj_y, humans, next_humans, i, planned_blocks);\n                    if (mv != \".\") {\n                        turn_actions[i] = mv[0];\n                        if (mv[0] == 'U') next_humans[i].x--;\n                        else if (mv[0] == 'D') next_humans[i].x++;\n                        else if (mv[0] == 'L') next_humans[i].y--;\n                        else if (mv[0] == 'R') next_humans[i].y++;\n                    }\n                }\n            }\n        }\n\n        // Execute actions\n        cout << turn_actions << endl;\n        for (int i = 0; i < M; i++) {\n            if (turn_actions[i] >= 'a' && turn_actions[i] <= 'z') {\n                int tx = humans[i].x, ty = humans[i].y;\n                if (turn_actions[i] == 'u') tx--; else if (turn_actions[i] == 'd') tx++;\n                else if (turn_actions[i] == 'l') ty--; else if (turn_actions[i] == 'r') ty++;\n                is_blocked[tx][ty] = true;\n            } else {\n                humans[i] = next_humans[i];\n            }\n        }\n\n        // Update pet positions based on feedback\n        for (int i = 0; i < N; i++) {\n            string pm; if (!(cin >> pm)) break;\n            for (char c : pm) {\n                if (c == 'U') pets[i].x--; else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--; else if (c == 'R') pets[i].y++;\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 <numeric>\n\nusing namespace std;\n\n// Directional moves: Up (0), Down (1), Left (2), Right (3)\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nint si, sj, ti, tj;\ndouble p_prob_val;\nstring h_wall[20], v_wall[19];\nint dist_to_target[400];\nint move_to[400][4];\ndouble P_mat[401][201];\ndouble W_mat[401][201];\ndouble G_prime_mat[401][201];\ndouble H_precomputed[401][201];\n\n// Check if a move from (i, j) in a given direction is possible (no walls)\nbool can_move_func(int i, int j, int dir) {\n    if (dir == 0) { // Up\n        if (i > 0 && v_wall[i - 1][j] == '0') return true;\n    } else if (dir == 1) { // Down\n        if (i < 19 && v_wall[i][j] == '0') return true;\n    } else if (dir == 2) { // Left\n        if (j > 0 && h_wall[i][j - 1] == '0') return true;\n    } else if (dir == 3) { // Right\n        if (j < 19 && h_wall[i][j] == '0') return true;\n    }\n    return false;\n}\n\n// Compute shortest distance from every square to the target (ti, tj) using BFS\nvoid bfs_target_dist() {\n    for (int i = 0; i < 400; ++i) dist_to_target[i] = 999;\n    int target_idx = ti * 20 + tj;\n    dist_to_target[target_idx] = 0;\n    queue<int> q;\n    q.push(target_idx);\n    while (!q.empty()) {\n        int idx = q.front();\n        q.pop();\n        int r = idx / 20, c = idx % 20;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = r - di[dir], nj = c - dj[dir]; // Inverse the direction to find neighbors\n            if (ni >= 0 && ni < 20 && nj >= 0 && nj < 20) {\n                // If we can move from (ni, nj) in direction 'dir' to reach (r, c)\n                if (can_move_func(ni, nj, dir)) {\n                    int n_idx = ni * 20 + nj;\n                    if (dist_to_target[n_idx] == 999) {\n                        dist_to_target[n_idx] = dist_to_target[idx] + 1;\n                        q.push(n_idx);\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Precompute probabilities for the heuristic evaluation\nvoid precompute_scoring() {\n    double l1p = log(1.0 - p_prob_val);\n    double lp = log(p_prob_val);\n    for (int d = 1; d <= 400; ++d) {\n        for (int t = 1; t <= 200; ++t) {\n            if (t < d) {\n                P_mat[d][t] = 0;\n            } else {\n                // Prob(d-th success occurs at turn t) = C(t-1, d-1) * (1-p)^d * p^(t-d)\n                double log_comb = lgamma(t) - lgamma(d) - lgamma(t - d + 1);\n                P_mat[d][t] = exp(log_comb + (double)d * l1p + (double)(t - d) * lp);\n            }\n        }\n        W_mat[d][0] = 0;\n        G_prime_mat[d][0] = 0;\n        for (int rem = 1; rem <= 200; ++rem) {\n            W_mat[d][rem] = W_mat[d][rem - 1] + P_mat[d][rem];\n            G_prime_mat[d][rem] = G_prime_mat[d][rem - 1] + (double)rem * P_mat[d][rem];\n        }\n        for (int k = 0; k <= 200; ++k) {\n            int rem_len = 200 - k;\n            // H_precomputed[d][k] = sum_{t=d}^{200-k} (401 - (k+t)) * P(d, t)\n            H_precomputed[d][k] = (401.0 - (double)k) * W_mat[d][rem_len] - G_prime_mat[d][rem_len];\n        }\n    }\n    for (int k = 0; k <= 200; ++k) H_precomputed[0][k] = 0;\n}\n\nstruct State {\n    string s;\n    double P[400];\n    double current_E_S;\n    double score;\n\n    State() {\n        for (int i = 0; i < 400; i++) P[i] = 0;\n        current_E_S = 0;\n        score = 0;\n        s = \"\";\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p_prob_val)) return 0;\n    for (int i = 0; i < 20; i++) cin >> h_wall[i];\n    for (int i = 0; i < 19; i++) cin >> v_wall[i];\n\n    bfs_target_dist();\n    precompute_scoring();\n\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            int idx = i * 20 + j;\n            for (int dir = 0; dir < 4; ++dir) {\n                if (can_move_func(i, j, dir)) {\n                    move_to[idx][dir] = (i + di[dir]) * 20 + (j + dj[dir]);\n                } else {\n                    move_to[idx][dir] = -1;\n                }\n            }\n        }\n    }\n\n    int target_idx = ti * 20 + tj;\n    const int B = 800; // Beam width\n    vector<State> current_beam;\n    State initial_state;\n    initial_state.P[si * 20 + sj] = 1.0;\n    initial_state.score = H_precomputed[dist_to_target[si * 20 + sj]][0];\n    current_beam.push_back(move(initial_state));\n\n    for (int k = 1; k <= 200; ++k) {\n        vector<State> next_beam_pool;\n        next_beam_pool.reserve(current_beam.size() * 4);\n\n        for (const auto& state : current_beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                State next_s;\n                next_s.s = state.s + dc[dir];\n                double p_reached = 0;\n\n                for (int idx = 0; idx < 400; ++idx) {\n                    if (idx == target_idx) continue; // Office is a sink\n                    double p_val = state.P[idx];\n                    if (p_val < 1e-18) continue;\n\n                    int n_idx = move_to[idx][dir];\n                    if (n_idx != -1) {\n                        // Prob p: stays in current square due to forgetfulness\n                        next_s.P[idx] += p_val * p_prob_val;\n                        // Prob 1-p: moves successfully\n                        if (n_idx == target_idx) {\n                            p_reached += p_val * (1.0 - p_prob_val);\n                        } else {\n                            next_s.P[n_idx] += p_val * (1.0 - p_prob_val);\n                        }\n                    } else {\n                        // Wall or forget both lead to staying in the square\n                        next_s.P[idx] += p_val;\n                    }\n                }\n\n                // Update accumulated expected score and heuristic for future steps\n                next_s.current_E_S = state.current_E_S + (401.0 - (double)k) * p_reached;\n                double h_future = 0;\n                for (int idx = 0; idx < 400; ++idx) {\n                    if (next_s.P[idx] > 1e-18) {\n                        int d = dist_to_target[idx];\n                        if (d <= 400) h_future += next_s.P[idx] * H_precomputed[d][k];\n                    }\n                }\n                next_s.score = next_s.current_E_S + h_future;\n                next_beam_pool.push_back(move(next_s));\n            }\n        }\n\n        // Sorting and pruning for Beam Search\n        if (next_beam_pool.size() > B) {\n            vector<int> indices(next_beam_pool.size());\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return next_beam_pool[a].score > next_beam_pool[b].score;\n            });\n            vector<State> pruned;\n            pruned.reserve(B);\n            for (int i = 0; i < B; i++) {\n                pruned.push_back(move(next_beam_pool[indices[i]]));\n            }\n            current_beam = move(pruned);\n        } else {\n            sort(next_beam_pool.begin(), next_beam_pool.end(), [](const State& a, const State& b) {\n                return a.score > b.score;\n            });\n            current_beam = move(next_beam_pool);\n        }\n    }\n\n    // Output the resulting string of movements\n    cout << current_beam[0].s << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 30;\nconst double TIME_LIMIT = 1.95; // Execution time limit in seconds\n\n// Global grid data and state\nint initial_grid[N][N];\nint current_tiles[N][N];\nint rot[N][N];\nint visited[N * N * 4]; // Fast loop detection using a 1D visited array\nint timer = 0;\n\n// Tile port connection table based on the problem hint\n// Directions: 0: Left, 1: Up, 2: Right, 3: Down\nint to_tbl[8][4] = {\n    {1, 0, -1, -1}, // Tile 0: Left <-> Top\n    {3, -1, -1, 0}, // Tile 1: Left <-> Bottom\n    {-1, -1, 3, 2}, // Tile 2: Right <-> Bottom\n    {-1, 2, 1, -1}, // Tile 3: Right <-> Top\n    {1, 0, 3, 2},   // Tile 4: Left <-> Top, Right <-> Bottom\n    {3, 2, 1, 0},   // Tile 5: Left <-> Bottom, Top <-> Right\n    {2, -1, 0, -1}, // Tile 6: Left <-> Right\n    {-1, 3, -1, 1}  // Tile 7: Top <-> Bottom\n};\n\n// Movement vectors for directions 0:L, 1:U, 2:R, 3:D\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Map rotation counts (0-3 CCW) to tile type based on the input generation logic\ninline int get_tile_type(int initial_type, int rotation) {\n    if (initial_type <= 3) return (initial_type + rotation) % 4;\n    if (initial_type <= 5) return 4 + (initial_type - 4 + rotation) % 2;\n    if (initial_type <= 7) return 6 + (initial_type - 6 + rotation) % 2;\n    return initial_type;\n}\n\n// Efficient evaluation function that finds all loop lengths in O(N^2)\nlong long evaluate(int& max1, int& max2) {\n    timer++;\n    max1 = 0; max2 = 0;\n    int num_loops = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                int p_idx = (i * N + j) * 4 + d;\n                if (visited[p_idx] == timer || to_tbl[current_tiles[i][j]][d] == -1) continue;\n                \n                int ci = i, cj = j, cd = d, length = 0;\n                bool is_loop = false;\n                while (true) {\n                    int cp = (ci * N + cj) * 4 + cd;\n                    if (visited[cp] == timer) break;\n                    int d_out = to_tbl[current_tiles[ci][cj]][cd];\n                    if (d_out == -1) break;\n                    \n                    visited[cp] = timer;\n                    visited[(ci * N + cj) * 4 + d_out] = timer;\n                    \n                    int ni = ci + di[d_out], nj = cj + dj[d_out], nd = d_out ^ 2;\n                    length++;\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    if (ni == i && nj == j && nd == d) { is_loop = true; break; }\n                    ci = ni, cj = nj, cd = nd;\n                }\n                if (is_loop) {\n                    num_loops++;\n                    if (length > max1) { max2 = max1; max1 = length; }\n                    else if (length > max2) { max2 = length; }\n                }\n            }\n        }\n    }\n    // Scoring criteria: L1 * L2 if at least two loops exist, otherwise 0\n    return (num_loops >= 2) ? (long long)max1 * max2 : 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input grid\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) initial_grid[i][j] = s[j] - '0';\n    }\n    \n    // Initialize state with random rotations\n    mt19937 rng(42);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rot[i][j] = rng() % 4;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n    \n    int m1, m2;\n    long long current_score = evaluate(m1, m2);\n    long long best_score = current_score;\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] = rot[i][j];\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double T_start = 100.0, T_end = 0.1, T = T_start;\n    \n    // Simulated Annealing loop\n    for (int iter = 0; ; ++iter) {\n        // Periodic time check and temperature cooling\n        if ((iter & 127) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n            T = T_start * pow(T_end / T_start, elapsed / TIME_LIMIT);\n        }\n        \n        // Pick a random tile and try a random rotation change\n        int i = rng() % N, j = rng() % N, old_r = rot[i][j];\n        rot[i][j] = (old_r + (rng() % 3) + 1) % 4;\n        current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        \n        int nm1, nm2;\n        long long next_score = evaluate(nm1, nm2);\n        \n        // Use a \"soft\" version of the score as the SA energy to provide a gradient\n        // 1M bonus ensures that states with 2 loops are generally favored over states with 1 loop\n        long long eff_next = (next_score > 0) ? (1000000 + next_score) : (nm1 + nm2);\n        long long eff_curr = (current_score > 0) ? (1000000 + current_score) : (m1 + m2);\n        \n        if (eff_next >= eff_curr || exp((double)(eff_next - eff_curr) / T) > (double)rng() / rng.max()) {\n            current_score = next_score; m1 = nm1; m2 = nm2;\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_rot[r][c] = rot[r][c];\n            }\n        } else {\n            // Revert the rotation if the move is rejected\n            rot[i][j] = old_r;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], old_r);\n        }\n    }\n    \n    // Output the optimized rotations for each tile\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) cout << best_rot[i][j];\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nint N, T_max;\nint id_to_type[101];\nint initial_empty_r, initial_empty_c;\n\nstruct DSU {\n    int parent[100];\n    int sz[100];\n    int edges[100];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) {\n            parent[i] = i;\n            sz[i] = 1;\n            edges[i] = 0;\n        }\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            parent[root_i] = root_j;\n            sz[root_j] += sz[root_i];\n            edges[root_j] += edges[root_i] + 1;\n        } else {\n            edges[root_i]++;\n        }\n    }\n};\n\nDSU dsu;\n\nint get_tree_score(const vector<int>& p) {\n    int total_tiles = N * N;\n    dsu.init(total_tiles);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int u = r * N + c;\n            int type_u = id_to_type[p[u]];\n            if (type_u == 0) continue;\n            if (c + 1 < N) {\n                int v = u + 1;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 4) && (type_v & 1)) dsu.unite(u, v);\n            }\n            if (r + 1 < N) {\n                int v = u + N;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 8) && (type_v & 2)) dsu.unite(u, v);\n            }\n        }\n    }\n    int max_s = 0;\n    for (int i = 0; i < total_tiles; ++i) {\n        if (dsu.parent[i] == i && id_to_type[p[i]] != 0) {\n            if (dsu.edges[i] == dsu.sz[i] - 1) {\n                if (dsu.sz[i] > max_s) max_s = dsu.sz[i];\n            }\n        }\n    }\n    return max_s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> T_max)) return 0;\n    vector<int> initial_p(N * N);\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            int type;\n            if (row[j] >= 'a') type = row[j] - 'a' + 10;\n            else type = row[j] - '0';\n            int tile_id = i * N + j;\n            id_to_type[tile_id] = type;\n            initial_p[tile_id] = tile_id;\n            if (type == 0) {\n                initial_empty_r = i;\n                initial_empty_c = j;\n            }\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(12345);\n    string current_moves = \"\";\n    vector<int> current_p = initial_p;\n    int current_s = get_tree_score(current_p);\n\n    string best_moves = current_moves;\n    int best_s = current_s;\n\n    const double time_limit = 2.85;\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit) {\n        string next_moves = current_moves;\n        int action = rng() % 3;\n        if (action == 0 && next_moves.size() < (size_t)T_max) {\n            next_moves += \"UDLR\"[rng() % 4];\n        } else if (action == 1 && !next_moves.empty()) {\n            next_moves.pop_back();\n        } else if (action == 2 && !next_moves.empty()) {\n            next_moves[rng() % next_moves.size()] = \"UDLR\"[rng() % 4];\n        } else {\n            continue;\n        }\n\n        vector<int> p = initial_p;\n        int er = initial_empty_r, ec = initial_empty_c;\n        bool possible = true;\n        for (char m : next_moves) {\n            int nr = er, nc = ec;\n            if (m == 'U') nr--;\n            else if (m == 'D') nr++;\n            else if (m == 'L') nc--;\n            else if (m == 'R') nc++;\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                swap(p[er * N + ec], p[nr * N + nc]);\n                er = nr; ec = nc;\n            } else {\n                possible = false;\n                break;\n            }\n        }\n\n        if (possible) {\n            int s = get_tree_score(p);\n            // Optimization for the target: larger tree is always better,\n            // if size is equal, a shorter sequence is better to potentially solve it or get a higher bonus.\n            bool accept = false;\n            if (s > current_s) {\n                accept = true;\n            } else if (s == current_s) {\n                if (next_moves.size() <= current_moves.size()) accept = true;\n                else if (rng() % 100 < 5) accept = true; // Limited random walk\n            } else {\n                if (rng() % 1000 < 1) accept = true; // SA-like behavior\n            }\n\n            if (accept) {\n                current_moves = next_moves;\n                current_s = s;\n                if (current_s > best_s || (current_s == best_s && current_moves.size() < best_moves.size())) {\n                    best_s = current_s;\n                    best_moves = current_moves;\n                }\n            }\n        }\n    }\n\n    cout << best_moves << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Strawberry structure to keep track of its coordinates and its grid cell\nstruct Strawberry {\n    int x, y;\n    int sx, sy;\n    int posInSlabX;\n    int posInSlabY;\n};\n\n// Global counts and pieces\nint count_grid[52][52];\nint b[5505];\nint a[11];\nint current_sum_min = 0;\n\n// Efficient update of b_d and the score sum(min(a_d, b_d))\nvoid update_b(int d, int delta) {\n    if (d >= 1 && d <= 10) current_sum_min -= min(a[d], b[d]);\n    b[d] += delta;\n    if (d >= 1 && d <= 10) current_sum_min += min(a[d], b[d]);\n}\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K_limit;\n    if (!(cin >> N >> K_limit)) return 0;\n\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Strawberry> strawberries(N);\n    vector<int> all_x, all_y;\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        all_x.push_back(strawberries[i].x);\n        all_y.push_back(strawberries[i].y);\n    }\n\n    // kx and ky are the number of vertical and horizontal cuts, kx+ky <= 100\n    int kx = 50, ky = 50;\n    vector<int> X(kx + 2), Y(ky + 2);\n    X[0] = -1000000; X[kx + 1] = 1000000;\n    Y[0] = -1000000; Y[ky + 1] = 1000000;\n\n    // Initialize cuts based on strawberry density\n    sort(all_x.begin(), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    for (int i = 1; i <= kx; ++i) X[i] = all_x[i * N / (kx + 1)];\n    for (int j = 1; j <= ky; ++j) Y[j] = all_y[j * N / (ky + 1)];\n\n    // Ensure all cuts are strictly increasing and within integer point boundaries\n    for (int i = 1; i <= kx; ++i) if (X[i] <= X[i - 1]) X[i] = X[i - 1] + 1;\n    for (int i = kx; i >= 1; --i) if (X[i] >= X[i + 1]) X[i] = X[i + 1] - 1;\n    for (int j = 1; j <= ky; ++j) if (Y[j] <= Y[j - 1]) Y[j] = Y[j - 1] + 1;\n    for (int j = ky; j >= 1; --j) if (Y[j] >= Y[j + 1]) Y[j] = Y[j + 1] - 1;\n\n    vector<vector<int>> SlabX(kx + 1), SlabY(ky + 1);\n    for (int d = 0; d <= N; ++d) b[d] = 0;\n\n    // Assign strawberries to slabs and grid cells\n    for (int i = 0; i < N; ++i) {\n        int sx = 0;\n        while (sx < kx && strawberries[i].x > X[sx + 1]) sx++;\n        int sy = 0;\n        while (sy < ky && strawberries[i].y > Y[sy + 1]) sy++;\n\n        strawberries[i].sx = sx;\n        strawberries[i].sy = sy;\n        strawberries[i].posInSlabX = SlabX[sx].size();\n        SlabX[sx].push_back(i);\n        strawberries[i].posInSlabY = SlabY[sy].size();\n        SlabY[sy].push_back(i);\n\n        update_b(count_grid[sx][sy], -1);\n        count_grid[sx][sy]++;\n        update_b(count_grid[sx][sy], 1);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    long long iterations = 0;\n\n    // Optimization through Hill Climbing\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n        }\n        iterations++;\n\n        bool is_x = rng() % 2 == 0;\n        if (is_x) {\n            int i = rng() % kx + 1;\n            int oldX = X[i];\n            int range = X[i + 1] - X[i - 1] - 1;\n            if (range <= 0) continue;\n\n            int newX;\n            int r = rng() % 100;\n            if (r < 50) newX = X[i] + (rng() % 21 - 10);\n            else if (r < 80) newX = strawberries[rng() % N].x;\n            else newX = X[i - 1] + 1 + rng() % range;\n            if (newX <= X[i - 1] || newX >= X[i + 1]) newX = X[i - 1] + 1 + (rng() % range);\n            if (newX == oldX) continue;\n\n            vector<int> moved_k;\n            if (newX > oldX) {\n                for (int k : SlabX[i]) if (strawberries[k].x <= newX) moved_k.push_back(k);\n            } else {\n                for (int k : SlabX[i - 1]) if (strawberries[k].x > newX) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sy = strawberries[k].sy;\n                if (newX > oldX) { // move from SlabX[i] to SlabX[i-1]\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                } else { // move from SlabX[i-1] to SlabX[i]\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                }\n            }\n\n            // Accept if score improved or stayed the same (plateau-walking)\n            if (current_sum_min >= prev_sum) {\n                X[i] = newX;\n                for (int k : moved_k) {\n                    int old_sx = strawberries[k].sx;\n                    int new_sx = (newX > oldX) ? i - 1 : i;\n                    // Slab update: O(1) remove/add\n                    int pos = strawberries[k].posInSlabX;\n                    int last_k = SlabX[old_sx].back();\n                    SlabX[old_sx][pos] = last_k;\n                    strawberries[last_k].posInSlabX = pos;\n                    SlabX[old_sx].pop_back();\n                    strawberries[k].sx = new_sx;\n                    strawberries[k].posInSlabX = SlabX[new_sx].size();\n                    SlabX[new_sx].push_back(k);\n                }\n            } else { // Undo changes if rejected\n                for (int k : moved_k) {\n                    int sy = strawberries[k].sy;\n                    if (newX > oldX) {\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                    } else {\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                    }\n                }\n            }\n        } else {\n            // Symmetrical horizontal move\n            int j = rng() % ky + 1;\n            int oldY = Y[j];\n            int range = Y[j + 1] - Y[j - 1] - 1;\n            if (range <= 0) continue;\n\n            int newY;\n            int r = rng() % 100;\n            if (r < 50) newY = Y[j] + (rng() % 21 - 10);\n            else if (r < 80) newY = strawberries[rng() % N].y;\n            else newY = Y[j - 1] + 1 + rng() % range;\n            if (newY <= Y[j - 1] || newY >= Y[j + 1]) newY = Y[j - 1] + 1 + (rng() % range);\n            if (newY == oldY) continue;\n\n            vector<int> moved_k;\n            if (newY > oldY) {\n                for (int k : SlabY[j]) if (strawberries[k].y <= newY) moved_k.push_back(k);\n            } else {\n                for (int k : SlabY[j - 1]) if (strawberries[k].y > newY) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sx = strawberries[k].sx;\n                if (newY > oldY) { // move from SlabY[j] to SlabY[j-1]\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                } else { // move from SlabY[j-1] to SlabY[j]\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                }\n            }\n\n            if (current_sum_min >= prev_sum) {\n                Y[j] = newY;\n                for (int k : moved_k) {\n                    int old_sy = strawberries[k].sy;\n                    int new_sy = (newY > oldY) ? j - 1 : j;\n                    int pos = strawberries[k].posInSlabY;\n                    int last_k = SlabY[old_sy].back();\n                    SlabY[old_sy][pos] = last_k;\n                    strawberries[last_k].posInSlabY = pos;\n                    SlabY[old_sy].pop_back();\n                    strawberries[k].sy = new_sy;\n                    strawberries[k].posInSlabY = SlabY[new_sy].size();\n                    SlabY[new_sy].push_back(k);\n                }\n            } else {\n                for (int k : moved_k) {\n                    int sx = strawberries[k].sx;\n                    if (newY > oldY) {\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                    } else {\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                    }\n                }\n            }\n        }\n    }\n\n    // Output formatting\n    cout << kx + ky << endl;\n    for (int i = 1; i <= kx; ++i) {\n        // Vertical lines x ~ X[i] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << X[i] << \" -1000000000 \" << X[i] + 1 << \" 1000000000\" << endl;\n    }\n    for (int j = 1; j <= ky; ++j) {\n        // Horizontal lines y ~ Y[j] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << \"-1000000000 \" << Y[j] << \" 1000000000 \" << Y[j] + 1 << endl;\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Operation structure to store the coordinates of the chosen four points\nstruct Op {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\n// Movement vectors for the 8 possible directions (4 axis-parallel, 4 diagonal)\nconst int dx[] = {1, 1, 0, -1, -1, -1, 0, 1};\nconst int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};\n\n// Pairs of directions that form orthogonal segments for a rectangle\nconst pair<int, int> ortho[] = {\n    {0, 2}, {2, 4}, {4, 6}, {6, 0}, // Axis-parallel: Right-Up, Up-Left, Left-Down, Down-Right\n    {1, 3}, {3, 5}, {5, 7}, {7, 1}  // 45-degree: UR-UL, UL-DL, DL-DR, DR-UR\n};\n\nint N, M;\nlong long weights[61][61];\nbool init_has_dot[61][61];\nbool has_dot[61][61];\nbool used[61][61][8];\n\n// Function to mark a segment of the rectangle perimeter as used in the grid\nvoid mark_used(int x1, int y1, int x2, int y2, int d) {\n    int cx = x1, cy = y1;\n    while (cx != x2 || cy != y2) {\n        used[cx][cy][d] = true;\n        int nx = cx + dx[d], ny = cy + dy[d];\n        used[nx][ny][(d + 4) % 8] = true;\n        cx = nx; cy = ny;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read grid size N and initial number of dots M\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            init_has_dot[i][j] = false;\n        }\n    }\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        init_has_dot[x][y] = true;\n    }\n\n    // Precalculate weights for all grid points based on their distance from the center\n    double c = (N - 1) / 2.0;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            weights[x][y] = (long long)((x - c) * (x - c) + (y - c) * (y - c) + 1);\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    long long best_total_weight = -1;\n    vector<Op> best_ops;\n\n    // List of candidates for placing the first point p1 (initially empty points)\n    vector<pair<int, int>> p1_candidates;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (!init_has_dot[x][y]) p1_candidates.push_back({x, y});\n        }\n    }\n\n    int trial = 0;\n    // Multi-start greedy approach using different randomization/strategies per trial\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 4700) break;\n\n        // Reset the board for a new trial\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                has_dot[i][j] = init_has_dot[i][j];\n                for (int d = 0; d < 8; d++) used[i][j][d] = false;\n            }\n        }\n\n        vector<Op> current_ops;\n        long long current_total_weight = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (has_dot[x][y]) current_total_weight += weights[x][y];\n\n        // Variation of point ordering strategies to explore the solution space\n        if (trial == 0) {\n            sort(p1_candidates.begin(), p1_candidates.end(), [](pair<int, int> a, pair<int, int> b) {\n                return weights[a.first][a.second] < weights[b.first][b.second];\n            });\n        } else if (trial == 1) {\n            sort(p1_candidates.begin(), p1_candidates.end(), [](pair<int, int> a, pair<int, int> b) {\n                return weights[a.first][a.second] > weights[b.first][b.second];\n            });\n        } else {\n            shuffle(p1_candidates.begin(), p1_candidates.end(), rng);\n        }\n\n        // alpha parameter adjusts the preference for smaller vs. larger rectangles\n        double alpha = (trial == 0) ? 1.5 : (1.0 + (rng() % 1501) / 1000.0);\n\n        while (true) {\n            bool changed = false;\n            for (auto& p : p1_candidates) {\n                int x = p.first, y = p.second;\n                if (has_dot[x][y]) continue;\n\n                int best_d1 = -1, best_d2 = -1;\n                int bp2x, bp2y, bp3x, bp3y, bp4x, bp4y;\n                double min_score = 1e18;\n\n                // For each point p1, check all 8 possible rectangle configurations\n                for (int i = 0; i < 8; i++) {\n                    int d1 = ortho[i].first, d2 = ortho[i].second;\n\n                    // Scan for the nearest dot p2 in direction d1\n                    int p2x = x + dx[d1], p2y = y + dy[d1];\n                    while (p2x >= 0 && p2x < N && p2y >= 0 && p2y < N) {\n                        if (used[p2x - dx[d1]][p2y - dy[d1]][d1]) { p2x = -1; break; }\n                        if (has_dot[p2x][p2y]) break;\n                        p2x += dx[d1]; p2y += dy[d1];\n                    }\n                    if (p2x < 0 || p2x >= N || p2y < 0 || p2y >= N || !has_dot[p2x][p2y]) continue;\n\n                    // Scan for the nearest dot p4 in direction d2\n                    int p4x = x + dx[d2], p4y = y + dy[d2];\n                    while (p4x >= 0 && p4x < N && p4y >= 0 && p4y < N) {\n                        if (used[p4x - dx[d2]][p4y - dy[d2]][d2]) { p4x = -1; break; }\n                        if (has_dot[p4x][p4y]) break;\n                        p4x += dx[d2]; p4y += dy[d2];\n                    }\n                    if (p4x < 0 || p4x >= N || p4y < 0 || p4y >= N || !has_dot[p4x][p4y]) continue;\n\n                    // Determine coordinates of the opposite vertex p3\n                    int p3x = p2x + p4x - x, p3y = p2y + p4y - y;\n                    if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N || !has_dot[p3x][p3y]) continue;\n\n                    // Validate segment p2-p3 (no other dots, no used segments)\n                    int cx2 = p2x, cy2 = p2y;\n                    bool ok23 = true;\n                    while (cx2 != p3x || cy2 != p3y) {\n                        if (used[cx2][cy2][d2]) { ok23 = false; break; }\n                        cx2 += dx[d2]; cy2 += dy[d2];\n                        if (has_dot[cx2][cy2] && (cx2 != p3x || cy2 != p3y)) { ok23 = false; break; }\n                    }\n                    if (!ok23) continue;\n\n                    // Validate segment p4-p3 (no other dots, no used segments)\n                    int cx4 = p4x, cy4 = p4y;\n                    bool ok43 = true;\n                    while (cx4 != p3x || cy4 != p3y) {\n                        if (used[cx4][cy4][d1]) { ok43 = false; break; }\n                        cx4 += dx[d1]; cy4 += dy[d1];\n                        if (has_dot[cx4][cy4] && (cx4 != p3x || cy4 != p3y)) { ok43 = false; break; }\n                    }\n                    if (!ok43) continue;\n\n                    // Calculate score to decide the best move (favoring smaller rectangles)\n                    int dist1 = max(abs(x - p2x), abs(y - p2y));\n                    int dist2 = max(abs(x - p4x), abs(y - p4y));\n                    double score = pow((double)(dist1 * dist1 + dist2 * dist2), alpha);\n                    if (score < min_score) {\n                        min_score = score;\n                        best_d1 = d1; best_d2 = d2;\n                        bp2x = p2x; bp2y = p2y; bp3x = p3x; bp3y = p3y; bp4x = p4x; bp4y = p4y;\n                    }\n                }\n\n                // If a valid rectangle is found, place the dot and mark edges\n                if (best_d1 != -1) {\n                    has_dot[x][y] = true;\n                    mark_used(x, y, bp2x, bp2y, best_d1);\n                    mark_used(bp2x, bp2y, bp3x, bp3y, best_d2);\n                    mark_used(bp3x, bp3y, bp4x, bp4y, (best_d1 + 4) % 8);\n                    mark_used(bp4x, bp4y, x, y, (best_d2 + 4) % 8);\n                    current_ops.push_back({x, y, bp2x, bp2y, bp3x, bp3y, bp4x, bp4y});\n                    current_total_weight += weights[x][y];\n                    changed = true;\n                }\n            }\n            if (!changed) break; // Terminate current trial if no more dots can be added\n        }\n\n        // Keep track of the best sequence of operations across all trials\n        if (current_total_weight > best_total_weight) {\n            best_total_weight = current_total_weight;\n            best_ops = current_ops;\n        }\n        trial++;\n    }\n\n    // Output the total number of operations and details for each operation\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.x1 << \" \" << op.y1 << \" \" << op.x2 << \" \" << op.y2 << \" \"\n             << op.x3 << \" \" << op.y3 << \" \" << op.x4 << \" \" << op.y4 << \"\\n\";\n    }\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <chrono>\n#include <algorithm>\n#include <cstdint>\n\nusing namespace std;\nusing namespace std::chrono;\n\n/**\n * Xorshift algorithm for fast pseudo-random number generation.\n * Essential for getting more Monte Carlo trials within the time limit.\n */\nstruct Xorshift {\n    uint32_t x;\n    Xorshift(uint32_t seed = 123456789) : x(seed) {}\n    uint32_t next() {\n        x ^= (x << 13);\n        x ^= (x >> 17);\n        x ^= (x << 5);\n        return x;\n    }\n};\n\n/**\n * Represents the 10x10 candy box grid.\n * We use a 1D array of 100 elements for better cache performance.\n */\nstruct Board {\n    int8_t grid[100]; // 0: empty, 1-3: flavors\n\n    Board() {\n        for (int i = 0; i < 100; ++i) grid[i] = 0;\n    }\n\n    /**\n     * Tilts the box in the specified direction.\n     * 0: Forward (Up), 1: Backward (Down), 2: Left, 3: Right.\n     */\n    bool tilt(int dir) {\n        bool changed = false;\n        if (dir == 0) { // Up\n            for (int j = 0; j < 10; ++j) {\n                int last = 0;\n                for (int i = 0; i < 10; ++i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 1) { // Down\n            for (int j = 0; j < 10; ++j) {\n                int last = 9;\n                for (int i = 9; i >= 0; --i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        } else if (dir == 2) { // Left\n            for (int i = 0; i < 10; ++i) {\n                int last = 0;\n                for (int j = 0; j < 10; ++j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 3) { // Right\n            for (int i = 0; i < 10; ++i) {\n                int last = 9;\n                for (int j = 9; j >= 0; --j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * Places the actual candy received into the p-th available empty cell.\n     */\n    void place_actual(int p, int flavor) {\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                if (++count == p) {\n                    grid[i] = (int8_t)flavor;\n                    return;\n                }\n            }\n        }\n    }\n\n    /**\n     * Randomly places a candy of the given flavor into an empty cell.\n     */\n    void place_randomly(int flavor, Xorshift& rng) {\n        int empty_indices[100], num_empty = 0;\n        for (int i = 0; i < 100; ++i) if (grid[i] == 0) empty_indices[num_empty++] = i;\n        if (num_empty > 0) {\n            grid[empty_indices[rng.next() % num_empty]] = (int8_t)flavor;\n        }\n    }\n\n    /**\n     * Calculates the sum of squares of connected component sizes.\n     * Note: This function modifies the grid to mark visited nodes.\n     */\n    int eval_score_and_destroy() {\n        int sum_sq = 0;\n        int q[100];\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] <= 0) continue;\n            int head = 0, tail = 0, flavor = grid[i];\n            q[tail++] = i;\n            grid[i] = -flavor; // Mark as visited\n            while (head < tail) {\n                int cur = q[head++];\n                if (cur >= 10 && grid[cur - 10] == flavor) { grid[cur - 10] = -flavor; q[tail++] = cur - 10; }\n                if (cur < 90 && grid[cur + 10] == flavor) { grid[cur + 10] = -flavor; q[tail++] = cur + 10; }\n                if (cur % 10 > 0 && grid[cur - 1] == flavor) { grid[cur - 1] = -flavor; q[tail++] = cur - 1; }\n                if (cur % 10 < 9 && grid[cur + 1] == flavor) { grid[cur + 1] = -flavor; q[tail++] = cur + 1; }\n            }\n            sum_sq += tail * tail;\n        }\n        return sum_sq;\n    }\n};\n\n// 4 different corner-clustering strategies for rollouts\nconst int policies[4][4] = {\n    {0, 2, 3, 1}, // Up, Left priority (Top-Left corner)\n    {0, 3, 2, 1}, // Up, Right priority (Top-Right corner)\n    {1, 2, 3, 0}, // Down, Left priority (Bottom-Left corner)\n    {1, 3, 2, 0}  // Down, Right priority (Bottom-Right corner)\n};\n\ninline void apply_policy(Board& b, int p_idx) {\n    const int* p = policies[p_idx];\n    if (b.tilt(p[0])) return;\n    if (b.tilt(p[1])) return;\n    if (b.tilt(p[2])) return;\n    b.tilt(p[3]);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Xorshift rng;\n    Board current_board;\n    char d_chars[] = {'F', 'B', 'L', 'R'};\n    auto start_prog = steady_clock::now();\n\n    for (int t = 0; t < 100; ++t) {\n        int p; cin >> p;\n        current_board.place_actual(p, flavors[t]);\n\n        auto turn_start = steady_clock::now();\n        double elapsed = duration<double>(turn_start - start_prog).count();\n        double turn_time = (1.95 - elapsed) / (100.0 - t);\n        if (turn_time < 0.002) turn_time = 0.002;\n\n        double scores[4] = {0};\n        int trials[4] = {0};\n        int total_trials = 0;\n        int d_idx = rng.next() % 4;\n\n        while (true) {\n            if (total_trials % 32 == 0) {\n                if (duration<double>(steady_clock::now() - turn_start).count() > turn_time) break;\n            }\n\n            int d = d_idx % 4;\n            Board sim = current_board;\n            sim.tilt(d);\n\n            int p_idx = rng.next() % 4; // Use one of the 4 corner policies\n            for (int k = t + 1; k < 100; ++k) {\n                sim.place_randomly(flavors[k], rng);\n                apply_policy(sim, p_idx);\n            }\n\n            scores[d] += sim.eval_score_and_destroy();\n            trials[d]++;\n            total_trials++;\n            d_idx++;\n        }\n\n        int best_d = 0;\n        double max_avg = -1.0;\n        for (int d = 0; d < 4; ++d) {\n            if (trials[d] > 0) {\n                double avg = scores[d] / trials[d];\n                if (avg > max_avg) {\n                    max_avg = avg;\n                    best_d = d;\n                }\n            }\n        }\n\n        cout << d_chars[best_d] << endl;\n        current_board.tilt(best_d);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Normal CDF function: Phi(x) = 0.5 * (1 + erf((x - mean) / (sigma * sqrt(2))))\n * This function calculates the probability that a random variable following a normal \n * distribution with the given mean and sigma is less than x.\n */\ndouble normal_cdf(double x, double mean, double sigma) {\n    if (sigma < 1e-9) {\n        if (x < mean) return 0.0;\n        if (x > mean) return 1.0;\n        return 0.5;\n    }\n    return 0.5 * (1.0 + erf((x - mean) / (sigma * sqrt(2.0))));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double eps;\n    // Read the number of graphs M and the error rate epsilon.\n    if (!(cin >> M >> eps)) return 0;\n\n    int bestN = 4;\n    double bestExpectedScore = -1.0;\n\n    // Iterate through all possible values for N (the number of vertices) to find the one that \n    // maximizes the expected score. The score is calculated based on the expected number of \n    // errors using an edge count encoding/decoding method.\n    for (int N = 4; N <= 100; ++N) {\n        int K = N * (N - 1) / 2; // Maximum number of possible edges.\n        vector<int> Es(M);\n        for (int s = 0; s < M; ++s) {\n            // Encode the number of edges for each graph G_s.\n            Es[s] = (int)round((double)s * K / (M - 1));\n        }\n\n        // Standard deviation of the edge count after noise (Binomial sum approximation).\n        double sigma = sqrt((double)K * eps * (1.0 - eps));\n        double P_avg = 0.0;\n\n        for (int s = 0; s < M; ++s) {\n            // Count how many graphs have the same number of edges as G_s.\n            int c = 0;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] == Es[s]) c++;\n            }\n\n            // The expected mean number of edges in the noisy graph H generated from G_s.\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n\n            // Find the closest different edge counts to identify the decision boundaries.\n            double E_prev = -1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] < Es[s]) {\n                    if (E_prev < -1e17 || Es[j] > E_prev) {\n                        E_prev = (double)Es[j];\n                    }\n                }\n            }\n\n            double E_next = 1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] > Es[s]) {\n                    if (E_next > 1e17 || Es[j] < E_next) {\n                        E_next = (double)Es[j];\n                    }\n                }\n            }\n\n            double low, high;\n            if (E_prev < -1e17) {\n                low = -1e18; // No lower bound for the first category.\n            } else {\n                double mu_prev = E_prev * (1.0 - 2.0 * eps) + (double)K * eps;\n                low = (mu_s + mu_prev) / 2.0;\n            }\n\n            if (E_next > 1e17) {\n                high = 1e18; // No upper bound for the last category.\n            } else {\n                double mu_next = E_next * (1.0 - 2.0 * eps) + (double)K * eps;\n                high = (mu_s + mu_next) / 2.0;\n            }\n\n            // Estimate the probability of correct decoding for the s-th graph.\n            double prob_correct_in_range;\n            if (sigma < 1e-9) {\n                prob_correct_in_range = 1.0;\n            } else {\n                prob_correct_in_range = normal_cdf(high, mu_s, sigma) - normal_cdf(low, mu_s, sigma);\n            }\n            // If multiple graphs have the same edge count, they are indistinguishable.\n            P_avg += prob_correct_in_range / (double)c;\n        }\n\n        // Calculate the overall expected probability of a correct prediction.\n        P_avg /= (double)M;\n        double p_error = 1.0 - P_avg;\n        // Expected absolute score formula: (1 - 0.1 * p_error)^100 / N.\n        double expectedScore = pow(1.0 - 0.1 * p_error, 100) / (double)N;\n\n        if (expectedScore > bestExpectedScore) {\n            bestExpectedScore = expectedScore;\n            bestN = N;\n        }\n    }\n\n    // Set up the selected N and the corresponding graphs G_0, ..., G_{M-1}.\n    int N = bestN;\n    int K = N * (N - 1) / 2;\n    vector<int> Es(M);\n    for (int s = 0; s < M; ++s) {\n        Es[s] = (int)round((double)s * K / (M - 1));\n    }\n\n    // Output the chosen number of vertices N.\n    cout << N << endl;\n    // Output the string representations for the M graphs.\n    for (int s = 0; s < M; ++s) {\n        string g(K, '0');\n        for (int i = 0; i < Es[s]; ++i) {\n            g[i] = '1';\n        }\n        cout << g << endl;\n    }\n    cout.flush();\n\n    // Process 100 noisy graph queries.\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        if (!(cin >> H)) break;\n        // Count the number of edges in the received graph H.\n        int EH = 0;\n        for (char c : H) {\n            if (c == '1') EH++;\n        }\n\n        // Find the graph s whose expected noisy edge count mean is closest to EH.\n        int best_s = 0;\n        double min_diff = 1e18;\n        for (int s = 0; s < M; ++s) {\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n            double diff = abs((double)EH - mu_s);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        // Output the prediction for the current query.\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Takahashi City Road Repair Problem\n * \n * Objective: Minimize the total frustration level for road repairs over D days.\n * Frustration is defined as the expected increase in the shortest path distance\n * between vertices when some edges are closed for repair.\n * \n * Strategy:\n * 1. Initial Assignment: Sort edges based on their spatial orientation (angle from \n *    the centroid of the city). Distribute them across D days using round-robin. \n *    This ensures that roads under repair on any given day are spread out spatially.\n * 2. Proxy Frustration Function: Instead of all-pairs shortest paths, calculate \n *    shortest paths from a set of S=12 source vertices chosen via Farthest Point \n *    Sampling (FPS) for better coverage.\n * 3. Local Optimization (Hill Climbing): Perform as many iterations as possible \n *    within the time limit (5.8s). Iterations involve swapping repair days for \n *    two edges or moving an edge from one day to another, targeted at reducing \n *    the frustration of the worst days.\n */\n\nconst int INF = 1000000000;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int to, weight, id;\n};\n\n// Problem data\nvector<Edge> adj[MAXN];\nint edge_u[MAXM], edge_v[MAXM], edge_w[MAXM];\nint edge_day_arr[MAXM];\nint base_dists[15][MAXN]; // Original shortest distances from S sources\nint X[MAXN], Y[MAXN];\nint N, M, D, K;\n\n// Dijkstra global state for efficiency\nint dists[MAXN];\nint vis[MAXN];\nint timer = 0;\nvector<int> sources;\n\n/**\n * Fast Dijkstra's algorithm.\n * Skips edges assigned to be repaired on 'repair_day'.\n */\nvoid dijkstra(int start, int repair_day) {\n    timer++;\n    dists[start] = 0;\n    vis[start] = timer;\n    using P = pair<int, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, start});\n    \n    while (!pq.empty()) {\n        P top = pq.top(); pq.pop();\n        int d = top.first;\n        int u = top.second;\n        if (d > dists[u]) continue;\n        \n        for (const auto& e : adj[u]) {\n            if (edge_day_arr[e.id] == repair_day) continue;\n            int vd = d + e.weight;\n            if (vis[e.to] != timer || vd < dists[e.to]) {\n                dists[e.to] = vd;\n                vis[e.to] = timer;\n                pq.push({vd, e.to});\n            }\n        }\n    }\n}\n\n/**\n * Proxy for day's frustration: sum over source nodes of path distance increases.\n */\nlong long compute_frustration(int day) {\n    long long total = 0;\n    for (int i = 0; i < (int)sources.size(); ++i) {\n        dijkstra(sources[i], day);\n        for (int j = 1; j <= N; ++j) {\n            int d_orig = base_dists[i][j];\n            int d_new = (vis[j] == timer) ? min(dists[j], INF) : INF;\n            total += (long long)(d_new - d_orig);\n        }\n    }\n    return total;\n}\n\nstruct EdgeInfo {\n    int id;\n    double angle;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    for (int i = 1; i <= M; ++i) {\n        cin >> edge_u[i] >> edge_v[i] >> edge_w[i];\n        adj[edge_u[i]].push_back({edge_v[i], edge_w[i], i});\n        adj[edge_v[i]].push_back({edge_u[i], edge_w[i], i});\n    }\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    mt19937 rng(1337);\n\n    // 1. Select representative source vertices for proxy scoring.\n    int S_count = 12;\n    sources.push_back(1);\n    for (int i = 1; i < S_count; ++i) {\n        int best_v = -1;\n        long long max_d = -1;\n        for (int v = 1; v <= N; ++v) {\n            long long min_d = 1e18;\n            for (int s : sources) {\n                long long d = (long long)(X[v]-X[s])*(X[v]-X[s]) + (long long)(Y[v]-Y[s])*(Y[v]-Y[s]);\n                if (d < min_d) min_d = d;\n            }\n            if (min_d > max_d) {\n                max_d = min_d;\n                best_v = v;\n            }\n        }\n        sources.push_back(best_v);\n    }\n\n    // 2. Precompute original shortest paths from sources.\n    for (int i = 0; i < S_count; ++i) {\n        for (int j = 1; j <= M; j++) edge_day_arr[j] = -1;\n        dijkstra(sources[i], -2);\n        for (int j = 1; j <= N; ++j) {\n            base_dists[i][j] = (vis[j] == timer) ? min(dists[j], INF) : INF;\n        }\n    }\n\n    // 3. Spatially sorted initial assignment.\n    double cx = 0, cy = 0;\n    for (int i = 1; i <= N; ++i) { cx += X[i]; cy += Y[i]; }\n    cx /= N; cy /= N;\n    vector<EdgeInfo> sorted_edges(M);\n    for (int i = 1; i <= M; ++i) {\n        double mx = (X[edge_u[i]] + X[edge_v[i]]) / 2.0;\n        double my = (Y[edge_u[i]] + Y[edge_v[i]]) / 2.0;\n        sorted_edges[i-1] = {i, atan2(my - cy, mx - cx)};\n    }\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const EdgeInfo& a, const EdgeInfo& b) {\n        return a.angle < b.angle;\n    });\n\n    vector<vector<int>> day_lists(D + 1);\n    for (int i = 0; i < M; ++i) {\n        int d = (i % D) + 1;\n        edge_day_arr[sorted_edges[i].id] = d;\n        day_lists[d].push_back(sorted_edges[i].id);\n    }\n\n    vector<long long> day_frust(D + 1);\n    for (int d = 1; d <= D; ++d) day_frust[d] = compute_frustration(d);\n\n    // 4. Optimization Loop (Hill Climbing).\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    while (true) {\n        if ((++iterations & 15) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5800) break;\n        }\n\n        int d1, d2;\n        // Bias towards picking the day with the highest frustration.\n        if (uniform_int_distribution<int>(0, 9)(rng) < 8) {\n            int best_d = 1;\n            for (int d = 2; d <= D; d++) if (day_frust[d] > day_frust[best_d]) best_d = d;\n            d1 = best_d;\n            if (day_frust[d1] == 0) d1 = uniform_int_distribution<int>(1, D)(rng);\n        } else {\n            d1 = uniform_int_distribution<int>(1, D)(rng);\n        }\n        d2 = uniform_int_distribution<int>(1, D)(rng);\n        while (d1 == d2) d2 = uniform_int_distribution<int>(1, D)(rng);\n\n        if (day_lists[d1].empty()) continue;\n\n        int op = uniform_int_distribution<int>(0, 9)(rng);\n        if (op < 2 && (int)day_lists[d2].size() < K) {\n            // Move operation: move edge from d1 to d2.\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            edge_day_arr[e1] = d2;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1;\n                day_frust[d2] = nf2;\n                day_lists[d2].push_back(e1);\n                day_lists[d1][idx1] = day_lists[d1].back();\n                day_lists[d1].pop_back();\n            } else {\n                edge_day_arr[e1] = d1;\n            }\n        } else if (!day_lists[d2].empty()) {\n            // Swap operation: swap edges between d1 and d2.\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int idx2 = uniform_int_distribution<int>(0, (int)day_lists[d2].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            int e2 = day_lists[d2][idx2];\n            edge_day_arr[e1] = d2;\n            edge_day_arr[e2] = d1;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1;\n                day_frust[d2] = nf2;\n                day_lists[d1][idx1] = e2;\n                day_lists[d2][idx2] = e1;\n            } else {\n                edge_day_arr[e1] = d1;\n                edge_day_arr[e2] = d2;\n            }\n        }\n    }\n\n    // Output result.\n    for (int i = 1; i <= M; ++i) {\n        cout << edge_day_arr[i] << (i == M ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n// Coordinate structure for voxels\nstruct Voxel {\n    int x, y, z;\n    bool operator<(const Voxel& o) const {\n        if (x != o.x) return x < o.x;\n        if (y != o.y) return y < o.y;\n        return z < o.z;\n    }\n};\n\n// Standard rotations for 90-degree axis changes\nVoxel rotX(Voxel v) { return {v.x, -v.z, v.y}; }\nVoxel rotY(Voxel v) { return {v.z, v.y, -v.x}; }\nVoxel rotZ(Voxel v) { return {-v.y, v.x, v.z}; }\n\n// Pre-calculate all 24 possible 90-degree rotations\nvector<vector<Voxel>> get_rotations() {\n    set<vector<Voxel>> unique_rots;\n    vector<Voxel> unit_cube = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};\n    for (int i = 0; i < 4; ++i) {\n        for (int j = 0; j < 4; ++j) {\n            for (int k = 0; k < 4; ++k) {\n                vector<Voxel> current = unit_cube;\n                for (int ii = 0; ii < i; ++ii) for (auto& v : current) v = rotX(v);\n                for (int jj = 0; jj < j; ++jj) for (auto& v : current) v = rotY(v);\n                for (int kk = 0; kk < k; ++kk) for (auto& v : current) v = rotZ(v);\n                unique_rots.insert(current);\n            }\n        }\n    }\n    vector<vector<Voxel>> res;\n    for (auto& rot : unique_rots) res.push_back(rot);\n    return res;\n}\n\nint D;\nstring f1[14], r1[14], f2[14], r2[14];\n\nstruct State {\n    int r_idx;\n    int dx, dy, dz;\n    double score = 1e18;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> D)) return 0;\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    // Q1 and Q2 are the maximal sets of voxels satisfying the silhouette requirements\n    vector<Voxel> Q1, Q2;\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 (f1[z][x] == '1' && r1[z][y] == '1') Q1.push_back({x, y, z});\n                if (f2[z][x] == '1' && r2[z][y] == '1') Q2.push_back({x, y, z});\n            }\n        }\n    }\n\n    auto rots = get_rotations();\n    vector<vector<Voxel>> Q2_rots(rots.size());\n    for (int i = 0; i < rots.size(); ++i) {\n        for (auto& v : Q2) {\n            Voxel rv;\n            rv.x = v.x * rots[i][0].x + v.y * rots[i][1].x + v.z * rots[i][2].x;\n            rv.y = v.x * rots[i][0].y + v.y * rots[i][1].y + v.z * rots[i][2].y;\n            rv.z = v.x * rots[i][0].z + v.y * rots[i][1].z + v.z * rots[i][2].z;\n            Q2_rots[i].push_back(rv);\n        }\n    }\n\n    State best_state;\n    static bool q2_rot_grid[60][60][60];\n\n    for (int ri = 0; ri < (int)rots.size(); ++ri) {\n        int min_x = 100, max_x = -100, min_y = 100, max_y = -100, min_z = 100, max_z = -100;\n        for (auto& v : Q2_rots[ri]) {\n            min_x = min(min_x, v.x); max_x = max(max_x, v.x);\n            min_y = min(min_y, v.y); max_y = max(max_y, v.y);\n            min_z = min(min_z, v.z); max_z = max(max_z, v.z);\n        }\n        \n        for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid[i][j][k] = false;\n        for (auto& v : Q2_rots[ri]) q2_rot_grid[v.x + 30][v.y + 30][v.z + 30] = true;\n\n        for (int dx = -(max_x + 1); dx <= D - min_x; ++dx) {\n            for (int dy = -(max_y + 1); dy <= D - min_y; ++dy) {\n                for (int dz = -(max_z + 1); dz <= D - min_z; ++dz) {\n                    vector<Voxel> S;\n                    bool s_f1[14][14] = {false}, s_r1[14][14] = {false};\n                    bool s_f2[14][14] = {false}, s_r2[14][14] = {false};\n                    \n                    for (auto& v : Q1) {\n                        if (q2_rot_grid[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) {\n                            S.push_back(v);\n                            s_f1[v.z][v.x] = true;\n                            s_r1[v.z][v.y] = true;\n                            \n                            int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n                            int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n                            int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n                            s_f2[oz][ox] = true;\n                            s_r2[oz][oy] = true;\n                        }\n                    }\n                    if (S.empty()) continue;\n\n                    int n1 = 0, n2 = 0;\n                    for (int z = 0; z < D; ++z) {\n                        int uf1 = 0, ur1 = 0, uf2 = 0, ur2 = 0;\n                        for (int x = 0; x < D; ++x) if (f1[z][x] == '1' && !s_f1[z][x]) uf1++;\n                        for (int y = 0; y < D; ++y) if (r1[z][y] == '1' && !s_r1[z][y]) ur1++;\n                        n1 += max(uf1, ur1);\n                        for (int x = 0; x < D; ++x) if (f2[z][x] == '1' && !s_f2[z][x]) uf2++;\n                        for (int y = 0; y < D; ++y) if (r2[z][y] == '1' && !s_r2[z][y]) ur2++;\n                        n2 += max(uf2, ur2);\n                    }\n\n                    if (max(n1, n2) > best_state.score) continue;\n\n                    double sum1v = 0;\n                    vector<bool> visited(S.size(), false);\n                    for (int i = 0; i < (int)S.size(); ++i) {\n                        if (!visited[i]) {\n                            int count = 0;\n                            queue<int> q; q.push(i); visited[i] = true;\n                            while (!q.empty()) {\n                                int u = q.front(); q.pop();\n                                count++;\n                                for (int v = 0; v < (int)S.size(); ++v) {\n                                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                                        visited[v] = true; q.push(v);\n                                    }\n                                }\n                            }\n                            sum1v += 1.0 / count;\n                        }\n                    }\n\n                    if (max(n1, n2) + sum1v < best_state.score) {\n                        best_state = {ri, dx, dy, dz, max(n1, n2) + sum1v};\n                    }\n                }\n            }\n        }\n    }\n\n    // Finalize output with the best rotation and translation found\n    int ri = best_state.r_idx;\n    int dx = best_state.dx, dy = best_state.dy, dz = best_state.dz;\n    vector<Voxel> S;\n    static bool q2_rot_grid_final[60][60][60];\n    for (int i = 0; i < 60; ++i) for (int j = 0; j < 60; ++j) for (int k = 0; k < 60; ++k) q2_rot_grid_final[i][j][k] = false;\n    for (auto& v : Q2_rots[ri]) q2_rot_grid_final[v.x + 30][v.y + 30][v.z + 30] = true;\n    for (auto& v : Q1) if (q2_rot_grid_final[v.x - dx + 30][v.y - dy + 30][v.z - dz + 30]) S.push_back(v);\n\n    static int b1[14][14][14], b2[14][14][14];\n    for (int i = 0; i < 14; ++i) for (int j = 0; j < 14; ++j) for (int k = 0; k < 14; ++k) b1[i][j][k] = b2[i][j][k] = 0;\n    int block_id = 1;\n\n    vector<bool> visited(S.size(), false);\n    for (int i = 0; i < (int)S.size(); ++i) {\n        if (!visited[i]) {\n            queue<int> q; q.push(i); visited[i] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                b1[S[u].x][S[u].y][S[u].z] = block_id;\n                int ox = (S[u].x - dx) * rots[ri][0].x + (S[u].y - dy) * rots[ri][0].y + (S[u].z - dz) * rots[ri][0].z;\n                int oy = (S[u].x - dx) * rots[ri][1].x + (S[u].y - dy) * rots[ri][1].y + (S[u].z - dz) * rots[ri][1].z;\n                int oz = (S[u].x - dx) * rots[ri][2].x + (S[u].y - dy) * rots[ri][2].y + (S[u].z - dz) * rots[ri][2].z;\n                b2[ox][oy][oz] = block_id;\n                for (int v = 0; v < (int)S.size(); ++v) {\n                    if (!visited[v] && abs(S[u].x - S[v].x) + abs(S[u].y - S[v].y) + abs(S[u].z - S[v].z) == 1) {\n                        visited[v] = true; q.push(v);\n                    }\n                }\n            }\n            block_id++;\n        }\n    }\n\n    auto get_extra_voxels = [&](const vector<Voxel>& s, const string* f, const string* r) {\n        vector<Voxel> extra_voxels;\n        bool s_f[14][14] = {false}, s_r[14][14] = {false};\n        for (auto& v : s) { s_f[v.z][v.x] = true; s_r[v.z][v.y] = true; }\n        for (int z = 0; z < D; ++z) {\n            vector<int> uf, ur;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1' && !s_f[z][x]) uf.push_back(x);\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1' && !s_r[z][y]) ur.push_back(y);\n            if (uf.empty() && ur.empty()) continue;\n            int any_x = -1, any_y = -1;\n            for (int x = 0; x < D; ++x) if (f[z][x] == '1') { any_x = x; break; }\n            for (int y = 0; y < D; ++y) if (r[z][y] == '1') { any_y = y; break; }\n            int m = max((int)uf.size(), (int)ur.size());\n            for (int i = 0; i < m; ++i) {\n                extra_voxels.push_back({(i < (int)uf.size()) ? uf[i] : any_x, (i < (int)ur.size()) ? ur[i] : any_y, z});\n            }\n        }\n        return extra_voxels;\n    };\n\n    vector<Voxel> S_in_Q2_orig;\n    for (auto& v : S) {\n        int ox = (v.x - dx) * rots[ri][0].x + (v.y - dy) * rots[ri][0].y + (v.z - dz) * rots[ri][0].z;\n        int oy = (v.x - dx) * rots[ri][1].x + (v.y - dy) * rots[ri][1].y + (v.z - dz) * rots[ri][1].z;\n        int oz = (v.x - dx) * rots[ri][2].x + (v.y - dy) * rots[ri][2].y + (v.z - dz) * rots[ri][2].z;\n        S_in_Q2_orig.push_back({ox, oy, oz});\n    }\n\n    auto extra1 = get_extra_voxels(S, f1, r1);\n    auto extra2 = get_extra_voxels(S_in_Q2_orig, f2, r2);\n\n    int k = min((int)extra1.size(), (int)extra2.size());\n    for (int i = 0; i < k; ++i) {\n        b1[extra1[i].x][extra1[i].y][extra1[i].z] = b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n    }\n    for (int i = k; i < (int)extra1.size(); ++i) b1[extra1[i].x][extra1[i].y][extra1[i].z] = block_id++;\n    for (int i = k; i < (int)extra2.size(); ++i) b2[extra2[i].x][extra2[i].y][extra2[i].z] = block_id++;\n\n    cout << block_id - 1 << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b1[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n    for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n        cout << b2[x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n + 1);\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    void reset(int n) {\n        for (int i = 0; i <= n; ++i) parent[i] = i;\n    }\n};\n\nlong long dist2_pts(int x1, int y1, int x2, int y2) {\n    return (long long)(x1 - x2) * (x1 - x2) + (long long)(y1 - y2) * (y1 - y2);\n}\n\nconst long long PENALTY = 1e15;\n\nint main() {\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<pair<int, int>> vertices(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> vertices[i].first >> vertices[i].second;\n\n    vector<Edge> edges(M);\n    vector<vector<int>> adj(N + 1);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) cin >> residents[k].first >> residents[k].second;\n\n    vector<vector<long long>> dist(N + 1, vector<long long>(N + 1, 1e15));\n    for (int i = 1; i <= N; ++i) dist[i][i] = 0;\n    for (int j = 0; j < M; ++j) {\n        dist[edges[j].u][edges[j].v] = min(dist[edges[j].u][edges[j].v], (long long)edges[j].w);\n        dist[edges[j].v][edges[j].u] = min(dist[edges[j].v][edges[j].u], (long long)edges[j].w);\n    }\n\n    for (int k = 1; k <= N; ++k)\n        for (int i = 1; i <= N; ++i)\n            for (int j = 1; j <= N; ++j)\n                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n\n    vector<int> path_edges[101][101];\n    for (int i = 1; i <= N; ++i) {\n        for (int j = 1; j <= N; ++j) {\n            if (i == j) continue;\n            int curr = i;\n            while (curr != j) {\n                bool found = false;\n                for (int e_idx : adj[curr]) {\n                    int next = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);\n                    if (edges[e_idx].w + dist[next][j] == dist[curr][j]) {\n                        path_edges[i][j].push_back(e_idx);\n                        curr = next;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n    }\n\n    vector<vector<long long>> dist2_v_r(N + 1, vector<long long>(K));\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dist2_v_r[i][k] = dist2_pts(vertices[i].first, vertices[i].second, residents[k].first, residents[k].second);\n        }\n    }\n\n    vector<vector<int>> sorted_v_for_r(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        iota(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), 1);\n        sort(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), [&](int a, int b) {\n            return dist2_v_r[a][k] < dist2_v_r[b][k];\n        });\n    }\n\n    vector<bool> is_active(N + 1, true);\n    vector<int> nearest_v(K);\n    for (int k = 0; k < K; ++k) nearest_v[k] = sorted_v_for_r[k][0];\n\n    auto start_time = chrono::steady_clock::now();\n    \n    static long long max_d2[101];\n    static int v_req_list[101];\n    static long long prim_min_d[101];\n    static bool prim_visited[101];\n\n    auto get_total_cost = [&]() {\n        for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n        for (int k = 0; k < K; ++k) {\n            if (dist2_v_r[nearest_v[k]][k] > max_d2[nearest_v[k]]) {\n                max_d2[nearest_v[k]] = dist2_v_r[nearest_v[k]][k];\n            }\n        }\n\n        long long coverage_cost = 0;\n        int n_req = 0;\n        v_req_list[n_req++] = 1;\n        for (int i = 1; i <= N; ++i) {\n            if (max_d2[i] > 0) {\n                if (i != 1) v_req_list[n_req++] = i;\n                if (max_d2[i] > 25000000LL) coverage_cost += PENALTY;\n                else {\n                    long long p = (long long)sqrt(max_d2[i]);\n                    while (p * p < max_d2[i]) p++;\n                    coverage_cost += p * p;\n                }\n            }\n        }\n\n        long long tree_cost = 0;\n        if (n_req > 1) {\n            for (int i = 0; i < n_req; ++i) { prim_min_d[i] = 2e15; prim_visited[i] = false; }\n            prim_min_d[0] = 0;\n            for (int i = 0; i < n_req; ++i) {\n                int u = -1;\n                for (int j = 0; j < n_req; ++j) {\n                    if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n                }\n                if (u == -1) break;\n                prim_visited[u] = true;\n                tree_cost += prim_min_d[u];\n                for (int v = 0; v < n_req; ++v) {\n                    if (!prim_visited[v]) {\n                        long long d = dist[v_req_list[u]][v_req_list[v]];\n                        if (d < prim_min_d[v]) prim_min_d[v] = d;\n                    }\n                }\n            }\n        }\n        return coverage_cost + tree_cost;\n    };\n\n    long long cur_cost = get_total_cost();\n    long long best_cost = cur_cost;\n    vector<bool> best_is_active = is_active;\n\n    mt19937 rng(42);\n    uniform_real_distribution<double> dist_unif(0, 1);\n    uniform_int_distribution<int> dist_v(2, N);\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 511) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n            if (elapsed > 1850) break;\n            \n            // Randomly reset to best to escape local optima occasionally\n            if (iter > 0 && dist_unif(rng) < 0.005) {\n                is_active = best_is_active;\n                for (int k = 0; k < K; ++k) {\n                    for (int nv : sorted_v_for_r[k]) {\n                        if (is_active[nv]) { nearest_v[k] = nv; break; }\n                    }\n                }\n                cur_cost = get_total_cost();\n            }\n        }\n        iter++;\n\n        int v = dist_v(rng);\n        bool was_active = is_active[v];\n        is_active[v] = !was_active;\n\n        vector<pair<int, int>> changed_residents;\n        if (is_active[v]) {\n            for (int k = 0; k < K; ++k) {\n                if (dist2_v_r[v][k] < dist2_v_r[nearest_v[k]][k]) {\n                    changed_residents.push_back({k, nearest_v[k]});\n                    nearest_v[k] = v;\n                }\n            }\n        } else {\n            for (int k = 0; k < K; ++k) {\n                if (nearest_v[k] == v) {\n                    changed_residents.push_back({k, v});\n                    for (int nv : sorted_v_for_r[k]) {\n                        if (is_active[nv]) { nearest_v[k] = nv; break; }\n                    }\n                }\n            }\n        }\n\n        long long new_cost = get_total_cost();\n        double progress = (double)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() / 1850.0;\n        double T = 1e6 * pow(1e2 / 1e6, progress);\n\n        if (new_cost < cur_cost || dist_unif(rng) < exp((double)(cur_cost - new_cost) / T)) {\n            cur_cost = new_cost;\n            if (cur_cost < best_cost) {\n                best_cost = cur_cost;\n                best_is_active = is_active;\n            }\n        } else {\n            is_active[v] = was_active;\n            for (auto& p : changed_residents) nearest_v[p.first] = p.second;\n        }\n    }\n\n    is_active = best_is_active;\n    for (int k = 0; k < K; ++k) {\n        for (int nv : sorted_v_for_r[k]) {\n            if (is_active[nv]) { nearest_v[k] = nv; break; }\n        }\n    }\n\n    for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n    for (int k = 0; k < K; ++k) max_d2[nearest_v[k]] = max(max_d2[nearest_v[k]], dist2_v_r[nearest_v[k]][k]);\n    \n    int n_req = 0;\n    v_req_list[n_req++] = 1;\n    for (int i = 1; i <= N; ++i) if (max_d2[i] > 0 && i != 1) v_req_list[n_req++] = i;\n\n    vector<int> final_B(M, 0);\n    if (n_req > 1) {\n        vector<int> union_edges;\n        static int edge_used_at[301] = {0};\n        static int ts = 1;\n        \n        for (int i = 0; i < n_req; ++i) { prim_min_d[i] = 2e15; prim_visited[i] = false; }\n        static int prim_parent[101];\n        prim_min_d[0] = 0; prim_parent[0] = -1;\n        for (int i = 0; i < n_req; ++i) {\n            int u = -1;\n            for (int j = 0; j < n_req; ++j) if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n            if (u == -1) break;\n            prim_visited[u] = true;\n            if (prim_parent[u] != -1) {\n                for (int e_id : path_edges[v_req_list[u]][v_req_list[prim_parent[u]]]) {\n                    if (edge_used_at[e_id] != ts) { edge_used_at[e_id] = ts; union_edges.push_back(e_id); }\n                }\n            }\n            for (int v = 0; v < n_req; ++v) {\n                if (!prim_visited[v]) {\n                    long long d = dist[v_req_list[u]][v_req_list[v]];\n                    if (d < prim_min_d[v]) { prim_min_d[v] = d; prim_parent[v] = u; }\n                }\n            }\n        }\n        DSU dsu(N);\n        sort(union_edges.begin(), union_edges.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n        for (int e_id : union_edges) if (dsu.unite(edges[e_id].u, edges[e_id].v)) final_B[e_id] = 1;\n    }\n\n    vector<int> reachable;\n    vector<int> q = {1};\n    vector<bool> visited_reach(N + 1, false);\n    visited_reach[1] = true;\n    int head = 0;\n    while(head < (int)q.size()){\n        int u = q[head++];\n        reachable.push_back(u);\n        for(int e_idx : adj[u]) if(final_B[e_idx]){\n            int v = (edges[e_idx].u == u ? edges[e_idx].v : edges[e_idx].u);\n            if(!visited_reach[v]){ visited_reach[v] = true; q.push_back(v); }\n        }\n    }\n\n    vector<long long> final_max_d2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        long long min_d2 = 8e18;\n        int best_v = -1;\n        for (int v : reachable) {\n            long long d2 = dist2_v_r[v][k];\n            if (d2 < min_d2) { min_d2 = d2; best_v = v; }\n        }\n        final_max_d2[best_v] = max(final_max_d2[best_v], min_d2);\n    }\n\n    vector<int> final_P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) if (final_max_d2[i] > 0) {\n        int p = (int)sqrt(final_max_d2[i]);\n        while ((long long)p * p < final_max_d2[i]) p++;\n        final_P[i] = p;\n    }\n\n    while (true) {\n        bool changed = false;\n        vector<int> deg(N + 1, 0);\n        for (int j = 0; j < M; ++j) if (final_B[j]) { deg[edges[j].u]++; deg[edges[j].v]++; }\n        for (int i = 2; i <= N; ++i) {\n            if (deg[i] == 1 && final_P[i] == 0) {\n                for (int j = 0; j < M; ++j) if (final_B[j] && (edges[j].u == i || edges[j].v == i)) {\n                    final_B[j] = 0; changed = true; break;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    for (int i = 1; i <= N; ++i) cout << min(final_P[i], 5000) << (i == N ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) cout << final_B[j] << (j == M - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#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 an N-tiered pyramid of balls (N=30, 465 balls). Each ball has a unique number.\n * We want to arrange the balls such that every ball (x, y) above the lowest tier\n * has a smaller number than the two balls below it (x+1, y) and (x+1, y+1).\n * This is equivalent to a min-heap property on the pyramid.\n * We need to achieve E=0 (no violations) with minimal operations K (swaps).\n */\n\nconst int N = 30;\nconst int NUM_BALLS = N * (N + 1) / 2;\n\nstruct Move {\n    int x1, y1, x2, y2;\n};\n\nint initial_pyramid[N][N];\nint pyramid[N][N];\nint pos_x[NUM_BALLS];\nint pos_y[NUM_BALLS];\n\nint main() {\n    // Speed up I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial pyramid configuration from input.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> initial_pyramid[i][j])) break;\n        }\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    // Using a fixed seed for reproducibility within a run, but randomizing across trials.\n    mt19937 rng(42);\n\n    vector<Move> best_moves;\n    int min_K = 10001; // Max K allowed is 10000.\n\n    int trials = 0;\n    while (true) {\n        trials++;\n        // Limit total execution time to stay under the 2.0s time limit.\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        // Reset the current pyramid and positions for the new trial.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j <= i; ++j) {\n                pyramid[i][j] = initial_pyramid[i][j];\n                pos_x[pyramid[i][j]] = i;\n                pos_y[pyramid[i][j]] = j;\n            }\n        }\n\n        vector<Move> current_moves;\n        int current_K = 0;\n        \n        // Randomly decide the parent-selection strategy for this trial.\n        // The first trial uses a deterministic \"larger parent\" heuristic.\n        // Subsequent trials randomize this bias between 50% and 100%.\n        int bias = (trials == 1) ? 100 : (rng() % 51 + 50);\n\n        // Systematic approach: process each ball from 0 up to 464.\n        // For each ball v, \"bubble it up\" until it no longer violates \n        // the heap property with its parents.\n        for (int v = 0; v < NUM_BALLS; ++v) {\n            while (true) {\n                int x = pos_x[v];\n                int y = pos_y[v];\n                if (x == 0) break; // Reached the top of the pyramid.\n\n                // Check parents: (x-1, y-1) and (x-1, y).\n                int p1x = x - 1, p1y = y - 1;\n                int p2x = x - 1, p2y = y;\n                bool p1_valid = (p1y >= 0 && pyramid[p1x][p1y] > v);\n                bool p2_valid = (p2y <= x - 1 && pyramid[p2x][p2y] > v);\n\n                // If both parents are already smaller than v, no violation.\n                if (!p1_valid && !p2_valid) break;\n\n                int tx, ty; // Target parent for the swap.\n                if (p1_valid && p2_valid) {\n                    // Both parents are larger than v. Decide which one to swap with.\n                    bool pick_p1;\n                    int v1 = pyramid[p1x][p1y];\n                    int v2 = pyramid[p2x][p2y];\n                    if ((int)(rng() % 100) < bias) {\n                        // Exploitation: pick the parent with the larger value to move down.\n                        pick_p1 = (v1 > v2);\n                    } else {\n                        // Exploration: randomly pick the smaller parent.\n                        pick_p1 = (v1 < v2);\n                    }\n                    if (pick_p1) { tx = p1x; ty = p1y; }\n                    else { tx = p2x; ty = p2y; }\n                } else if (p1_valid) {\n                    tx = p1x; ty = p1y;\n                } else {\n                    tx = p2x; ty = p2y;\n                }\n\n                // Perform the swap between v and the selected parent.\n                int other_v = pyramid[tx][ty];\n                pyramid[x][y] = other_v;\n                pyramid[tx][ty] = v;\n                pos_x[v] = tx; pos_y[v] = ty;\n                pos_x[other_v] = x; pos_y[other_v] = y;\n                current_moves.push_back({x, y, tx, ty});\n                current_K++;\n                \n                // If this trial already exceeds our best K, skip it.\n                if (current_K >= min_K) break; \n            }\n            if (current_K >= min_K) break;\n        }\n\n        // Keep track of the best move sequence (the one with the minimum K).\n        if (current_K < min_K) {\n            min_K = current_K;\n            best_moves = current_moves;\n        }\n    }\n\n    // Output the resulting K and the sequence of swaps for the best simulation found.\n    cout << best_moves.size() << \"\\n\";\n    for (const auto& m : best_moves) {\n        cout << m.x1 << \" \" << m.y1 << \" \" << m.x2 << \" \" << m.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// Warehouse dimensions and constants\nconst int D = 9;\nconst int ENTRANCE_I = 0;\nconst int ENTRANCE_J = 4; // Center of the northernmost row\n\n// Represents a square in the DxD warehouse grid\nstruct Square {\n    int i, j;\n    bool operator<(const Square& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Square& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint V[D][D];         // Storage/Removal priority rank (higher = deeper, remove later)\nbool obstacle[D][D]; // Grid status: true if square is an obstacle\nint grid[D][D];      // Current grid state: -3=entrance, -2=obstacle, -1=empty, >=0=container ID\n\n/**\n * Precalculates the ideal removal order (V ranks) for each storage square.\n * This simulation identifies squares that can be removed as \"leaves\" (not blocking others)\n * and assigns them higher ranks based on their distance from the entrance.\n */\nvoid precalculate_V(int M) {\n    int dist_bfs[D][D];\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) dist_bfs[i][j] = -1;\n\n    // Initial BFS to calculate minimal distance from the entrance for all squares\n    queue<Square> q;\n    q.push({ENTRANCE_I, ENTRANCE_J});\n    dist_bfs[ENTRANCE_I][ENTRANCE_J] = 0;\n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n    while (!q.empty()) {\n        Square curr = q.front(); q.pop();\n        for (int k = 0; k < 4; ++k) {\n            int ni = curr.i + di[k], nj = curr.j + dj[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && dist_bfs[ni][nj] == -1) {\n                dist_bfs[ni][nj] = dist_bfs[curr.i][curr.j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Determine the ideal sequence of retrieval using a greedy approach\n    set<Square> E_v;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j)\n            if (!obstacle[i][j] && !(i == ENTRANCE_I && j == ENTRANCE_J)) E_v.insert({i, j});\n\n    // We simulate retrieval in reverse order (M-1 down to 0) to assign ranks\n    for (int k = M - 1; k >= 0; --k) {\n        Square best_s = {-1, -1};\n        int max_score = -1;\n        for (auto const& s : E_v) {\n            // Check connectivity: removing square 's' shouldn't isolate any other empty square\n            int count = 0;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int ni = curr.i + di[d], nj = curr.j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && \n                        E_v.count({ni, nj}) && !visited[ni][nj] && !(ni == s.i && nj == s.j)) {\n                        visited[ni][nj] = true;\n                        q_safe.push({ni, nj});\n                        count++;\n                    }\n                }\n            }\n            if (count == (int)E_v.size() - 1) {\n                // Tie-breaker prioritizing deeper/further squares for higher ranks\n                int score = dist_bfs[s.i][s.j] * 1000 + abs(s.j - ENTRANCE_J) * 10 + s.i;\n                if (score > max_score) { max_score = score; best_s = s; }\n            }\n        }\n        if (best_s.i != -1) {\n            V[best_s.i][best_s.j] = k;\n            E_v.erase(best_s);\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) obstacle[i][j] = false;\n    for (int i = 0; i < N; ++i) {\n        int r, c; cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n\n    int M = D * D - 1 - N; // Total containers\n    precalculate_V(M);\n\n    vector<int> remaining_t;\n    for (int i = 0; i < M; ++i) remaining_t.push_back(i);\n\n    set<Square> E; // Set of currently empty storage squares\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == ENTRANCE_I && j == ENTRANCE_J) grid[i][j] = -3;\n            else if (obstacle[i][j]) grid[i][j] = -2;\n            else { grid[i][j] = -1; E.insert({i, j}); }\n        }\n    }\n\n    // 1. Online Storage Phase\n    for (int d = 0; d < M; ++d) {\n        int t_d; cin >> t_d;\n        int t_rank = 0;\n        for (int t : remaining_t) if (t < t_d) t_rank++;\n\n        // Find all reachable empty squares that are also \"safe\" (not blocking others)\n        vector<Square> safe_reachable;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n        for (auto const& s : E) {\n            int count = 0;\n            bool s_reachable = false;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int ni = curr.i + di[k], nj = curr.j + dj[k];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] != -2 && !visited[ni][nj]) {\n                        if (ni == s.i && nj == s.j) { s_reachable = true; visited[ni][nj] = true; }\n                        else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                            visited[ni][nj] = true; q_safe.push({ni, nj});\n                            if (grid[ni][nj] == -1) count++;\n                        }\n                    }\n                }\n            }\n            if (s_reachable && count == (int)E.size() - 1) safe_reachable.push_back(s);\n        }\n\n        // Match the current container's rank to the available storage square ranks\n        Square best_s = {-1, -1};\n        int min_diff = 1e9;\n        for (auto const& s : safe_reachable) {\n            int v_rank = 0;\n            for (auto const& other : E) if (V[other.i][other.j] < V[s.i][s.j]) v_rank++;\n            if (abs(v_rank - t_rank) < min_diff) { min_diff = abs(v_rank - t_rank); best_s = s; }\n            else if (abs(v_rank - t_rank) == min_diff) {\n                if (best_s.i == -1 || V[s.i][s.j] > V[best_s.i][best_s.j]) best_s = s;\n            }\n        }\n        if (best_s.i == -1) best_s = *E.begin(); // Safety fallback\n\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = t_d;\n        E.erase(best_s);\n        remaining_t.erase(find(remaining_t.begin(), remaining_t.end(), t_d));\n    }\n\n    // 2. Offline Removal Phase\n    for (int d = 0; d < M; ++d) {\n        vector<Square> reachable_containers;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<Square> q;\n        q.push({ENTRANCE_I, ENTRANCE_J});\n        visited[ENTRANCE_I][ENTRANCE_J] = true;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n        while (!q.empty()) {\n            Square curr = q.front(); q.pop();\n            for (int k = 0; k < 4; ++k) {\n                int ni = curr.i + di[k], nj = curr.j + dj[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] != -2) {\n                    if (grid[ni][nj] >= 0) {\n                        reachable_containers.push_back({ni, nj});\n                        visited[ni][nj] = true;\n                    } else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        Square best_s = {-1, -1};\n        int min_t = 1e9;\n        for (auto const& s : reachable_containers) {\n            if (grid[s.i][s.j] < min_t) { min_t = grid[s.i][s.j]; best_s = s; }\n        }\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = -1; // Mark square as empty for future retrieval paths\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Takahashi City grid size (50x50) and number of wards (100) are fixed as per problem statement.\nconst int N = 50;\nconst int M = 100;\n\nint grid[N][N];\nint E[M + 1][M + 1];\nbool original_adj[M + 1][M + 1];\nint ward_size[M + 1];\nint dx[] = {0, 0, 1, -1};\nint dy[] = {1, -1, 0, 0};\n\n// Shared data structures for connectivity BFS for efficiency.\nint vis[N][N];\nint vis_token = 0;\npair<int, int> q_arr[N * N];\n\n// Returns the color of a cell at (r, c), or 0 if it's outside the grid.\ninline int get_color(int r, int c) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return 0;\n    return grid[r][c];\n}\n\n// Check if removing square (r, c) from ward c_old preserves its connectivity.\nbool check_connectivity(int r, int c, int c_old, const vector<pair<int, int>>& neighbors) {\n    if (neighbors.size() <= 1) return true;\n    vis_token++;\n    int head = 0, tail = 0;\n    q_arr[tail++] = neighbors[0];\n    vis[neighbors[0].first][neighbors[0].second] = vis_token;\n    vis[r][c] = vis_token; // Act as a wall (as square (r, c) will be removed)\n\n    int found_count = 1;\n    while (head < tail) {\n        pair<int, int> curr = q_arr[head++];\n        for (int k = 0; k < 4; k++) {\n            int ni = curr.first + dx[k], nj = curr.second + dy[k];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == c_old && vis[ni][nj] != vis_token) {\n                vis[ni][nj] = vis_token;\n                q_arr[tail++] = {ni, nj};\n                for (auto& neighbor : neighbors) {\n                    if (ni == neighbor.first && nj == neighbor.second) {\n                        found_count++;\n                        break;\n                    }\n                }\n                // Stop early if all target neighbor squares are reachable.\n                if (found_count == (int)neighbors.size()) return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Checks if changing square (r, c) to color 0 is valid.\nbool can_remove(int r, int c) {\n    int c_old = grid[r][c];\n    if (c_old == 0) return false;\n    \n    // Constraint: Ward c_old can only have a 0 square if it was originally on the boundary (adjacent to color 0).\n    if (!original_adj[c_old][0]) return false;\n\n    // Rule: Color 0 must remain connected (including \"outside\").\n    // To ensure this, we only convert a square to 0 if it touches the boundary or an existing 0-square.\n    bool next_to_0 = false;\n    if (r == 0 || r == N - 1 || c == 0 || c == N - 1) next_to_0 = true;\n    else {\n        for (int k = 0; k < 4; k++) {\n            if (grid[r + dx[k]][c + dy[k]] == 0) {\n                next_to_0 = true;\n                break;\n            }\n        }\n    }\n    if (!next_to_0) return false;\n\n    int c_old_neighbors_count = 0;\n    static vector<pair<int, int>> c_old_neighbors;\n    c_old_neighbors.clear();\n    int neighbor_wards[4];\n    int num_neighbor_wards = 0;\n\n    for (int k = 0; k < 4; k++) {\n        int d = get_color(r + dx[k], c + dy[k]);\n        if (d == c_old) {\n            c_old_neighbors_count++;\n            c_old_neighbors.push_back({r + dx[k], c + dy[k]});\n        } else if (d > 0) {\n            // New d square becomes adjacent to 0; allowed only if d was originally adjacent to 0.\n            if (!original_adj[d][0]) return false;\n            \n            // Check if ward-ward adjacency (c_old, d) remains after removal.\n            bool already_checked = false;\n            for (int j = 0; j < num_neighbor_wards; j++) {\n                if (neighbor_wards[j] == d) { already_checked = true; break; }\n            }\n            if (!already_checked) {\n                neighbor_wards[num_neighbor_wards++] = d;\n                int edges_to_d = 0;\n                for (int m = 0; m < 4; m++) {\n                    if (get_color(r + dx[m], c + dy[m]) == d) edges_to_d++;\n                }\n                if (E[c_old][d] - edges_to_d <= 0) return false;\n            }\n        }\n    }\n\n    // Ward cannot disappear completely.\n    if (c_old_neighbors_count == 0 && ward_size[c_old] > 1) {\n        // This is a safety check: if ward_size is 1, c_old_neighbors_count will be 0.\n        // If ward_size > 1 and c_old_neighbors_count is 0, (r,c) is an isolated square, not allowed.\n        return false;\n    }\n    if (ward_size[c_old] <= 1) return false;\n\n    // Perform connectivity check for ward c_old.\n    if (!check_connectivity(r, c, c_old, c_old_neighbors)) return false;\n\n    return true;\n}\n\n// Convert square (r, c) to color 0 and update internal adjacency tallies.\nvoid remove_and_update(int r, int c) {\n    int c_old = grid[r][c];\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c + dy[k];\n        int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : grid[ni][nj];\n        E[c_old][d]--; E[d][c_old]--;\n        E[0][d]++; E[d][0]++;\n    }\n    grid[r][c] = 0;\n    ward_size[c_old]--;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n            ward_size[grid[i][j]]++;\n        }\n    }\n\n    // Initialize edge counts between all color pairs.\n    for (int i = 0; i <= M; i++) for (int j = 0; j <= M; j++) E[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int k = 0; k < 4; k++) {\n                int d = get_color(i + dx[k], j + dy[k]);\n                E[grid[i][j]][d]++;\n            }\n        }\n    }\n    // Record original ward adjacencies.\n    for (int i = 0; i <= M; i++) for (int j = 0; j <= M; j++) original_adj[i][j] = (E[i][j] > 0);\n\n    // List of candidates for removal: only squares of wards originally on the grid boundary can be converted to 0.\n    vector<pair<int, int>> coords;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (original_adj[grid[i][j]][0]) {\n                coords.push_back({i, j});\n            }\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(1337);\n\n    // Iteratively shuffle and try greedily removing squares until time is almost up.\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        shuffle(coords.begin(), coords.end(), rng);\n        bool changed = false;\n        for (auto& p : coords) {\n            if (grid[p.first][p.second] != 0 && can_remove(p.first, p.second)) {\n                remove_and_update(p.first, p.second);\n                changed = true;\n            }\n        }\n        if (!changed) break; // Reached local optimum\n    }\n\n    // Output final grid to stdout.\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 <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n/**\n * Problem Strategy:\n * 1. Initial Sorting (Phase 1): Perform an initial partial or full sort of the items\n *    using MergeSort within a query limit. Each comparison provides a constraint \n *    on the relative weights of two items.\n * 2. Weight Estimation (Phase 2): Estimate the weights of items based on the\n *    order statistics of an exponential distribution. Refine these estimates iteratively.\n * 3. Set Balancing & Querying (Phase 3): Construct balanced sets using current weight estimates.\n *    Perform queries to compare sets. If a query contradicts the current estimates, \n *    adjust the estimated weights (hat_w) using an iterative relaxation method \n *    (similar to Isotonic Regression) to satisfy both set and item-level constraints.\n * 4. Final Partition: Output the best partition found using the refined weight estimates.\n */\n\nint N, D, Q;\nint q_count = 0;\n\nstruct Constraint {\n    vector<int> L, R;\n    int res; // 1 if weight(L) > weight(R), -1 if weight(L) < weight(R), 0 if equal\n};\n\nstruct ItemConstraint {\n    int small, large;\n};\n\nvector<Constraint> set_constraints;\nvector<ItemConstraint> item_constraints;\n\n// Wrapper for the balance query. Synchronizes output and input.\nchar query(const vector<int>& L, const vector<int>& R) {\n    if (q_count >= Q) return '=';\n    q_count++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res;\n    if (!(cin >> res)) exit(0);\n    return res;\n}\n\n// Partial MergeSort logic to build initial constraints and ordering.\nvoid merge(vector<int>& arr, int l, int m, int r, int Q_limit) {\n    vector<int> left(arr.begin() + l, arr.begin() + m);\n    vector<int> right(arr.begin() + m, arr.begin() + r);\n    int i = 0, j = 0, k = l;\n    while (i < (int)left.size() && j < (int)right.size()) {\n        if (q_count < Q_limit) {\n            char res = query({left[i]}, {right[j]});\n            if (res == '<') {\n                item_constraints.push_back({left[i], right[j]});\n                arr[k++] = left[i++];\n            } else if (res == '>') {\n                item_constraints.push_back({right[j], left[i]});\n                arr[k++] = right[j++];\n            } else {\n                arr[k++] = left[i++];\n            }\n        } else {\n            if (left[i] < right[j]) arr[k++] = left[i++];\n            else arr[k++] = right[j++];\n        }\n    }\n    while (i < (int)left.size()) arr[k++] = left[i++];\n    while (j < (int)right.size()) arr[k++] = right[j++];\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r, int Q_limit) {\n    if (r - l <= 1) return;\n    int m = l + (r - l) / 2;\n    merge_sort(arr, l, m, Q_limit);\n    merge_sort(arr, m, r, Q_limit);\n    merge(arr, l, m, r, Q_limit);\n}\n\n// Iterative weight adjustment algorithm to satisfy all recorded constraints.\nvoid update_weights(vector<double>& hat_w, const vector<int>& sorted_items) {\n    int n_constraints = (int)set_constraints.size() + (int)item_constraints.size() + N;\n    // Scale iterations based on constraint count to stay within time limit.\n    int iters = 40000 / n_constraints;\n    if (iters < 5) iters = 5;\n    if (iters > 100) iters = 100;\n\n    for (int iter = 0; iter < iters; iter++) {\n        // Enforce set-comparison constraints (L > R or L < R).\n        for (auto& c : set_constraints) {\n            double sumL = 0, sumR = 0;\n            for (int idx : c.L) sumL += hat_w[idx];\n            for (int idx : c.R) sumR += hat_w[idx];\n            if (c.res == 1 && sumL <= sumR) {\n                double delta = (sumR - sumL + 10.0) / (c.L.size() + c.R.size());\n                for (int idx : c.L) hat_w[idx] += delta;\n                for (int idx : c.R) hat_w[idx] -= delta;\n            } else if (c.res == -1 && sumL >= sumR) {\n                double delta = (sumL - sumR + 10.0) / (c.L.size() + c.R.size());\n                for (int idx : c.R) hat_w[idx] += delta;\n                for (int idx : c.L) hat_w[idx] -= delta;\n            }\n        }\n        // Enforce pairwise item comparison constraints discovered during sorting.\n        for (auto& ic : item_constraints) {\n            if (hat_w[ic.small] > hat_w[ic.large]) {\n                double avg = (hat_w[ic.small] + hat_w[ic.large]) / 2.0;\n                hat_w[ic.small] = hat_w[ic.large] = avg;\n            }\n        }\n        // Maintain a rough global ordering based on the MergeSort sequence.\n        for (int i = 0; i < N - 1; i++) {\n            if (hat_w[sorted_items[i]] > hat_w[sorted_items[i+1]]) {\n                double avg = (hat_w[sorted_items[i]] + hat_w[sorted_items[i+1]]) / 2.0;\n                hat_w[sorted_items[i]] = hat_w[sorted_items[i+1]] = avg;\n            }\n        }\n        for (int i = 0; i < N; i++) if (hat_w[i] < 1.0) hat_w[i] = 1.0;\n    }\n}\n\n// Heuristic multi-way partitioner (LPT + Hill Climbing refinement).\nvector<vector<int>> solve_partition(const vector<double>& hat_w) {\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n    sort(indices.begin(), indices.end(), [&](int a, int b) {\n        return hat_w[a] > hat_w[b];\n    });\n\n    vector<vector<int>> sets(D);\n    vector<double> set_sums(D, 0);\n    for (int idx : indices) {\n        int best_s = 0;\n        for (int j = 1; j < D; j++) if (set_sums[j] < set_sums[best_s]) best_s = j;\n        sets[best_s].push_back(idx);\n        set_sums[best_s] += hat_w[idx];\n    }\n\n    mt19937 rng(123);\n    for (int i = 0; i < 2000; i++) {\n        int a = rng() % D, b = rng() % D;\n        if (a == b) continue;\n        \n        // Potential move\n        if (sets[a].size() > 1) {\n            int idx_in_a = rng() % sets[a].size();\n            int item = sets[a][idx_in_a];\n            double new_sum_a = set_sums[a] - hat_w[item];\n            double new_sum_b = set_sums[b] + hat_w[item];\n            if (abs(new_sum_a - new_sum_b) < abs(set_sums[a] - set_sums[b])) {\n                set_sums[a] = new_sum_a;\n                set_sums[b] = new_sum_b;\n                sets[b].push_back(item);\n                sets[a].erase(sets[a].begin() + idx_in_a);\n                continue;\n            }\n        }\n        // Potential swap\n        if (!sets[a].empty() && !sets[b].empty()) {\n            int ia = rng() % sets[a].size(), ib = rng() % sets[b].size();\n            int item_a = sets[a][ia], item_b = sets[b][ib];\n            double new_sum_a = set_sums[a] - hat_w[item_a] + hat_w[item_b];\n            double new_sum_b = set_sums[b] - hat_w[item_b] + hat_w[item_a];\n            if (abs(new_sum_a - new_sum_b) < abs(set_sums[a] - set_sums[b])) {\n                set_sums[a] = new_sum_a;\n                set_sums[b] = new_sum_b;\n                swap(sets[a][ia], sets[b][ib]);\n            }\n        }\n    }\n    return sets;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n\n    // Initial item sorting phase using a significant portion of Q.\n    int Q_sort = min(Q - D, 800);\n    if (Q_sort < 0) Q_sort = 0;\n    merge_sort(items, 0, N, Q_sort);\n\n    vector<double> hat_w(N);\n    double cur_h = 0;\n    // Initialization using expected order statistics of the exponential distribution.\n    for (int i = 0; i < N; i++) {\n        cur_h += 100000.0 / (N - i);\n        hat_w[items[i]] = cur_h;\n    }\n\n    mt19937 rng(456);\n    // Active query loop to refine weight estimates.\n    while (q_count < Q) {\n        auto sets = solve_partition(hat_w);\n        vector<int> s_idx(D);\n        iota(s_idx.begin(), s_idx.end(), 0);\n        sort(s_idx.begin(), s_idx.end(), [&](int a, int b) {\n            double sum_a = 0, sum_b = 0;\n            for (int x : sets[a]) sum_a += hat_w[x];\n            for (int x : sets[b]) sum_b += hat_w[x];\n            return sum_a < sum_b;\n        });\n\n        int a, b;\n        // Selection strategy: focus on adjacent sets to refine close estimates,\n        // or extreme sets to detect significant weight outliers.\n        if (rng() % 10 < 7) {\n            int i = rng() % (D - 1);\n            a = s_idx[i]; b = s_idx[i+1];\n        } else {\n            a = s_idx[0]; b = s_idx[D - 1];\n        }\n\n        char res_char = query(sets[a], sets[b]);\n        int res = (res_char == '>' ? 1 : (res_char == '<' ? -1 : 0));\n        set_constraints.push_back({sets[a], sets[b], res});\n        // Limit constraint memory to maintain performance.\n        if (set_constraints.size() > 250) set_constraints.erase(set_constraints.begin());\n        \n        update_weights(hat_w, items);\n    }\n\n    // Final result calculation.\n    auto final_sets = solve_partition(hat_w);\n    vector<int> d(N);\n    for (int i = 0; i < D; i++) {\n        for (int x : final_sets[i]) d[x] = i;\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 <algorithm>\n#include <climits>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - n = 200 boxes, m = 10 stacks. Boxes must be carried out in order (1 to n).\n * - Carrying out a box v (operation 2) is free if v is at the top of its stack.\n * - Moving a block of k boxes (operation 1) costs k+1 energy.\n * - Goal: Minimize the total energy expenditure within 5000 operations.\n *\n * Strategy:\n * - Employ a greedy simulation that moves boxes above the target box v in sub-blocks.\n * - Each sub-block is ideally \"well-ordered\" (descending order from bottom to top).\n * - A refined heuristic scoring function evaluates potential stacks for each sub-block\n *   based on potential future blocking of boxes, stack size, and fit.\n * - Find the best heuristic parameters by running thousands of randomized simulations \n *   within the given time limit.\n */\n\nstruct Move {\n    int v, i;\n};\n\n// State manages the configuration of stacks and energy simulation.\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<int> box_to_stack;\n    vector<Move> moves;\n    long long energy;\n\n    State(int n, int m, const vector<vector<int>>& initial_stacks) \n        : n(n), m(m), stacks(initial_stacks), energy(0) {\n        box_to_stack.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            for (int v : stacks[i]) {\n                box_to_stack[v] = i;\n            }\n        }\n    }\n\n    // Moves box v and all boxes above it to the specified destination stack.\n    void move_block(int v, int dest_stack_idx) {\n        int src_stack_idx = box_to_stack[v];\n        if (src_stack_idx == dest_stack_idx) return;\n\n        auto& src_stack = stacks[src_stack_idx];\n        auto& dest_stack = stacks[dest_stack_idx];\n\n        int pos = -1;\n        for (int i = (int)src_stack.size() - 1; i >= 0; --i) {\n            if (src_stack[i] == v) {\n                pos = i;\n                break;\n            }\n        }\n\n        int k = (int)src_stack.size() - pos;\n        energy += (k + 1);\n        moves.push_back({v, dest_stack_idx + 1});\n\n        for (int i = pos; i < (int)src_stack.size(); ++i) {\n            box_to_stack[src_stack[i]] = dest_stack_idx;\n            dest_stack.push_back(src_stack[i]);\n        }\n        src_stack.resize(pos);\n    }\n\n    // Carries out box v.\n    void carry_out(int v) {\n        int s_idx = box_to_stack[v];\n        stacks[s_idx].pop_back();\n        moves.push_back({v, 0});\n    }\n};\n\n// Evaluates how good a destination stack is for a specific sub-block of boxes.\ninline long long calculate_score(const vector<int>& stack_d, int bottom_v, int top_S, int v, \n                                 int weight_future, int weight_size, int weight_urgent, \n                                 int lookahead, int weight_top_diff, int empty_val, int penalty_bury) {\n    int top_v = stack_d.empty() ? empty_val : stack_d.back();\n    long long score = 0;\n    \n    // Penalize if the destination stack top is smaller than the block's bottom.\n    if (top_v > bottom_v) {\n        score += (long long)(top_v - bottom_v) * weight_top_diff;\n    } else {\n        score += penalty_bury + (long long)(bottom_v - top_v) * weight_top_diff;\n    }\n\n    // Penalty for boxes in the stack that are smaller than the incoming bottom box and will be buried.\n    for (int x : stack_d) {\n        if (x < bottom_v) {\n            // High penalty for boxes needed very soon.\n            if (x > v && x <= v + lookahead) {\n                score += (long long)weight_urgent * (lookahead - (x - v) + 1);\n            }\n            score += weight_future;\n        }\n    }\n    score += (long long)stack_d.size() * weight_size;\n    return score;\n}\n\n// Full simulation of the extraction process.\nlong long simulate(int n, int m, const vector<vector<int>>& initial_stacks, \n                   int limit, int weight_future, int weight_size, int weight_urgent, \n                   int lookahead, int weight_top_diff, int empty_val, int penalty_bury,\n                   vector<Move>& out_moves) {\n    State state(n, m, initial_stacks);\n    for (int v = 1; v <= n; ++v) {\n        int s_idx = state.box_to_stack[v];\n        \n        // If the target box v is not at the top, clear the boxes above it.\n        if (state.stacks[s_idx].back() != v) {\n            auto& s = state.stacks[s_idx];\n            int pos = -1;\n            for (int i = (int)s.size() - 1; i >= 0; --i) {\n                if (s[i] == v) { pos = i; break; }\n            }\n            \n            // Split above-target boxes into descending sub-blocks.\n            vector<vector<int>> sub_blocks;\n            vector<int> current_S = {s[pos + 1]};\n            for (int i = pos + 2; i < (int)s.size(); ++i) {\n                // Split if order is violated (increasing) or gap is too large.\n                if (s[i-1] < s[i] || s[i-1] - s[i] > limit) {\n                    sub_blocks.push_back(current_S);\n                    current_S = {s[i]};\n                } else {\n                    current_S.push_back(s[i]);\n                }\n            }\n            sub_blocks.push_back(current_S);\n\n            // Move each sub-block (from top of stack to bottom) based on the heuristic score.\n            for (int i = (int)sub_blocks.size() - 1; i >= 0; --i) {\n                const auto& S = sub_blocks[i];\n                int bottom_v = S[0];\n                int top_S = S.back();\n                int best_d = -1;\n                long long min_score = LLONG_MAX;\n                \n                for (int d = 0; d < m; ++d) {\n                    if (d == s_idx) continue;\n                    long long score = calculate_score(state.stacks[d], bottom_v, top_S, v, \n                                                      weight_future, weight_size, weight_urgent, \n                                                      lookahead, weight_top_diff, empty_val, penalty_bury);\n                    if (score < min_score) {\n                        min_score = score;\n                        best_d = d;\n                    }\n                }\n                state.move_block(bottom_v, best_d);\n            }\n        }\n        state.carry_out(v);\n        if (state.moves.size() > 5000) return LLONG_MAX;\n    }\n    out_moves = state.moves;\n    return state.energy;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> initial_stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int b; cin >> b;\n            initial_stacks[i].push_back(b);\n        }\n    }\n\n    long long min_energy = LLONG_MAX;\n    vector<Move> best_moves;\n\n    mt19937 rng(12345);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Heuristic parameter distributions for randomized search.\n    uniform_int_distribution<int> dist_limit(1, 200);\n    uniform_int_distribution<int> dist_future(0, 400);\n    uniform_int_distribution<int> dist_size(0, 100);\n    uniform_int_distribution<int> dist_urgent(0, 2000);\n    uniform_int_distribution<int> dist_lookahead(1, 50);\n    uniform_int_distribution<int> dist_top_diff(0, 50);\n    uniform_int_distribution<int> dist_empty(150, 300);\n    uniform_int_distribution<int> dist_bury(500, 20000);\n\n    // Initial trials with baseline parameters.\n    int baselines[][8] = {\n        {30, 100, 10, 500, 15, 2, 210, 10000},\n        {100, 50, 5, 200, 20, 1, 201, 8000},\n        {15, 150, 15, 800, 10, 5, 230, 12000},\n        {200, 0, 0, 0, 1, 0, 200, 5000}\n    };\n    for (auto& b : baselines) {\n        vector<Move> current_moves;\n        long long energy = simulate(n, m, initial_stacks, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], current_moves);\n        if (energy < min_energy) {\n            min_energy = energy;\n            best_moves = current_moves;\n        }\n    }\n\n    // Keep running randomized simulations until the time limit.\n    int count = 0;\n    while (true) {\n        if ((count & 127) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1900) {\n                break;\n            }\n        }\n        count++;\n        \n        int limit = dist_limit(rng);\n        int wf = dist_future(rng);\n        int ws = dist_size(rng);\n        int wu = dist_urgent(rng);\n        int la = dist_lookahead(rng);\n        int td = dist_top_diff(rng);\n        int ev = dist_empty(rng);\n        int pb = dist_bury(rng);\n        \n        vector<Move> current_moves;\n        long long energy = simulate(n, m, initial_stacks, limit, wf, ws, wu, la, td, ev, pb, current_moves);\n        if (energy < min_energy) {\n            min_energy = energy;\n            best_moves = current_moves;\n        }\n    }\n\n    // Output the operation sequence of the best state found.\n    for (const auto& move : best_moves) {\n        cout << move.v << \" \" << move.i << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n// Maximum size of the board as per problem description\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\n\nstruct Edge {\n    int u, v;\n};\n\n// Global structures to store the adjacency list and edges of the graph\nvector<Edge> all_edges;\nbool is_in_tree[MAXN * MAXN][MAXN * MAXN];\nint parent_in_tree[MAXN * MAXN];\nint subtree_size[MAXN * MAXN];\nvector<int> tree_adj[MAXN * MAXN];\n\n// Perform DFS to compute subtree sizes for each node in the spanning tree\nvoid dfs_size(int u, int p) {\n    parent_in_tree[u] = p;\n    subtree_size[u] = 1;\n    for (int next_u : tree_adj[u]) {\n        if (next_u != p) {\n            dfs_size(next_u, u);\n            subtree_size[u] += subtree_size[next_u];\n        }\n    }\n}\n\n// Calculate the quality score of the current spanning tree based on dirtiness and subtree distribution.\n// The average dirtiness S is related to the sum of squares of the gaps between visits to each square.\n// For a DFS tour on a spanning tree, the gaps between visits to node u are twice the sizes of the \n// components formed by removing u from the tree.\nlong long compute_total_score() {\n    long long total = 0;\n    int total_nodes = N * N;\n    for (int u = 0; u < total_nodes; ++u) {\n        long long node_sum_s2 = 0;\n        for (int next_u : tree_adj[u]) {\n            if (next_u == parent_in_tree[u]) {\n                // The size of the component \"above\" node u\n                int s = total_nodes - subtree_size[u];\n                node_sum_s2 += (long long)s * s;\n            } else {\n                // The size of the subtree rooted at node u\n                int s = subtree_size[next_u];\n                node_sum_s2 += (long long)s * s;\n            }\n        }\n        total += (long long)d[u / N][u % N] * node_sum_s2;\n    }\n    return total;\n}\n\n// Helper to find the path from a given node to the root (0,0) in the tree\nvector<int> get_path_to_root(int u) {\n    vector<int> path;\n    while (u != -1) {\n        path.push_back(u);\n        u = parent_in_tree[u];\n    }\n    return path;\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read problem input\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\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    // Identify all possible edges between grid squares not separated by a wall\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = (i + 1) * N + j;\n                all_edges.push_back({u, vv});\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = i * N + (j + 1);\n                all_edges.push_back({u, vv});\n            }\n        }\n    }\n\n    // Generate an initial random spanning tree using Kruskal's algorithm\n    mt19937 rng(42);\n    vector<Edge> edges = all_edges;\n    shuffle(edges.begin(), edges.end(), rng);\n    vector<int> dsu(N * N);\n    for (int i = 0; i < N * N; ++i) dsu[i] = i;\n    auto dsu_find = [&](auto self, int i) -> int {\n        return dsu[i] == i ? i : dsu[i] = self(self, dsu[i]);\n    };\n    for (auto& e : edges) {\n        int root_u = dsu_find(dsu_find, e.u);\n        int root_v = dsu_find(dsu_find, e.v);\n        if (root_u != root_v) {\n            dsu[root_u] = root_v;\n            is_in_tree[e.u][e.v] = is_in_tree[e.v][e.u] = true;\n            tree_adj[e.u].push_back(e.v);\n            tree_adj[e.v].push_back(e.u);\n        }\n    }\n\n    // Initial score of the spanning tree\n    dfs_size(0, -1);\n    long long current_score = compute_total_score();\n\n    // Simulated Annealing parameters\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    const double TIME_LIMIT = 1.9; // Target time limit for SA process\n    double start_temp = 1e7;\n    double end_temp = 1e3;\n\n    // Run Simulated Annealing to optimize the spanning tree structure\n    while (true) {\n        // Occasionally check elapsed time\n        if (iterations % 256 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n        }\n        iterations++;\n\n        // Select a non-tree edge and add it to form a cycle\n        int e_idx = uniform_int_distribution<int>(0, all_edges.size() - 1)(rng);\n        Edge e_in = all_edges[e_idx];\n        if (is_in_tree[e_in.u][e_in.v]) continue;\n\n        // Trace paths to find the cycle formed by adding e_in\n        vector<int> path_u = get_path_to_root(e_in.u);\n        vector<int> path_v = get_path_to_root(e_in.v);\n        int iu = path_u.size() - 1, iv = path_v.size() - 1;\n        while (iu >= 0 && iv >= 0 && path_u[iu] == path_v[iv]) {\n            iu--; iv--;\n        }\n        vector<Edge> cycle;\n        for (int i = 0; i <= iu; ++i) cycle.push_back({path_u[i], parent_in_tree[path_u[i]]});\n        for (int i = 0; i <= iv; ++i) cycle.push_back({path_v[i], parent_in_tree[path_v[i]]});\n        cycle.push_back({e_in.u, e_in.v});\n\n        // Select a random edge from the cycle to remove, maintaining a spanning tree\n        int e_out_idx = uniform_int_distribution<int>(0, cycle.size() - 2)(rng);\n        Edge e_out = cycle[e_out_idx];\n\n        // Perform the edge swap (Remove e_out, Add e_in)\n        is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = false;\n        tree_adj[e_out.u].erase(remove(tree_adj[e_out.u].begin(), tree_adj[e_out.u].end(), e_out.v), tree_adj[e_out.u].end());\n        tree_adj[e_out.v].erase(remove(tree_adj[e_out.v].begin(), tree_adj[e_out.v].end(), e_out.u), tree_adj[e_out.v].end());\n        is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = true;\n        tree_adj[e_in.u].push_back(e_in.v);\n        tree_adj[e_in.v].push_back(e_in.u);\n\n        // Recompute sizes and the new tree's score\n        dfs_size(0, -1);\n        long long next_score = compute_total_score();\n\n        // SA Acceptance Criteria\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n        double progress = min(1.0, elapsed / TIME_LIMIT);\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        if (next_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - next_score) / T)) {\n            current_score = next_score;\n        } else {\n            // Revert swap if not accepted\n            is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = false;\n            tree_adj[e_in.u].erase(remove(tree_adj[e_in.u].begin(), tree_adj[e_in.u].end(), e_in.v), tree_adj[e_in.u].end());\n            tree_adj[e_in.v].erase(remove(tree_adj[e_in.v].begin(), tree_adj[e_in.v].end(), e_in.u), tree_adj[e_in.v].end());\n            is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = true;\n            tree_adj[e_out.u].push_back(e_out.v);\n            tree_adj[e_out.v].push_back(e_out.u);\n            dfs_size(0, -1);\n        }\n    }\n\n    // Generate the final cleaning tour by performing a DFS on the optimized spanning tree.\n    string tour = \"\";\n    auto get_dir = [&](int u, int v) {\n        int r1 = u / N, c1 = u % N;\n        int r2 = v / N, c2 = v % N;\n        if (r1 < r2) return 'D';\n        if (r1 > r2) return 'U';\n        if (c1 < c2) return 'R';\n        return 'L';\n    };\n    auto dfs_tour_gen = [&](auto self, int u, int p) -> void {\n        for (int next_u : tree_adj[u]) {\n            if (next_u != p) {\n                tour += get_dir(u, next_u);\n                self(self, next_u, u);\n                tour += get_dir(next_u, u);\n            }\n        }\n    };\n    dfs_tour_gen(dfs_tour_gen, 0, -1);\n\n    // Output the resulting cleaning route\n    cout << tour << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n/**\n * Strategy:\n * 1. Precompute the minimum movement cost for typing the suffix of each word from any grid position.\n * 2. Precompute a transition cost matrix (d[i][j]) between words, prioritizing overlaps to reduce total string length.\n * 3. Use multi-start greedy to find an initial word sequence, then optimize it with Simulated Annealing (SA) using 2-opt and shift moves.\n * 4. Construct the resulting lucky string S from the optimized word sequence.\n * 5. Use dynamic programming (DP) to choose the optimal grid coordinates for each character in S to minimize the total Manhattan movement cost.\n */\n\n// Cost function: Manhattan distance + 1\ninline int get_dist(int p1, int p2) {\n    return abs(p1 / 15 - p2 / 15) + abs(p1 % 15 - p2 % 15) + 1;\n}\n\n// Function to compute the maximum suffix-prefix overlap between word a and word b\nint get_overlap(const string& a, const string& b) {\n    for (int o = 4; o >= 1; --o) {\n        bool match = true;\n        for (int k = 0; k < o; ++k) {\n            if (a[5 - o + k] != b[k]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return o;\n    }\n    return 0;\n}\n\n// Precomputed cost tables\nint min_cost_table[6][200][225];\ndouble d[200][200];\ndouble d_start[200];\nvector<int> pos_of_char[26];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read problem dimensions and finger starting position\n    int N_in, M_in;\n    if (!(cin >> N_in >> M_in)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read keyboard layout and the 200 lucky words\n    vector<string> A(15);\n    for (int i = 0; i < 15; ++i) cin >> A[i];\n    vector<string> T_str(200);\n    for (int i = 0; i < 200; ++i) cin >> T_str[i];\n\n    // Store all grid positions for each uppercase letter\n    for (int i = 0; i < 15; ++i) {\n        for (int j = 0; j < 15; ++j) {\n            pos_of_char[A[i][j] - 'A'].push_back(i * 15 + j);\n        }\n    }\n\n    // Precompute typing costs for suffixes of words starting from any grid position\n    for (int j = 0; j < 200; ++j) {\n        for (int pos = 0; pos < 225; ++pos) min_cost_table[5][j][pos] = 0;\n        for (int k = 4; k >= 0; --k) {\n            int char_idx = T_str[j][k] - 'A';\n            for (int pos = 0; pos < 225; ++pos) {\n                int best = 1e9;\n                for (int next_pos : pos_of_char[char_idx]) {\n                    int c = get_dist(pos, next_pos) + min_cost_table[k + 1][j][next_pos];\n                    if (c < best) best = c;\n                }\n                min_cost_table[k][j][pos] = best;\n            }\n        }\n    }\n\n    // Precompute transition costs between words for TSP\n    for (int i = 0; i < 200; ++i) {\n        int last_char_i = T_str[i][4] - 'A';\n        for (int j = 0; j < 200; ++j) {\n            int o = get_overlap(T_str[i], T_str[j]);\n            int min_v = 1e9;\n            for (int pos : pos_of_char[last_char_i]) {\n                if (min_cost_table[o][j][pos] < min_v) min_v = min_cost_table[o][j][pos];\n            }\n            // Length reduction (5-o) is highly weighted (50.0) to prioritize overlaps\n            d[i][j] = (double)(5 - o) * 50.0 + (double)min_v;\n        }\n        d_start[i] = (double)min_cost_table[0][i][si * 15 + sj];\n    }\n\n    // Initial Path: Multi-start greedy approach\n    vector<int> best_p;\n    double best_ever_cost = 1e18;\n    for (int s = 0; s < 200; ++s) {\n        vector<int> path;\n        path.push_back(s);\n        vector<bool> used(200, false);\n        used[s] = true;\n        double current_path_cost = d_start[s];\n        for (int i = 1; i < 200; ++i) {\n            int last = path.back(), next_v = -1;\n            double min_d = 1e18;\n            for (int v = 0; v < 200; ++v) {\n                if (!used[v] && d[last][v] < min_d) { min_d = d[last][v]; next_v = v; }\n            }\n            path.push_back(next_v); used[next_v] = true; current_path_cost += min_d;\n        }\n        if (current_path_cost < best_ever_cost) { best_ever_cost = current_path_cost; best_p = path; }\n    }\n\n    // Optimization: Simulated Annealing (SA)\n    auto get_total_path_cost = [&](const vector<int>& path) {\n        double cost = d_start[path[0]];\n        for (int k = 0; k < 199; ++k) cost += d[path[k]][path[k + 1]];\n        return cost;\n    };\n\n    vector<int> p = best_p;\n    double current_cost = best_ever_cost;\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(1337);\n\n    for (int iter = 0; ; ++iter) {\n        if ((iter & 511) == 0) {\n            auto now = chrono::steady_clock::now();\n            long long elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > 1900) break;\n            double temp = 30.0 * (1.0 - (double)elapsed / 1900.0);\n            if (current_cost < best_ever_cost) { best_ever_cost = current_cost; best_p = p; }\n        }\n\n        int move_type = uniform_int_distribution<int>(0, 1)(rng);\n        int i = uniform_int_distribution<int>(0, 199)(rng), j = uniform_int_distribution<int>(0, 199)(rng);\n        if (i == j) continue;\n\n        if (move_type == 0) { // 2-opt (reversing segments)\n            if (i > j) swap(i, j);\n            double next_cost = current_cost;\n            if (i == 0) { next_cost -= d_start[p[0]]; next_cost += d_start[p[j]]; }\n            else { next_cost -= d[p[i - 1]][p[i]]; next_cost += d[p[i - 1]][p[j]]; }\n            if (j < 199) { next_cost -= d[p[j]][p[j + 1]]; next_cost += d[p[i]][p[j + 1]]; }\n            for (int k = i; k < j; ++k) { next_cost -= d[p[k]][p[k + 1]]; next_cost += d[p[k + 1]][p[k]]; }\n\n            auto now = chrono::steady_clock::now();\n            double temp = 30.0 * (1.0 - (double)chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1900.0);\n            if (next_cost < current_cost || (temp > 0.01 && uniform_real_distribution<double>(0, 1)(rng) < exp((current_cost - next_cost) / temp))) {\n                current_cost = next_cost; reverse(p.begin() + i, p.begin() + j + 1);\n            }\n        } else { // Shift (repositioning a single word)\n            vector<int> next_p = p;\n            int val = next_p[i]; next_p.erase(next_p.begin() + i); next_p.insert(next_p.begin() + j, val);\n            double next_cost = get_total_path_cost(next_p);\n\n            auto now = chrono::steady_clock::now();\n            double temp = 30.0 * (1.0 - (double)chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1900.0);\n            if (next_cost < current_cost || (temp > 0.01 && uniform_real_distribution<double>(0, 1)(rng) < exp((current_cost - next_cost) / temp))) {\n                current_cost = next_cost; p = next_p;\n            }\n        }\n    }\n\n    // Construct the lucky string S\n    p = best_p;\n    string S = T_str[p[0]];\n    for (int i = 1; i < 200; ++i) {\n        int o = get_overlap(T_str[p[i - 1]], T_str[p[i]]);\n        S += T_str[p[i]].substr(o);\n    }\n\n    // Dynamic Programming: Optimal grid coordinate selection\n    int L = S.size();\n    vector<vector<int>> dp_vals(L), parent(L), pos_list(L);\n    for (int k = 0; k < L; ++k) {\n        pos_list[k] = pos_of_char[S[k] - 'A'];\n        dp_vals[k].assign(pos_list[k].size(), 1e9);\n        parent[k].assign(pos_list[k].size(), -1);\n    }\n\n    for (int i = 0; i < (int)pos_list[0].size(); ++i) dp_vals[0][i] = get_dist(si * 15 + sj, pos_list[0][i]);\n    for (int k = 1; k < L; ++k) {\n        for (int i = 0; i < (int)pos_list[k].size(); ++i) {\n            int curr_pos = pos_list[k][i];\n            for (int j = 0; j < (int)pos_list[k - 1].size(); ++j) {\n                int c = dp_vals[k - 1][j] + get_dist(pos_list[k - 1][j], curr_pos);\n                if (c < dp_vals[k][i]) { dp_vals[k][i] = c; parent[k][i] = j; }\n            }\n        }\n    }\n\n    int last_idx = 0, min_total = 2e9;\n    for (int i = 0; i < (int)pos_list[L - 1].size(); ++i) {\n        if (dp_vals[L - 1][i] < min_total) { min_total = dp_vals[L - 1][i]; last_idx = i; }\n    }\n\n    // Output results\n    vector<int> res_coords(L);\n    for (int k = L - 1; k >= 0; --k) { res_coords[k] = pos_list[k][last_idx]; last_idx = parent[k][last_idx]; }\n    for (int pos : res_coords) cout << pos / 15 << \" \" << pos % 15 << \"\\n\";\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int r, c;\n};\n\nstruct Polyomino {\n    int id;\n    int d;\n    vector<Point> ps;\n    vector<vector<Point>> positions;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<pair<vector<int>, int>> queries;\nvector<pair<Point, int>> drills;\nvector<vector<vector<int>>> W; // W[field_idx][pos_idx][query_idx]\n\ndouble normal_cdf(double x) {\n    return 0.5 * erfc(-x * M_SQRT1_2);\n}\n\ndouble get_prob(int k, int v_sum, int v_obs) {\n    if (k == 1) return (v_sum == v_obs) ? 1.0 : 1e-18;\n    double mu = (k - v_sum) * eps + v_sum * (1.0 - eps);\n    double sigma = sqrt((double)k * eps * (1.0 - eps));\n    if (v_obs == 0) {\n        return max(1e-18, normal_cdf((0.5 - mu) / sigma));\n    } else {\n        return max(1e-18, normal_cdf((v_obs + 0.5 - mu) / sigma) - normal_cdf((v_obs - 0.5 - mu) / sigma));\n    }\n}\n\ndouble get_log_prob(int k, int v_sum, int v_obs) {\n    return log(get_prob(k, v_sum, v_obs));\n}\n\nstruct Config {\n    vector<int> pos_idx;\n    vector<int> v_sums;\n    vector<vector<int>> grid_v;\n    double log_prob;\n\n    Config() : pos_idx(M), v_sums(), grid_v(N, vector<int>(N, 0)), log_prob(0) {}\n\n    void compute_all() {\n        for (int i = 0; i < N; ++i) fill(grid_v[i].begin(), grid_v[i].end(), 0);\n        for (int i = 0; i < M; ++i) {\n            for (const auto& p : oil_fields[i].positions[pos_idx[i]]) {\n                grid_v[p.r][p.c]++;\n            }\n        }\n        v_sums.assign(queries.size(), 0);\n        log_prob = 0;\n        for (size_t q = 0; q < queries.size(); ++q) {\n            for (int k = 0; k < M; ++k) {\n                v_sums[q] += W[k][pos_idx[k]][q];\n            }\n            log_prob += get_log_prob(queries[q].first.size(), v_sums[q], queries[q].second);\n        }\n        for (const auto& d : drills) {\n            if (grid_v[d.first.r][d.first.c] != d.second) log_prob -= 1e6;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> eps)) return 0;\n    oil_fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int d; cin >> d; oil_fields[i].d = d;\n        vector<Point> ps(d);\n        int max_r = 0, max_c = 0;\n        for (int j = 0; j < d; ++j) {\n            cin >> ps[j].r >> ps[j].c;\n            max_r = max(max_r, ps[j].r);\n            max_c = max(max_c, ps[j].c);\n        }\n        oil_fields[i].ps = ps;\n        for (int r = 0; r <= N - 1 - max_r; ++r) {\n            for (int c = 0; c <= N - 1 - max_c; ++c) {\n                vector<Point> pos;\n                for (const auto& p : ps) pos.push_back({p.r + r, p.c + c});\n                oil_fields[i].positions.push_back(pos);\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    for (int i = 0; i < 2 * N; ++i) {\n        vector<int> S;\n        for (int j = 0; j < N * N; ++j) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < 0.5) S.push_back(j);\n        }\n        if (S.size() < 2) { S.push_back(0); S.push_back(1); }\n        cout << \"q \" << S.size();\n        for (int idx : S) cout << \" \" << idx / N << \" \" << idx % N;\n        cout << endl;\n        int resp; cin >> resp;\n        queries.push_back({S, resp});\n    }\n\n    W.assign(M, vector<vector<int>>());\n    for (int i = 0; i < M; ++i) {\n        W[i].assign(oil_fields[i].positions.size(), vector<int>(queries.size(), 0));\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            vector<vector<bool>> is_in_pos(N, vector<bool>(N, false));\n            for (const auto& pt : oil_fields[i].positions[p]) is_in_pos[pt.r][pt.c] = true;\n            for (size_t q = 0; q < queries.size(); ++q) {\n                for (int idx : queries[q].first) {\n                    if (is_in_pos[idx / N][idx % N]) W[i][p][q]++;\n                }\n            }\n        }\n    }\n\n    const int num_samples = 400;\n    vector<Config> samples(num_samples);\n    for (int i = 0; i < num_samples; ++i) {\n        for (int j = 0; j < M; ++j) {\n            samples[i].pos_idx[j] = uniform_int_distribution<int>(0, (int)oil_fields[j].positions.size() - 1)(rng);\n        }\n        samples[i].compute_all();\n    }\n\n    for (int iter = 0; iter < 2 * N * N; ++iter) {\n        for (int i = 0; i < num_samples; ++i) {\n            for (int step = 0; step < 30; ++step) {\n                int m = uniform_int_distribution<int>(0, M - 1)(rng);\n                int old_pos = samples[i].pos_idx[m];\n                int new_pos = uniform_int_distribution<int>(0, (int)oil_fields[m].positions.size() - 1)(rng);\n                if (old_pos == new_pos) continue;\n\n                double old_lp = samples[i].log_prob;\n                for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]--;\n                for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]++;\n                \n                double new_lp = 0;\n                vector<int> old_v_sums = samples[i].v_sums;\n                for (size_t q = 0; q < queries.size(); ++q) {\n                    samples[i].v_sums[q] = samples[i].v_sums[q] - W[m][old_pos][q] + W[m][new_pos][q];\n                    new_lp += get_log_prob(queries[q].first.size(), samples[i].v_sums[q], queries[q].second);\n                }\n                for (const auto& d : drills) {\n                    if (samples[i].grid_v[d.first.r][d.first.c] != d.second) new_lp -= 1e6;\n                }\n                \n                if (new_lp > old_lp || uniform_real_distribution<double>(0, 1)(rng) < exp(new_lp - old_lp)) {\n                    samples[i].log_prob = new_lp;\n                    samples[i].pos_idx[m] = new_pos;\n                } else {\n                    for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]--;\n                    for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]++;\n                    samples[i].v_sums = old_v_sums;\n                }\n            }\n        }\n\n        vector<vector<double>> p(N, vector<double>(N, 0));\n        for (int i = 0; i < num_samples; ++i) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) if (samples[i].grid_v[r][c] > 0) p[r][c] += 1.0;\n            }\n        }\n\n        bool confident = true;\n        vector<Point> guess_set;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p[r][c] /= num_samples;\n                if (p[r][c] > 0.5) guess_set.push_back({r, c});\n                if (p[r][c] > 0.01 && p[r][c] < 0.99) confident = false;\n            }\n        }\n\n        if (confident || iter > N * N) {\n            cout << \"a \" << guess_set.size();\n            for (const auto& pt : guess_set) cout << \" \" << pt.r << \" \" << pt.c;\n            cout << endl;\n            int resp; if (!(cin >> resp)) break;\n            if (resp == 1) break;\n        }\n\n        double max_var = -1; Point best_p = {0, 0};\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                double var = p[r][c] * (1.0 - p[r][c]);\n                if (var > max_var) { max_var = var; best_p = {r, c}; }\n            }\n        }\n\n        cout << \"q 1 \" << best_p.r << \" \" << best_p.c << endl;\n        int resp; if (!(cin >> resp)) break;\n        drills.push_back({best_p, resp});\n        for (int i = 0; i < num_samples; ++i) samples[i].compute_all();\n    }\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <deque>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS & STRATEGY:\n * - We are partitioning a W x W grid (W=1000) into N rectangular sections for D days.\n * - Each day has N reservations with desired areas a_{d,k}.\n * - Area deficit penalty: 100 * (desired_area - assigned_area).\n * - Partition change cost Ld: Total length of partition segments added or removed from the previous day.\n * - Strategy: Use horizontal strips for all days. Each day's reservation k is assigned a horizontal \n *   strip of height h_{d,k}. The horizontal partitions between strips can change position each day.\n * - This approach is robust because partition changes (cost 2W per changed partition) are \n *   significantly cheaper than area deficit penalties (100 per unit area).\n * - For each day d, we use Dynamic Programming (DP) to determine the best horizontal partition \n *   positions y_{d,k} that minimize (total area penalty + partition change cost Ld).\n * - Ld is calculated as the symmetric difference of the horizontal partition coordinates between \n *   consecutive days, multiplied by W.\n */\n\n// Use a large constant for INF that fits within long long limits even after additions.\nconst long long INF = 1e17;\n\nint main() {\n    // Optimize standard I/O for faster processing.\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n\n    // Read the desired areas a[d][k] for each reservation.\n    vector<vector<long long>> a(D, vector<long long>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a[d][k];\n        }\n    }\n\n    // S[d][k] will store the y-coordinates of the N+1 horizontal strip boundaries on day d.\n    // S[d][0] = 0 and S[d][N] = W are the perimeter boundaries of the event hall.\n    vector<vector<int>> S(D, vector<int>(N + 1));\n    vector<bool> in_prev_S(W + 1, false);\n\n    for (int d = 0; d < D; ++d) {\n        // dp[k][y]: min cost for the first k reservations on day d, where the k-th reservation\n        // ends at horizontal coordinate y.\n        vector<vector<long long>> dp(N + 1, vector<long long>(W + 1, INF));\n        vector<vector<int>> parent(N + 1, vector<int>(W + 1, -1));\n\n        // Base case: 0 reservations assigned at coordinate 0.\n        dp[0][0] = 0;\n\n        for (int k = 1; k <= N; ++k) {\n            long long cur_a = a[d][k - 1];\n            // H is the minimum height required for strip k to have 0 area penalty.\n            int H = (cur_a + W - 1) / W;\n\n            // Pre-calculate prefix minimums for Case 1: Assigned height >= H (Penalty = 0).\n            vector<long long> p1_min(W + 1, INF);\n            vector<int> p1_idx(W + 1, -1);\n            for (int j = 0; j <= W; ++j) {\n                if (j == 0) {\n                    p1_min[j] = dp[k - 1][j];\n                    p1_idx[j] = j;\n                } else {\n                    if (dp[k - 1][j] < p1_min[j - 1]) {\n                        p1_min[j] = dp[k - 1][j];\n                        p1_idx[j] = j;\n                    } else {\n                        p1_min[j] = p1_min[j - 1];\n                        p1_idx[j] = p1_idx[j - 1];\n                    }\n                }\n            }\n\n            // Case 2 (Assigned height < H): Penalty = 100 * (cur_a - W * (y - prev_y)).\n            // Penalty = (100 * cur_a - 100 * W * y) + 100 * W * prev_y.\n            // We use a sliding window deque to find the best prev_y in range (y-H, y) efficiently.\n            deque<int> dq;\n            auto g_special = [&](int j) {\n                if (dp[k - 1][j] >= INF) return INF;\n                return dp[k - 1][j] + 100LL * W * j;\n            };\n\n            for (int y = 1; y <= W; ++y) {\n                // Constraint: Reserve at least 1 unit of height for each subsequent strip.\n                if (y < k || y > W - (N - k)) continue;\n\n                // Update sliding window range: (max(k-1, y-H+1), y-1).\n                while (!dq.empty() && dq.front() <= y - H) dq.pop_front();\n                int new_j = y - 1;\n                if (new_j >= k - 1) {\n                    long long val = g_special(new_j);\n                    if (val < INF) {\n                        while (!dq.empty() && g_special(dq.back()) >= val) dq.pop_back();\n                        dq.push_back(new_j);\n                    }\n                }\n\n                long long best_val = INF;\n                int best_prev_y = -1;\n\n                // Part 1: No penalty (prev_y <= y - H).\n                if (y - H >= 0 && y - H >= k - 1) {\n                    best_val = p1_min[y - H];\n                    best_prev_y = p1_idx[y - H];\n                }\n\n                // Part 2: Linear penalty (y-H < prev_y < y).\n                if (!dq.empty()) {\n                    long long val2 = g_special(dq.front()) + 100LL * cur_a - 100LL * W * y;\n                    if (val2 < best_val) {\n                        best_val = val2;\n                        best_prev_y = dq.front();\n                    }\n                }\n\n                // Store best result and record parent for backtracking.\n                if (best_val < INF) {\n                    // Cost 2W is incurred if a new partition coordinate y is used that wasn't present yesterday.\n                    // This accounts for both installing a new partition and removing an old one.\n                    // Perimeter boundaries (y=0 or y=W) do not incur change costs.\n                    long long change_cost = (d > 0 && k < N && !in_prev_S[y]) ? 2LL * W : 0;\n                    dp[k][y] = best_val + change_cost;\n                    parent[k][y] = best_prev_y;\n                }\n            }\n        }\n\n        // Backtrack to find the optimal horizontal boundaries for day d.\n        int curr_y = W;\n        for (int k = N; k >= 1; --k) {\n            S[d][k] = curr_y;\n            curr_y = parent[k][curr_y];\n        }\n        S[d][0] = 0;\n\n        // Populate in_prev_S to calculate the partition change costs for day d+1.\n        fill(in_prev_S.begin(), in_prev_S.end(), false);\n        for (int k = 1; k < N; ++k) {\n            in_prev_S[S[d][k]] = true;\n        }\n    }\n\n    // Final output: Print rectangle coordinates for all D days.\n    // Each rectangle k is defined by strip boundaries S[d][k] to S[d][k+1] and full hall width W.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << S[d][k] << \" 0 \" << S[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <stdint.h>\n#include <string.h>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\nconst double W = 0.5; // Heuristic weight for board squares that are not yet \"fixed\"\n\n// Struct to store a single stamp operation\nstruct Op {\n    int m, p, q;\n};\n\n// Struct to represent a combination of 0 to 3 stamps used at the same (p, q) position\nstruct Combination {\n    int k;                   // Total number of stamps in the combination\n    vector<int> ms;          // Indices of the stamps used\n    uint32_t s[3][3];        // Sum of stamp values modulo P\n};\n\n// State representation for the beam search\nstruct State {\n    uint32_t board[N][N];    // Board square values modulo P\n    int total_k;             // Cumulative number of stamps used so far\n    int parent_idx;          // Link to parent state index in the previous beam level\n    int combi_idx;           // Index of the combination chosen at the current step\n    double eval;             // Weighted evaluation score\n};\n\n// Potential candidate for the next step of the beam search\nstruct Candidate {\n    int state_idx;           // Index of the parent state in the current beam\n    int combi_idx;           // Index of the combination to apply\n    double eval;             // Resulting evaluation score\n\n    // Descending order comparison by evaluation score\n    bool operator>(const Candidate& other) const {\n        return eval > other.eval;\n    }\n};\n\n// Global arrays for precomputed heuristic values to speed up evaluation\ndouble pre_eval_sum_sw[49][1771];\ndouble P_w_after[49][3][3];\ndouble w_after_val[49][3][3];\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    uint32_t a[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    uint32_t stamps[M][3][3];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[m][i][j];\n\n    // Precompute all stamp combinations of sizes 0, 1, 2, and 3\n    vector<Combination> all_combi;\n    all_combi.push_back({0, {}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}});\n\n    for (int m = 0; m < M; ++m) {\n        Combination c;\n        c.k = 1; c.ms = {m};\n        for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c.s[i][j] = stamps[m][i][j];\n        all_combi.push_back(c);\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            Combination c;\n            c.k = 2; c.ms = {m1, m2};\n            for (int i = 0; i < 3; ++i)\n                for (int j = 0; j < 3; ++j)\n                    c.s[i][j] = (stamps[m1][i][j] + stamps[m2][i][j]) % P;\n            all_combi.push_back(c);\n        }\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            for (int m3 = m2; m3 < M; ++m3) {\n                Combination c;\n                c.k = 3; c.ms = {m1, m2, m3};\n                for (int i = 0; i < 3; ++i)\n                    for (int j = 0; j < 3; ++j)\n                        c.s[i][j] = ((long long)stamps[m1][i][j] + stamps[m2][i][j] + stamps[m3][i][j]) % P;\n                all_combi.push_back(c);\n            }\n        }\n    }\n\n    // List all potential stamp placement corners (p, q) in row-major order\n    vector<pair<int, int>> positions;\n    for (int p = 0; p <= 6; ++p)\n        for (int q = 0; q <= 6; ++q)\n            positions.push_back({p, q});\n\n    // Identify for each grid cell when it will no longer be affected by future stamps\n    int last_p[N][N], last_q[N][N];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            last_p[r][c] = -1; last_q[r][c] = -1;\n            for (const auto& pos : positions) {\n                if (r >= pos.first && r < pos.first + 3 && c >= pos.second && c < pos.second + 3) {\n                    last_p[r][c] = pos.first;\n                    last_q[r][c] = pos.second;\n                }\n            }\n        }\n    }\n\n    // Track which squares become \"fixed\" at each step in the beam search\n    vector<pair<int, int>> fixed_squares[7][7];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            fixed_squares[last_p[r][c]][last_q[r][c]].push_back({r, c});\n        }\n    }\n\n    // Precompute heuristic values for stamp weights at each position\n    for (int step = 0; step < 49; ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                double w = (last_p[r][c] == p && last_q[r][c] == q) ? 1.0 : W;\n                w_after_val[step][i][j] = w;\n                P_w_after[step][i][j] = (double)P * w;\n            }\n        }\n        for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n            double sum_sw = 0;\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    sum_sw += (double)all_combi[c_idx].s[i][j] * w_after_val[step][i][j];\n                }\n            }\n            pre_eval_sum_sw[step][c_idx] = sum_sw;\n        }\n    }\n\n    // Beam search initialization\n    State initial_state;\n    memcpy(initial_state.board, a, sizeof(a));\n    initial_state.total_k = 0;\n    initial_state.parent_idx = -1;\n    initial_state.combi_idx = -1;\n    initial_state.eval = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.eval += (double)a[i][j] * W;\n\n    vector<vector<State>> all_beams;\n    all_beams.push_back({initial_state});\n\n    int B = 900; // Beam size (adjusted for speed)\n    vector<Candidate> candidates;\n    candidates.reserve(B * all_combi.size());\n\n    // Iterative beam search through each stamp position\n    for (int step = 0; step < (int)positions.size(); ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        const vector<State>& current_beam = all_beams.back();\n        candidates.clear();\n\n        for (int s_idx = 0; s_idx < (int)current_beam.size(); ++s_idx) {\n            const State& st = current_beam[s_idx];\n            double base_eval_increase = 0;\n            for (const auto& sq : fixed_squares[p][q]) {\n                base_eval_increase += (double)st.board[sq.first][sq.second] * (1.0 - W);\n            }\n            double base_eval = st.eval + base_eval_increase;\n\n            // Tight inner loop for evaluation of each combination\n            for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n                const Combination& combi = all_combi[c_idx];\n                if (st.total_k + combi.k > K) continue;\n\n                double cur_eval = base_eval + pre_eval_sum_sw[step][c_idx];\n                if (st.board[p][q] + combi.s[0][0] >= P) cur_eval -= P_w_after[step][0][0];\n                if (st.board[p][q+1] + combi.s[0][1] >= P) cur_eval -= P_w_after[step][0][1];\n                if (st.board[p][q+2] + combi.s[0][2] >= P) cur_eval -= P_w_after[step][0][2];\n                if (st.board[p+1][q] + combi.s[1][0] >= P) cur_eval -= P_w_after[step][1][0];\n                if (st.board[p+1][q+1] + combi.s[1][1] >= P) cur_eval -= P_w_after[step][1][1];\n                if (st.board[p+1][q+2] + combi.s[1][2] >= P) cur_eval -= P_w_after[step][1][2];\n                if (st.board[p+2][q] + combi.s[2][0] >= P) cur_eval -= P_w_after[step][2][0];\n                if (st.board[p+2][q+1] + combi.s[2][1] >= P) cur_eval -= P_w_after[step][2][1];\n                if (st.board[p+2][q+2] + combi.s[2][2] >= P) cur_eval -= P_w_after[step][2][2];\n                \n                candidates.push_back({s_idx, c_idx, cur_eval});\n            }\n        }\n\n        // Selection of top B candidates for the next beam level\n        int next_B = min((int)candidates.size(), B);\n        nth_element(candidates.begin(), candidates.begin() + next_B, candidates.end(), greater<Candidate>());\n        candidates.resize(next_B);\n\n        vector<State> next_beam;\n        next_beam.reserve(next_B);\n        for (const auto& cand : candidates) {\n            const State& parent = current_beam[cand.state_idx];\n            const Combination& combi = all_combi[cand.combi_idx];\n            State ns;\n            memcpy(ns.board, parent.board, sizeof(parent.board));\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    uint32_t v = ns.board[p + i][q + j] + combi.s[i][j];\n                    if (v >= P) v -= P;\n                    ns.board[p + i][q + j] = v;\n                }\n            }\n            ns.total_k = parent.total_k + combi.k;\n            ns.parent_idx = cand.state_idx;\n            ns.combi_idx = cand.combi_idx;\n            ns.eval = cand.eval;\n            next_beam.push_back(std::move(ns));\n        }\n        all_beams.push_back(std::move(next_beam));\n    }\n\n    // Retrieve best overall final state and output the sequence of operations\n    const vector<State>& final_beam = all_beams.back();\n    int best_state_idx = 0;\n    double best_eval = -1e18;\n    for (int i = 0; i < (int)final_beam.size(); ++i) {\n        if (final_beam[i].eval > best_eval) {\n            best_eval = final_beam[i].eval;\n            best_state_idx = i;\n        }\n    }\n\n    vector<Op> final_ops;\n    int cur_idx = best_state_idx;\n    for (int step = (int)positions.size() - 1; step >= 0; --step) {\n        const State& st = all_beams[step + 1][cur_idx];\n        const Combination& combi = all_combi[st.combi_idx];\n        for (int m_idx : combi.ms) {\n            final_ops.push_back({m_idx, positions[step].first, positions[step].second});\n        }\n        cur_idx = st.parent_idx;\n    }\n\n    cout << final_ops.size() << \"\\n\";\n    for (int i = (int)final_ops.size() - 1; i >= 0; --i) {\n        cout << final_ops[i].m << \" \" << final_ops[i].p << \" \" << final_ops[i].q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer's solution for the container terminal problem.\n *\n * Strategy:\n * 1. Bomb all small cranes (cranes 1-4) in Turn 0 to clear the grid.\n * 2. Use the large crane (crane 0) to handle all containers one by one.\n * 3. Crane 0 strategy:\n *    - Priority 1: If a container that is next in order for its dispatch gate is already on the grid,\n *                  pick it up and move it to its dispatch gate.\n *    - Priority 2: If no such container is on the grid, find the most urgent container (smallest index\n *                  that hasn't been dispatched) still in a receiving queue. Move the top container of\n *                  that queue to a buffer square to clear the way.\n * 4. This strategy ensures M1=0 (no inversions), M2=0 (all to correct gates), and M3=0 (all dispatched).\n *    The turns count M0 will be minimized by only moving what's necessary and using shortest paths.\n */\n\nvoid add_move_to_queue(vector<char>& q, int tr, int tc, int& r, int& c) {\n    while (r < tr) { q.push_back('D'); r++; }\n    while (r > tr) { q.push_back('U'); r--; }\n    while (c < tc) { q.push_back('R'); c++; }\n    while (c > tc) { q.push_back('L'); c--; }\n}\n\nint main() {\n    int N_in;\n    if (!(cin >> N_in)) return 0;\n    int N = 5;\n    vector<vector<int>> arrival_queue(5, vector<int>(5));\n    vector<int> gate_of(25);\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            cin >> arrival_queue[i][j];\n            gate_of[arrival_queue[i][j]] = i;\n        }\n    }\n\n    vector<int> current_gate_idx(5, 0);\n    vector<vector<int>> grid(5, vector<int>(5, -1));\n    vector<int> next_needed(5);\n    for (int i = 0; i < 5; i++) next_needed[i] = 5 * i;\n    vector<bool> is_dispatched(25, false);\n    int dispatched_count = 0;\n\n    int crane_r = 0, crane_c = 0;\n    int held = -1;\n    vector<string> actions(5, \"\");\n    vector<char> action_queue;\n\n    for (int t = 0; t < 10000; ++t) {\n        // Step 1: Arrival of containers\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][0] == -1 && current_gate_idx[i] < 5) {\n                // Containers arrive only if square is empty and no crane is holding there\n                if (!(crane_r == i && crane_c == 0 && held != -1)) {\n                    grid[i][0] = arrival_queue[i][current_gate_idx[i]];\n                    current_gate_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        char act0 = '.';\n        if (t == 0) {\n            // Initial moves: move Crane 0 out of (0,0) and bomb others\n            act0 = 'R';\n            for (int i = 1; i < 5; i++) actions[i] += 'B';\n        } else {\n            if (action_queue.empty()) {\n                // Determine next task for Crane 0\n                if (held == -1) {\n                    int target_r = -1, target_c = -1;\n                    // Check if a needed container is already on the grid (arrival gates or buffer)\n                    for (int r = 0; r < 5; ++r) {\n                        for (int c = 0; c < 4; ++c) {\n                            if (grid[r][c] != -1) {\n                                int val = grid[r][c];\n                                if (val == next_needed[val / 5]) {\n                                    target_r = r; target_c = c; break;\n                                }\n                            }\n                        }\n                        if (target_r != -1) break;\n                    }\n\n                    if (target_r != -1) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, target_r, target_c, r, c);\n                        action_queue.push_back('P');\n                    } else {\n                        // Find most urgent container still in a queue and clear its path\n                        int urgent_v = 100;\n                        int clear_gate = -1;\n                        for (int i = 0; i < 5; ++i) {\n                            if (next_needed[i] < 5 * (i + 1)) {\n                                int v = next_needed[i];\n                                bool is_av = !is_dispatched[v];\n                                if (is_av) {\n                                    for (int r1 = 0; r1 < 5; r1++)\n                                        for (int c1 = 0; c1 < 4; c1++)\n                                            if (grid[r1][c1] == v) is_av = false;\n                                }\n                                if (is_av && v < urgent_v) {\n                                    urgent_v = v;\n                                    clear_gate = gate_of[v];\n                                }\n                            }\n                        }\n                        if (clear_gate != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, clear_gate, 0, r, c);\n                            if (grid[clear_gate][0] != -1) action_queue.push_back('P');\n                            else action_queue.push_back('.'); // Wait for container arrival\n                        }\n                    }\n                } else {\n                    // Holding a container: either dispatch it or move it to a buffer\n                    if (held == next_needed[held / 5]) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, held / 5, 4, r, c);\n                        action_queue.push_back('Q');\n                    } else {\n                        int br = -1, bc = -1;\n                        for (int c = 1; c <= 3; ++c) {\n                            for (int r = 0; r < 5; ++r) {\n                                if (grid[r][c] == -1) { br = r; bc = c; break; }\n                            }\n                            if (br != -1) break;\n                        }\n                        if (br != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, br, bc, r, c);\n                            action_queue.push_back('Q');\n                        } else {\n                            action_queue.push_back('.');\n                        }\n                    }\n                }\n            }\n\n            if (!action_queue.empty()) {\n                act0 = action_queue.front();\n                action_queue.erase(action_queue.begin());\n            }\n            for (int i = 1; i < 5; i++) actions[i] += '.';\n        }\n\n        actions[0] += act0;\n        if (act0 == 'P') { held = grid[crane_r][crane_c]; grid[crane_r][crane_c] = -1; }\n        else if (act0 == 'Q') {\n            int val = held;\n            grid[crane_r][crane_c] = val;\n            if (crane_c == 4) next_needed[val / 5]++;\n            held = -1;\n        } else if (act0 == 'U') crane_r--;\n        else if (act0 == 'D') crane_r++;\n        else if (act0 == 'L') crane_c--;\n        else if (act0 == 'R') crane_c++;\n\n        // Step 3: Container dispatch\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][4] != -1) {\n                is_dispatched[grid[i][4]] = true;\n                grid[i][4] = -1;\n                dispatched_count++;\n            }\n        }\n\n        if (dispatched_count == 25) break;\n    }\n\n    // Output all actions, padding with '.' as necessary\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) max_len = max(max_len, (int)actions[i].length());\n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) actions[i] += '.';\n        cout << actions[i] << endl;\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n// Grid size is fixed at 20x20 according to the problem statement.\nconst int N = 20;\n\n/**\n * State struct maintains the current status of the land, truck position, \n * amount of soil loaded, and the total cost incurred through operations.\n */\nstruct State {\n    int h[N][N];\n    int r, c;\n    long long L;\n    long long cost;\n    vector<string> ops;\n\n    State(const int initial_h[N][N]) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                h[i][j] = initial_h[i][j];\n            }\n        }\n        r = 0; c = 0; L = 0; cost = 0;\n        ops.reserve(50000);\n    }\n\n    // Load d units of soil from the current square.\n    // Cost is equal to the amount of soil moved.\n    void load(int d) {\n        if (d <= 0) return;\n        h[r][c] -= d;\n        L += d;\n        cost += d;\n        ops.push_back(\"+\" + to_string(d));\n    }\n\n    // Unload d units of soil from the dump truck to the current square.\n    void unload(int d) {\n        if (d <= 0) return;\n        h[r][c] += d;\n        L -= d;\n        cost += d;\n        ops.push_back(\"-\" + to_string(d));\n    }\n\n    // Move to an adjacent square. Cost depends on both moving and current truck load L.\n    void move(char dir) {\n        if (dir == 'U') r--;\n        else if (dir == 'D') r++;\n        else if (dir == 'L') c--;\n        else if (dir == 'R') c++;\n        cost += (100 + L);\n        ops.push_back(string(1, dir));\n    }\n};\n\n// Global precomputed power tables to speed up heuristic score calculation.\ndouble dist_pow_table[41];\ndouble soil_pow_table[101];\n\n/**\n * Solve function implements a greedy strategy with randomized heuristic parameters.\n * It selects the next target square based on distance, soil volume, and current truck load,\n * then moves toward it while checking every cell on the path.\n *\n * Parameters:\n * dist_p, soil_p: Exponents used to non-linearly weight distance and soil volume.\n * load_penalty: Discourages picking up more soil as the current load L increases.\n * sink_weight: Balances the priority between sources (loading) and sinks (unloading).\n */\nvoid solve(const int initial_h[N][N], double dist_p, double soil_p, double load_penalty, double sink_weight, vector<string>& best_ops, long long &best_total_cost, mt19937& rng) {\n    State s(initial_h);\n    vector<pair<int, int>> targets;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (initial_h[i][j] != 0) targets.push_back({i, j});\n        }\n    }\n\n    // Precompute power tables for this run's specific parameters.\n    for (int i = 0; i <= 40; ++i) dist_pow_table[i] = pow((double)i, dist_p);\n    for (int i = 1; i <= 100; ++i) soil_pow_table[i] = pow((double)i, soil_p);\n\n    while (!targets.empty() && s.ops.size() < 99900) {\n        // Handle the current cell: load if source (h>0) or unload if sink (h<0).\n        if (s.h[s.r][s.c] > 0) {\n            s.load(s.h[s.r][s.c]);\n        } else if (s.h[s.r][s.c] < 0 && s.L > 0) {\n            int amount = (int)min((long long)abs(s.h[s.r][s.c]), s.L);\n            s.unload(amount);\n        }\n\n        // Clean up completed squares from the target list.\n        for (int k = 0; k < (int)targets.size(); ++k) {\n            if (s.h[targets[k].first][targets[k].second] == 0) {\n                targets[k] = targets.back();\n                targets.pop_back();\n                k--;\n            }\n        }\n        if (targets.empty()) break;\n\n        // Greedy Target Selection: Find square with minimum heuristic score.\n        int tr = -1, tc = -1;\n        double min_score = 1e30;\n        for (const auto& t : targets) {\n            int dist = abs(s.r - t.first) + abs(s.c - t.second);\n            if (dist == 0) continue; \n            \n            double score;\n            if (s.h[t.first][t.second] > 0) {\n                // Source: loading soil. Future move cost will increase.\n                score = (dist_pow_table[dist] * (100.0 + (double)s.L) / soil_pow_table[s.h[t.first][t.second]]) * (1.0 + (double)s.L * load_penalty);\n            } else {\n                // Sink: unloading soil. Truck must carry soil to visit a sink.\n                int can_unload = (int)min((long long)abs(s.h[t.first][t.second]), s.L);\n                if (can_unload == 0) continue;\n                score = (dist_pow_table[dist] * (100.0 + (double)s.L) / soil_pow_table[can_unload]) * sink_weight;\n            }\n            if (score < min_score) {\n                min_score = score;\n                tr = t.first; tc = t.second;\n            }\n        }\n\n        if (tr == -1) break;\n\n        // Path Optimization: Move one step towards the target. \n        // If multiple steps are valid, prioritize squares that require work.\n        int dr = tr - s.r;\n        int dc = tc - s.c;\n        char move_dir = 0;\n        if (dr != 0 && dc != 0) {\n            int r1 = s.r + (dr > 0 ? 1 : -1);\n            int c1 = s.c;\n            int r2 = s.r;\n            int c2 = s.c + (dc > 0 ? 1 : -1);\n            if (s.h[r1][c1] != 0) move_dir = (dr > 0 ? 'D' : 'U');\n            else if (s.h[r2][c2] != 0) move_dir = (dc > 0 ? 'R' : 'L');\n            else move_dir = (rng() % 2 == 0) ? (dr > 0 ? 'D' : 'U') : (dc > 0 ? 'R' : 'L');\n        } else if (dr != 0) {\n            move_dir = (dr > 0 ? 'D' : 'U');\n        } else {\n            move_dir = (dc > 0 ? 'R' : 'L');\n        }\n        s.move(move_dir);\n    }\n\n    // Evaluate total cost including scoring penalties for non-zero squares.\n    long long final_diff = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s.h[i][j] != 0) final_diff += 100LL * abs(s.h[i][j]) + 10000LL;\n        }\n    }\n    if (s.L > 0) final_diff += 10000LL;\n\n    // Track the best operation sequence found across all randomized trials.\n    if (s.cost + final_diff < best_total_cost) {\n        best_total_cost = s.cost + final_diff;\n        best_ops = s.ops;\n    }\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    int h[N][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    auto start_time = chrono::steady_clock::now();\n    long long best_total_cost = 8e18;\n    vector<string> best_ops;\n    mt19937 rng(1337);\n\n    // Initial parameters derived from previous heuristics.\n    vector<vector<double>> params = {\n        {1.5, 1.0, 0.005, 0.5},\n        {1.8, 1.2, 0.001, 0.3},\n        {1.2, 0.8, 0.010, 0.8},\n        {2.0, 0.5, 0.001, 0.6},\n        {1.4, 1.4, 0.0001, 0.9}\n    };\n    for (const auto& p : params) {\n        solve(h, p[0], p[1], p[2], p[3], best_ops, best_total_cost, rng);\n    }\n\n    // Perform randomized search within the execution time limit (2.0s).\n    uniform_real_distribution<double> dist_dist(1.1, 2.3);\n    uniform_real_distribution<double> soil_dist(0.5, 1.6);\n    uniform_real_distribution<double> load_dist(0.0005, 0.015);\n    uniform_real_distribution<double> sink_dist(0.1, 1.0);\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1850) {\n        solve(h, dist_dist(rng), soil_dist(rng), load_dist(rng), sink_dist(rng), best_ops, best_total_cost, rng);\n    }\n\n    // Output the operation sequence of the best solution found.\n    for (const string& op : best_ops) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Strategy:\n * 1. Each turn, we manage 60 seeds and must plant 36 in an N x N (6x6) grid.\n * 2. 60 edges in this grid (vertical and horizontal neighbors) will produce 60 new seeds.\n * 3. We use a potential function P(i, j) = (sum of max(seed_i.x[l], seed_j.x[l]))^2 to estimate\n *    the quality of the offspring produced by breeding seeds i and j.\n * 4. Diversity is maintained by ensuring the best seed for each criterion (dimension) is \n *    always considered for planting.\n * 5. Simulated Annealing is used to optimize the grid arrangement and seed selection from\n *    the available pool, maximizing the total potential sum of all edges.\n * 6. The SA neighborhood includes swapping two seeds on the grid and swapping a grid seed \n *    with an unused pool seed.\n */\n\nconst int N = 6;\nconst int M = 15;\nconst int T_MAX = 10;\nconst int SEED_COUNT = 60;\nconst int PLANT_COUNT = 36;\nconst int UNUSED_COUNT = 24;\n\nstruct Seed {\n    int x[M];\n    int v;\n};\n\n// P2[i][j] precomputes the potential value of offspring from seed i and seed j.\nlong long P2[SEED_COUNT][SEED_COUNT];\n\nvoid precompute_potentials(const vector<Seed>& seeds) {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = i + 1; j < SEED_COUNT; ++j) {\n            long long s_max = 0;\n            for (int l = 0; l < M; ++l) {\n                s_max += max(seeds[i].x[l], seeds[j].x[l]);\n            }\n            // Using a squared sum targets both high mean and variance in offspring.\n            P2[i][j] = P2[j][i] = s_max * s_max;\n        }\n        P2[i][i] = 0;\n    }\n}\n\nint main() {\n    // Fast Standard IO optimization.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, m_in, t_in;\n    if (!(cin >> n_in >> m_in >> t_in)) return 0;\n\n    vector<Seed> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            if (!(cin >> seeds[i].x[j])) return 0;\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    mt19937 rng(1337);\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    for (int t = 0; t < T_MAX; ++t) {\n        precompute_potentials(seeds);\n\n        // Initial Selection: Diversity (best per dimension) + top total sums.\n        vector<int> selection;\n        vector<bool> is_selected(SEED_COUNT, false);\n        for (int l = 0; l < M; ++l) {\n            int best_idx = -1, max_val = -1;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (seeds[i].x[l] > max_val) {\n                    max_val = seeds[i].x[l];\n                    best_idx = i;\n                }\n            }\n            if (best_idx != -1 && !is_selected[best_idx]) {\n                is_selected[best_idx] = true;\n                selection.push_back(best_idx);\n            }\n        }\n        vector<int> sorted_indices(SEED_COUNT);\n        iota(sorted_indices.begin(), sorted_indices.end(), 0);\n        sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n        for (int idx : sorted_indices) {\n            if (selection.size() < PLANT_COUNT && !is_selected[idx]) {\n                is_selected[idx] = true;\n                selection.push_back(idx);\n            }\n        }\n\n        // Setup the initial planting grid and the off-grid pool.\n        int grid[N][N];\n        int off_grid[UNUSED_COUNT];\n        int sel_idx = 0;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                grid[r][c] = selection[sel_idx++];\n            }\n        }\n        int off_idx = 0;\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            if (!is_selected[i]) off_grid[off_idx++] = i;\n        }\n\n        // Helper to calculate the sum of edge potentials connected to a square.\n        auto get_local_score = [&](int r, int c) {\n            long long res = 0;\n            if (r > 0) res += P2[grid[r][c]][grid[r - 1][c]];\n            if (r < N - 1) res += P2[grid[r][c]][grid[r + 1][c]];\n            if (c > 0) res += P2[grid[r][c]][grid[r][c - 1]];\n            if (c < N - 1) res += P2[grid[r][c]][grid[r][c + 1]];\n            return res;\n        };\n\n        // Current total potential of the grid.\n        long long current_total_score = 0;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r + 1 < N) current_total_score += P2[grid[r][c]][grid[r + 1][c]];\n                if (c + 1 < N) current_total_score += P2[grid[r][c]][grid[r][c + 1]];\n            }\n        }\n\n        long long best_total_score = current_total_score;\n        int best_grid[N][N];\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n\n        // Simulated Annealing Parameters.\n        auto turn_start = chrono::steady_clock::now();\n        const double TIME_LIMIT = 0.19;\n        const double start_temp = 50000.0;\n        const double end_temp = 100.0;\n        int iterations = 0;\n\n        while (true) {\n            // Check time limit periodically.\n            if ((iterations & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - turn_start).count();\n                if (elapsed > TIME_LIMIT) break;\n                double temp = start_temp * pow(end_temp / start_temp, elapsed / TIME_LIMIT);\n\n                for (int step = 0; step < 1024; ++step) {\n                    int move_type = rng() % 2;\n                    if (move_type == 0) {\n                        // Neighborhood move: Swap two grid seeds.\n                        int r1 = rng() % N, c1 = rng() % N;\n                        int r2 = rng() % N, c2 = rng() % N;\n                        if (r1 == r2 && c1 == c2) continue;\n\n                        long long old_l = get_local_score(r1, c1) + get_local_score(r2, c2);\n                        swap(grid[r1][c1], grid[r2][c2]);\n                        long long new_l = get_local_score(r1, c1) + get_local_score(r2, c2);\n                        long long diff = new_l - old_l;\n\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_score) {\n                                best_total_score = current_total_score;\n                                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n                            }\n                        } else {\n                            swap(grid[r1][c1], grid[r2][c2]); // Revert move.\n                        }\n                    } else {\n                        // Neighborhood move: Swap a grid seed with a pool seed.\n                        int r = rng() % N, c = rng() % N;\n                        int idx = rng() % UNUSED_COUNT;\n\n                        long long old_l = get_local_score(r, c);\n                        swap(grid[r][c], off_grid[idx]);\n                        long long new_l = get_local_score(r, c);\n                        long long diff = new_l - old_l;\n\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_score) {\n                                best_total_score = current_total_score;\n                                for (int rr = 0; rr < N; ++rr) for (int cc = 0; cc < N; ++cc) best_grid[rr][cc] = grid[rr][cc];\n                            }\n                        } else {\n                            swap(grid[r][c], off_grid[idx]); // Revert move.\n                        }\n                    }\n                }\n            }\n            iterations++;\n        }\n\n        // Turn output.\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                cout << best_grid[r][c] << (c == N - 1 ? \"\" : \" \");\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read resulting generation for the next turn.\n        if (t < T_MAX - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                seeds[i].v = 0;\n                for (int j = 0; j < M; ++j) {\n                    if (!(cin >> seeds[i].x[j])) return 0;\n                    seeds[i].v += seeds[i].x[j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * Heuristic approach for the takoyaki robotic arm problem.\n * The robotic arm is designed as a star structure (vertex 0 is the root, all others are fingertips).\n * A greedy task selection strategy is used: the arm identifies the closest pickup or delivery task\n * and moves towards it while allowing all fingertips to pick or release takoyakis if they pass \n * over suitable squares during the movement.\n */\n\nstruct Takoyaki {\n    int sx, sy, tx, ty;\n    int state; // 0: unpicked, 1: holding, 2: delivered\n    int finger_id;\n};\n\nint main() {\n    // Optimize standard I/O for faster processing\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n\n    // Read the grid configurations\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Identify start and target squares for all takoyakis\n    vector<pair<int, int>> S_positions, T_positions;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') S_positions.push_back({i, j});\n            if (t_grid[i][j] == '1') T_positions.push_back({i, j});\n        }\n    }\n\n    // Match each initial takoyaki with its nearest available target square greedily\n    vector<Takoyaki> takoyakis(M);\n    vector<bool> target_assigned(M, false);\n    for (int i = 0; i < M; ++i) {\n        int best_j = -1, best_dist = 1e9;\n        for (int j = 0; j < M; ++j) {\n            if (!target_assigned[j]) {\n                int dist = abs(S_positions[i].first - T_positions[j].first) + abs(S_positions[i].second - T_positions[j].second);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_j = j;\n                }\n            }\n        }\n        takoyakis[i] = {S_positions[i].first, S_positions[i].second, T_positions[best_j].first, T_positions[best_j].second, 0, -1};\n        target_assigned[best_j] = true;\n    }\n\n    // Tracker for the takoyakis currently located on specific grid squares\n    vector<vector<int>> grid_takoyaki_id(N, vector<int>(N, -1));\n    vector<vector<bool>> grid_has_takoyaki(N, vector<bool>(N, false));\n    int delivered_count = 0;\n    for (int j = 0; j < M; ++j) {\n        if (takoyakis[j].sx == takoyakis[j].tx && takoyakis[j].sy == takoyakis[j].ty) {\n            // Already at target position\n            takoyakis[j].state = 2;\n            delivered_count++;\n            grid_has_takoyaki[takoyakis[j].sx][takoyakis[j].sy] = true;\n        } else {\n            grid_takoyaki_id[takoyakis[j].sx][takoyakis[j].sy] = j;\n            grid_has_takoyaki[takoyakis[j].sx][takoyakis[j].sy] = true;\n        }\n    }\n\n    // Robotic arm design: root (vertex 0) connected to V-1 fingers (fingertips)\n    cout << V << \"\\n\";\n    vector<int> finger_lengths(V, 0);\n    for (int i = 1; i < V; ++i) {\n        // Diversify finger lengths, ensuring a finger of length 1 exists for universal reachability\n        finger_lengths[i] = (i - 1) % (N - 1) + 1;\n        cout << 0 << \" \" << finger_lengths[i] << \"\\n\";\n    }\n\n    // Initial position of the root\n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n\n    // Absolute directions in grid coordinates: Right, Down, Left, Up\n    int drow[] = {0, 1, 0, -1};\n    int dcol[] = {1, 0, -1, 0};\n    vector<int> finger_dirs(V, 0); // All fingers initially point Right (dir 0)\n    vector<int> finger_holding(V, -1); // Index of takoyaki being held by the finger\n\n    // Update current finger direction and return the required rotation command\n    auto get_rot_char = [&](int& cur_d, int target_d) {\n        if (cur_d == target_d) return '.';\n        if ((cur_d + 1) % 4 == target_d) { cur_d = (cur_d + 1) % 4; return 'R'; } // Clockwise\n        if ((cur_d + 3) % 4 == target_d) { cur_d = (cur_d + 3) % 4; return 'L'; } // Counter-clockwise\n        cur_d = (cur_d + 1) % 4; return 'R'; // 180 degrees case\n    };\n\n    int turns = 0;\n    // Simulation loop\n    while (delivered_count < M && turns < 100000) {\n        int best_cost = 1e9;\n        int focus_j = -1, focus_f = -1, focus_d = -1;\n        int target_rx = -1, target_ry = -1;\n\n        // Choose the next focus task (pickup or delivery) that is closest in turns\n        for (int j = 0; j < M; ++j) {\n            if (takoyakis[j].state == 2) continue;\n            bool is_pickup = (takoyakis[j].state == 0);\n            int tx = is_pickup ? takoyakis[j].sx : takoyakis[j].tx;\n            int ty = is_pickup ? takoyakis[j].sy : takoyakis[j].ty;\n            \n            // Avoid attempting delivery if the target square is currently blocked by a takoyaki (state 0)\n            if (!is_pickup && grid_has_takoyaki[tx][ty]) continue;\n\n            for (int f = 1; f < V; ++f) {\n                if (is_pickup && finger_holding[f] != -1) continue;\n                if (!is_pickup && takoyakis[j].finger_id != f) continue;\n                \n                for (int d = 0; d < 4; ++d) {\n                    int trx = tx - drow[d] * finger_lengths[f];\n                    int try_ = ty - dcol[d] * finger_lengths[f];\n                    if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                        int dist_cost = abs(rx - trx) + abs(ry - try_);\n                        int rot_cost = (finger_dirs[f] == d ? 0 : (abs(finger_dirs[f] - d) == 2 ? 2 : 1));\n                        int total_cost = max(dist_cost, rot_cost);\n                        if (total_cost < best_cost) {\n                            best_cost = total_cost; focus_j = j; focus_f = f; focus_d = d;\n                            target_rx = trx; target_ry = try_;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (focus_j == -1) break; // All available tasks are completed or blocked\n\n        int focus_initial_state = takoyakis[focus_j].state;\n        // Inner movement loop: progress the root and fingers towards the chosen task's target\n        while (turns < 100000) {\n            string turn_op = \"\";\n            // Step 1: Root movement\n            if (rx < target_rx) { rx++; turn_op += 'D'; }\n            else if (rx > target_rx) { rx--; turn_op += 'U'; }\n            else if (ry < target_ry) { ry++; turn_op += 'R'; }\n            else if (ry > target_ry) { ry--; turn_op += 'L'; }\n            else turn_op += '.';\n\n            // Step 2: Finger subtree rotations\n            for (int f = 1; f < V; ++f) {\n                if (f == focus_f) turn_op += get_rot_char(finger_dirs[f], focus_d);\n                else turn_op += '.';\n            }\n\n            // Step 3: Finger pickup/release actions\n            string act_part = \".\"; // Root vertex 0 doesn't act\n            for (int f = 1; f < V; ++f) {\n                int fr = rx + drow[finger_dirs[f]] * finger_lengths[f];\n                int fc = ry + dcol[finger_dirs[f]] * finger_lengths[f];\n                bool acted = false;\n                if (fr >= 0 && fr < N && fc >= 0 && fc < N) {\n                    if (finger_holding[f] == -1) {\n                        int tid = grid_takoyaki_id[fr][fc];\n                        if (tid != -1 && takoyakis[tid].state == 0) {\n                            takoyakis[tid].state = 1; takoyakis[tid].finger_id = f;\n                            finger_holding[f] = tid; grid_has_takoyaki[fr][fc] = false;\n                            grid_takoyaki_id[fr][fc] = -1; act_part += 'P'; acted = true;\n                        }\n                    } else {\n                        int tid = finger_holding[f];\n                        if (fr == takoyakis[tid].tx && fc == takoyakis[tid].ty && !grid_has_takoyaki[fr][fc]) {\n                            takoyakis[tid].state = 2; finger_holding[f] = -1;\n                            grid_has_takoyaki[fr][fc] = true; delivered_count++;\n                            act_part += 'P'; acted = true;\n                        }\n                    }\n                }\n                if (!acted) act_part += '.';\n            }\n            cout << turn_op << act_part << \"\\n\";\n            turns++;\n\n            // Break if simulation ends or focus status changes\n            if (delivered_count == M) break;\n            if (takoyakis[focus_j].state != focus_initial_state) break;\n            if (rx == target_rx && ry == target_ry && finger_dirs[focus_f] == focus_d) break;\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n// Coordinate grid and DP constants\n// Grid size is set to 60 to ensure coordinate compression provides distinct grid points\n// and to keep the DP performance high.\nconst int G_MAX = 65;\nconst long long INF = 1e18;\nconst long long SCALE = 100000000LL; // Scaling factor to handle mackerel-sardine score and perimeter in the same DP.\n\nstruct Point {\n    int x, y;\n};\n\nstruct Result {\n    long long score; // Final mackerel - sardine score (a - b)\n    int i_start, i_end;\n    vector<pair<int, int>> path;\n    bool swapped;\n    vector<int> xs, ys;\n};\n\n// Global memory tables to reduce stack usage and memory allocation time.\nstatic int cell_score[G_MAX][G_MAX];\nstatic int row_sum[G_MAX][G_MAX + 1];\nstatic long long dp[G_MAX][G_MAX][G_MAX];\nstatic pair<short, short> p_table[G_MAX][G_MAX][G_MAX];\n\n/**\n * Solve function finding an optimal x-monotone rectilinear polygon.\n * Coordinate compression focuses the search on regions with fish.\n */\nResult solve_with_grid(int N, const vector<Point>& macks, const vector<Point>& sards, bool swap_xy, int grid_size) {\n    vector<Point> m = macks, s = sards;\n    // Transpose if searching for y-monotone polygons.\n    if (swap_xy) {\n        for (int i = 0; i < N; ++i) {\n            swap(m[i].x, m[i].y);\n            swap(s[i].x, s[i].y);\n        }\n    }\n\n    // Coordinate compression for the grid.\n    vector<int> X, Y;\n    for (int i = 0; i < N; ++i) {\n        X.push_back(m[i].x); Y.push_back(m[i].y);\n        X.push_back(s[i].x); Y.push_back(s[i].y);\n    }\n    X.push_back(0); X.push_back(100000);\n    Y.push_back(0); Y.push_back(100000);\n    sort(X.begin(), X.end()); X.erase(unique(X.begin(), X.end()), X.end());\n    sort(Y.begin(), Y.end()); Y.erase(unique(Y.begin(), Y.end()), Y.end());\n\n    vector<int> xs, ys;\n    for (int i = 0; i <= grid_size; ++i) {\n        xs.push_back(X[i * (X.size() - 1) / grid_size]);\n        ys.push_back(Y[i * (Y.size() - 1) / grid_size]);\n    }\n\n    // Assign fish to cells and compute prefix sums.\n    for (int i = 0; i < grid_size; ++i) for (int j = 0; j < grid_size; ++j) cell_score[i][j] = 0;\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), m[i].x) - xs.begin(); if (gx > 0 && (gx == grid_size || xs[gx] > m[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), m[i].y) - ys.begin(); if (gy > 0 && (gy == grid_size || ys[gy] > m[i].y)) gy--;\n        if (gx < grid_size && gy < grid_size) cell_score[gx][gy]++;\n    }\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), s[i].x) - xs.begin(); if (gx > 0 && (gx == grid_size || xs[gx] > s[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), s[i].y) - ys.begin(); if (gy > 0 && (gy == grid_size || ys[gy] > s[i].y)) gy--;\n        if (gx < grid_size && gy < grid_size) cell_score[gx][gy]--;\n    }\n\n    for (int i = 0; i < grid_size; ++i) {\n        row_sum[i][0] = 0;\n        for (int j = 0; j < grid_size; ++j) row_sum[i][j + 1] = row_sum[i][j] + cell_score[i][j];\n    }\n\n    // DP initialization.\n    for (int i = 0; i < grid_size; ++i) \n        for (int L = 0; L < grid_size; ++L) \n            for (int R = L; R < grid_size; ++R) \n                dp[i][L][R] = -INF;\n\n    /**\n     * DP state: dp[i][L][R] stores (current_net_fish_score * SCALE - perimeter_cost).\n     * Connectivity between columns is maintained by ensuring vertical intervals [L, R] overlap.\n     */\n    int d_limit = 12; // Maximum jump distance in cells between adjacent columns.\n    for (int i = 0; i < grid_size; ++i) {\n        long long h_cost = 2LL * (xs[i + 1] - xs[i]);\n        for (int L = 0; L < grid_size; ++L) {\n            for (int R = L; R < grid_size; ++R) {\n                long long cur_cell_f = row_sum[i][R + 1] - row_sum[i][L];\n                // Case: Polygon starts at this column.\n                dp[i][L][R] = cur_cell_f * SCALE - (ys[R + 1] - ys[L]) - h_cost;\n                p_table[i][L][R] = { -1, -1 };\n                // Case: Polygon extends from previous column.\n                if (i > 0) {\n                    for (int L1 = max(0, L - d_limit); L1 <= min(grid_size - 1, L + d_limit); ++L1) {\n                        for (int R1 = max(L1, R - d_limit); R1 <= min(grid_size - 1, R + d_limit); ++R1) {\n                            if (dp[i-1][L1][R1] == -INF) continue;\n                            // Ensure the vertical segments at boundary x overlap to maintain a single connected polygon.\n                            if (max(L, L1) > min(R, R1)) continue; \n                            long long v_cost = (long long)abs(ys[L] - ys[L1]) + abs(ys[R + 1] - ys[R1 + 1]);\n                            long long val = dp[i - 1][L1][R1] + cur_cell_f * SCALE - v_cost - h_cost;\n                            if (val > dp[i][L][R]) {\n                                dp[i][L][R] = val;\n                                p_table[i][L][R] = { (short)L1, (short)R1 };\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Global best selection from all valid DP paths.\n    long long best_val = -1;\n    int bi = -1, bl = -1, br = -1;\n    for (int i = 0; i < grid_size; ++i) {\n        for (int L = 0; L < grid_size; ++L) {\n            for (int R = L; R < grid_size; ++R) {\n                if (dp[i][L][R] == -INF) continue;\n                // Add vertical edge at the end of the polygon.\n                long long total_fv = dp[i][L][R] - (ys[R + 1] - ys[L]);\n                long long a_minus_b = (total_fv >= 0) ? (total_fv + SCALE / 2) / SCALE : (total_fv - SCALE / 2) / SCALE;\n                long long total_perim = a_minus_b * SCALE - total_fv;\n                if (total_perim <= 400000 && a_minus_b > best_val) {\n                    best_val = a_minus_b; bi = i; bl = L; br = R;\n                }\n            }\n        }\n    }\n\n    if (bi == -1) return { -1, -1, -1, {}, swap_xy, xs, ys };\n    \n    // Backtrack to build the interval path.\n    vector<pair<int, int>> path;\n    int ci = bi, cl = bl, cr = br;\n    while (ci >= 0 && cl != -1) {\n        path.push_back({ cl, cr });\n        auto p = p_table[ci][cl][cr];\n        cl = p.first; cr = p.second; ci--;\n    }\n    reverse(path.begin(), path.end());\n    return { best_val, bi - (int)path.size() + 1, bi, path, swap_xy, xs, ys };\n}\n\n/**\n * Converts the x-monotone interval sequence into a list of clockwise vertices.\n */\nvoid output(const Result& res) {\n    if (res.score <= 0) { \n        cout << \"4\\n0 0\\n0 100000\\n100000 100000\\n100000 0\" << endl; \n        return; \n    }\n    vector<pair<int, int>> v;\n    int n = res.path.size();\n    // Left edge\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].first] });\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].second + 1] });\n    // Top boundary path\n    for (int i = 0; i < n - 1; ++i) {\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i].second + 1] });\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i + 1].second + 1] });\n    }\n    // Right edge\n    v.push_back({ res.xs[res.i_end + 1], res.ys[res.path.back().second + 1] });\n    v.push_back({ res.xs[res.i_end + 1], res.ys[res.path.back().first] });\n    // Bottom boundary path\n    for (int i = n - 1; i > 0; --i) {\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i].first] });\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i - 1].first] });\n    }\n\n    if (res.swapped) for (auto& p : v) swap(p.first, p.second);\n    \n    // Cleanup consecutive duplicate vertices.\n    vector<pair<int, int>> uv;\n    for (auto p : v) if (uv.empty() || p != uv.back()) uv.push_back(p);\n    while (uv.size() > 1 && uv.front() == uv.back()) uv.pop_back();\n\n    cout << uv.size() << endl;\n    for (auto p : uv) cout << p.first << \" \" << p.second << endl;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    int N; if (!(cin >> N)) return 0;\n    vector<Point> macks(N), sards(N);\n    for (int i = 0; i < N; ++i) cin >> macks[i].x >> macks[i].y;\n    for (int i = 0; i < N; ++i) cin >> sards[i].x >> sards[i].y;\n\n    Result best_res = { -1, -1, -1, {}, false, {}, {} };\n    // Try both orientations to maximize mackerel catch.\n    for (bool swap_xy : {false, true}) {\n        Result res = solve_with_grid(N, macks, sards, swap_xy, 60);\n        if (res.score > best_res.score) best_res = res;\n    }\n    output(best_res);\n    return 0;\n}\n","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Structure for a rectangle's placement on the 2D plane\nstruct Rect {\n    long long x, y, xw, yh;\n};\n\n// Configuration of placements for all N rectangles\nstruct Config {\n    int r[100]; // 0: no rotation (width x height), 1: 90-degree rotation (height x width)\n    int d[100]; // 0: Upward ('U'), 1: Leftward ('L')\n    int b[100]; // Index of the reference rectangle (-1 for coordinate axis)\n};\n\nint main() {\n    // Standard optimization for faster input and output\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T_turns;\n    double sigma_val;\n    if (!(cin >> N >> T_turns >> sigma_val)) return 0;\n\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // Time management utility\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_time = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    mt19937 rng(42);\n\n    // Initial estimates based on provided noisy measurements\n    vector<double> w_est(N), h_est(N);\n    vector<int> k_counts(N, 1);\n    for (int i = 0; i < N; ++i) {\n        w_est[i] = (double)w_obs[i];\n        h_est[i] = (double)h_obs[i];\n    }\n\n    // Measurement Phase: Determine how many turns to spend on individual rectangle measurements\n    // to improve our width and height estimates.\n    int T_pack = max(1, T_turns / 5);\n    if (T_turns >= 10 && T_pack < 5) T_pack = 5;\n    int M = max(0, min(T_turns - T_pack, (int)(N * 1.5)));\n\n    vector<int> idx_to_measure(N);\n    for (int i = 0; i < N; ++i) idx_to_measure[i] = i;\n    // Prioritize measuring the largest rectangles first\n    sort(idx_to_measure.begin(), idx_to_measure.end(), [&](int a, int b) {\n        return (w_obs[a] + h_obs[a]) > (w_obs[b] + h_obs[b]);\n    });\n\n    for (int t = 0; t < M; ++t) {\n        int i = idx_to_measure[t % N];\n        // Measure only one rectangle to get a direct (noisy) reading of its dimensions\n        cout << 1 << \"\\n\";\n        cout << i << \" 0 U -1\\n\" << flush;\n        long long W_prime, H_prime;\n        if (!(cin >> W_prime >> H_prime)) break;\n        // Refine the mean estimate using a simple running average\n        w_est[i] = (w_est[i] * k_counts[i] + (double)W_prime) / (k_counts[i] + 1);\n        h_est[i] = (h_est[i] * k_counts[i] + (double)H_prime) / (k_counts[i] + 1);\n        k_counts[i]++;\n    }\n\n    // Packing Phase functions\n    // Calculate the placement of rectangles starting from index k\n    auto evaluate_from = [&](int k, int n_rects, const Config& conf, Rect* p, const vector<long long>& w, const vector<long long>& h) {\n        for (int i = k; i < n_rects; ++i) {\n            long long cur_w = conf.r[i] ? h[i] : w[i];\n            long long cur_h = conf.r[i] ? w[i] : h[i];\n            long long cur_x = 0, cur_y = 0;\n            if (conf.d[i] == 0) { // 'U'\n                cur_x = (conf.b[i] == -1) ? 0 : p[conf.b[i]].xw;\n                for (int j = 0; j < i; ++j) {\n                    if (cur_x < p[j].xw && p[j].x < cur_x + cur_w) {\n                        if (p[j].yh > cur_y) cur_y = p[j].yh;\n                    }\n                }\n            } else { // 'L'\n                cur_y = (conf.b[i] == -1) ? 0 : p[conf.b[i]].yh;\n                for (int j = 0; j < i; ++j) {\n                    if (cur_y < p[j].yh && p[j].y < cur_y + cur_h) {\n                        if (p[j].xw > cur_x) cur_x = p[j].xw;\n                    }\n                }\n            }\n            p[i] = {cur_x, cur_y, cur_x + cur_w, cur_y + cur_h};\n        }\n    };\n\n    auto get_score = [&](int n_rects, Rect* p) {\n        long long max_w = 0, max_h = 0;\n        for (int i = 0; i < n_rects; ++i) {\n            if (p[i].xw > max_w) max_w = p[i].xw;\n            if (p[i].yh > max_h) max_h = p[i].yh;\n        }\n        return max_w + max_h;\n    };\n\n    Config current_config;\n    for (int i = 0; i < N; ++i) {\n        current_config.r[i] = (w_est[i] < h_est[i] ? 1 : 0);\n        current_config.d[i] = (rng() % 2);\n        current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n    }\n\n    Config best_overall_config = current_config;\n    long long best_measured_score = -1;\n\n    // Remaining turns used to find the best packing using Simulated Annealing\n    for (int t = M; t < T_turns; ++t) {\n        double turn_start_time = elapsed_time();\n        double turn_time_limit = (2.95 - turn_start_time) / (T_turns - t);\n\n        // Sample potential true dimensions based on the estimated mean and standard error\n        vector<long long> w_sample(N), h_sample(N);\n        for (int i = 0; i < N; ++i) {\n            normal_distribution<double> dist_w(w_est[i], sigma_val / sqrt(k_counts[i]));\n            normal_distribution<double> dist_h(h_est[i], sigma_val / sqrt(k_counts[i]));\n            w_sample[i] = max(1LL, min(1000000000LL, (long long)round(dist_w(rng))));\n            h_sample[i] = max(1LL, min(1000000000LL, (long long)round(dist_h(rng))));\n        }\n\n        // Initialize from the best overall or a fresh random state\n        if (best_measured_score != -1 && (rng() % 100 < 70)) {\n            current_config = best_overall_config;\n        } else {\n            for (int i = 0; i < N; ++i) {\n                current_config.r[i] = (rng() % 2);\n                current_config.d[i] = (rng() % 2);\n                current_config.b[i] = (int)(rng() % (i + 1)) - 1;\n            }\n        }\n\n        Rect placed[100];\n        evaluate_from(0, N, current_config, placed, w_sample, h_sample);\n        long long current_score = get_score(N, placed);\n        Config best_in_turn = current_config;\n        long long best_score_in_turn = current_score;\n\n        double t_start = sigma_val;\n        double t_end = 1.0;\n        uniform_real_distribution<double> dist01(0, 1);\n\n        // Perform SA for the allocated time of the turn\n        while (elapsed_time() - turn_start_time < turn_time_limit) {\n            int k = rng() % N;\n            int old_r = current_config.r[k], old_d = current_config.d[k], old_b = current_config.b[k];\n            Rect backup_p[100];\n            for (int i = k; i < N; ++i) backup_p[i] = placed[i];\n\n            int type = rng() % 3;\n            if (type == 0) current_config.r[k] = 1 - current_config.r[k];\n            else if (type == 1) current_config.d[k] = 1 - current_config.d[k];\n            else current_config.b[k] = (int)(rng() % (k + 1)) - 1;\n\n            evaluate_from(k, N, current_config, placed, w_sample, h_sample);\n            long long new_score = get_score(N, placed);\n            double ratio = (elapsed_time() - turn_start_time) / turn_time_limit;\n            double temp = t_start * pow(t_end / t_start, ratio);\n\n            if (new_score < current_score || dist01(rng) < exp((double)(current_score - new_score) / temp)) {\n                current_score = new_score;\n                if (new_score < best_score_in_turn) {\n                    best_score_in_turn = new_score;\n                    best_in_turn = current_config;\n                }\n            } else {\n                current_config.r[k] = old_r; current_config.d[k] = old_d; current_config.b[k] = old_b;\n                for (int i = k; i < N; ++i) placed[i] = backup_p[i];\n            }\n        }\n\n        // Final output for the current turn\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; ++i) {\n            cout << i << \" \" << best_in_turn.r[i] << \" \" << (best_in_turn.d[i] == 0 ? 'U' : 'L') << \" \" << best_in_turn.b[i] << \"\\n\";\n        }\n        cout << flush;\n\n        // Feedback from the judge\n        long long W_feedback, H_feedback;\n        if (!(cin >> W_feedback >> H_feedback)) break;\n        // We track the configuration that resulted in the smallest measured bounding box perimeter\n        if (best_measured_score == -1 || (W_feedback + H_feedback) < best_measured_score) {\n            best_measured_score = W_feedback + H_feedback;\n            best_overall_config = best_in_turn;\n        }\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#include <numeric>\n\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int H_LIMIT = 10;\n\nint N, M, H_input;\nlong long A[MAXN];\nvector<int> adj[MAXN];\nint parent_v[MAXN];\nvector<int> children_v[MAXN];\nint depth_v[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_depth_rel[MAXN];\n\n// Fast check for ancestor within height limit to prevent cycles\nbool is_ancestor(int u, int v) {\n    if (u == -1) return false;\n    int curr = v;\n    int count = 0;\n    while (curr != -1 && count <= H_LIMIT + 2) {\n        if (curr == u) return true;\n        curr = parent_v[curr];\n        count++;\n    }\n    return false;\n}\n\n// Recompute beauty sum and relative max depth for node u\nvoid recompute_node_metrics(int u) {\n    long long sum = A[u];\n    int mx = 0;\n    for (int child : children_v[u]) {\n        sum += subtree_sum_A[child];\n        mx = max(mx, max_depth_rel[child] + 1);\n    }\n    subtree_sum_A[u] = sum;\n    max_depth_rel[u] = mx;\n}\n\n// Update a node and its ancestors after a change in its subtree\nvoid update_ancestors(int u) {\n    int count = 0;\n    while (u != -1 && count <= H_LIMIT + 2) {\n        long long old_sum = subtree_sum_A[u];\n        int old_mx = max_depth_rel[u];\n        recompute_node_metrics(u);\n        if (subtree_sum_A[u] == old_sum && max_depth_rel[u] == old_mx) break;\n        u = parent_v[u];\n        count++;\n    }\n}\n\n// Propagate depth changes down the subtree\nvoid update_subtree_depth(int u, int d) {\n    depth_v[u] = d;\n    for (int child : children_v[u]) {\n        update_subtree_depth(child, d + 1);\n    }\n}\n\n// Move a node and its entire subtree to a new parent\nvoid move_v(int v, int new_p) {\n    int old_p = parent_v[v];\n    if (old_p != -1) {\n        auto& cv = children_v[old_p];\n        for (size_t i = 0; i < cv.size(); ++i) {\n            if (cv[i] == v) {\n                cv[i] = cv.back();\n                cv.pop_back();\n                break;\n            }\n        }\n        update_ancestors(old_p);\n    }\n    parent_v[v] = new_p;\n    if (new_p != -1) {\n        children_v[new_p].push_back(v);\n        update_subtree_depth(v, depth_v[new_p] + 1);\n        update_ancestors(new_p);\n    } else {\n        update_subtree_depth(v, 0);\n        update_ancestors(-1); \n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> H_input)) 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; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    for (int i = 0; i < N; ++i) {\n        parent_v[i] = -1; depth_v[i] = 0; children_v[i].clear();\n        subtree_sum_A[i] = A[i]; max_depth_rel[i] = 0;\n    }\n\n    mt19937 mt(42);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    sort(nodes.begin(), nodes.end(), [&](int i, int j) { return A[i] > A[j]; });\n\n    // Greedy start\n    for (int v : nodes) {\n        int best_p = -1, max_h = -1;\n        for (int p : adj[v]) {\n            if (!is_ancestor(v, p) && depth_v[p] + 1 + max_depth_rel[v] <= H_LIMIT) {\n                if (depth_v[p] > max_h) { max_h = depth_v[p]; best_p = p; }\n            }\n        }\n        if (best_p != -1) move_v(v, best_p);\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    double T_start = 2000.0, T_end = 0.1, log_T_ratio = log(T_end / T_start);\n    long long iter = 0; \n    double T = T_start;\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Simulated Annealing\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 1.92) break;\n            T = T_start * exp(log_T_ratio * (elapsed / 1.92));\n        }\n        iter++;\n        int v = mt() % N;\n        int deg = (int)adj[v].size();\n        int r = mt() % (deg + 1);\n        int new_p = (r == deg) ? -1 : adj[v][r];\n\n        if (new_p == parent_v[v]) continue;\n\n        bool ok = (new_p == -1) || (depth_v[new_p] + 1 + max_depth_rel[v] <= H_LIMIT && !is_ancestor(v, new_p));\n        if (ok) {\n            int old_d = depth_v[v];\n            int new_d = (new_p == -1 ? 0 : depth_v[new_p] + 1);\n            long long delta = (long long)(new_d - old_d) * subtree_sum_A[v];\n            if (delta >= 0 || (T > 0 && dist(mt) < exp((double)delta / T))) {\n                move_v(v, new_p);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << parent_v[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#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 20;\n\nstruct Oni {\n    int r, c;\n    vector<int> safe_dirs; // 0:L, 1:R, 2:U, 3:D\n};\n\n// Calculate cost for the last dimension set. These shifts don't need a final move back.\nint cost_last(int move1, int move2) {\n    if (move1 > 0 && move2 > 0) return min(2 * move1 + move2, 2 * move2 + move1);\n    return max(move1, move2);\n}\n\n// Calculate the total number of operations T for a specific direction assignment.\nint calculate_total_cost(const vector<Oni>& onis, const vector<int>& d, bool rows_last) {\n    int L[N] = {0}, R[N] = {0}, U[N] = {0}, D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        if (d[i] == 0) L[onis[i].r] = max(L[onis[i].r], onis[i].c + 1);\n        else if (d[i] == 1) R[onis[i].r] = max(R[onis[i].r], N - onis[i].c);\n        else if (d[i] == 2) U[onis[i].c] = max(U[onis[i].c], onis[i].r + 1);\n        else if (d[i] == 3) D[onis[i].c] = max(D[onis[i].c], N - onis[i].r);\n    }\n    int total = 0;\n    if (rows_last) {\n        for (int j = 0; j < N; ++j) total += 2 * (U[j] + D[j]);\n        for (int i = 0; i < N; ++i) total += cost_last(L[i], R[i]);\n    } else {\n        for (int i = 0; i < N; ++i) total += 2 * (L[i] + R[i]);\n        for (int j = 0; j < N; ++j) total += cost_last(U[j], D[j]);\n    }\n    return total;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in;\n    if (!(cin >> n_in)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // Pre-calculate safe shift distances for each row and column based on Fukunokami locations.\n    int max_L[N], max_R[N], max_U[N], max_D[N];\n    for (int i = 0; i < N; ++i) {\n        max_L[i] = N;\n        for (int j = 0; j < N; ++j) if (board[i][j] == 'o') { max_L[i] = j; break; }\n        max_R[i] = N;\n        for (int j = N - 1; j >= 0; --j) if (board[i][j] == 'o') { max_R[i] = N - 1 - j; break; }\n    }\n    for (int j = 0; j < N; ++j) {\n        max_U[j] = N;\n        for (int i = 0; i < N; ++i) if (board[i][j] == 'o') { max_U[j] = i; break; }\n        max_D[j] = N;\n        for (int i = N - 1; i >= 0; --i) if (board[i][j] == 'o') { max_D[j] = N - 1 - i; break; }\n    }\n\n    vector<Oni> onis;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                Oni oni; oni.r = i; oni.c = j;\n                if (j + 1 <= max_L[i]) oni.safe_dirs.push_back(0);\n                if (N - j <= max_R[i]) oni.safe_dirs.push_back(1);\n                if (i + 1 <= max_U[j]) oni.safe_dirs.push_back(2);\n                if (N - i <= max_D[j]) oni.safe_dirs.push_back(3);\n                onis.push_back(oni);\n            }\n        }\n    }\n\n    if (onis.empty()) return 0;\n\n    mt19937 rng(42);\n    vector<int> current_d(onis.size());\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        current_d[i] = onis[i].safe_dirs[rng() % onis[i].safe_dirs.size()];\n    }\n\n    auto get_best_cost = [&](const vector<int>& d, bool& out_rows_last) {\n        int r_cost = calculate_total_cost(onis, d, true);\n        int c_cost = calculate_total_cost(onis, d, false);\n        if (r_cost <= c_cost) { out_rows_last = true; return r_cost; }\n        else { out_rows_last = false; return c_cost; }\n    };\n\n    bool current_rows_last;\n    int current_cost = get_best_cost(current_d, current_rows_last);\n    \n    auto start_time = chrono::steady_clock::now();\n    double start_temp = 10.0, end_temp = 0.1;\n    long long iter = 0;\n    \n    // Simulated Annealing to find the direction assignment that minimizes T.\n    while (true) {\n        if ((iter & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > 1950) break;\n        }\n        iter++;\n        int k = rng() % onis.size();\n        if (onis[k].safe_dirs.size() <= 1) continue;\n        int old_dir = current_d[k];\n        int new_dir = onis[k].safe_dirs[rng() % onis[k].safe_dirs.size()];\n        if (new_dir == old_dir) continue;\n        current_d[k] = new_dir;\n        bool next_rows_last;\n        int next_cost = get_best_cost(current_d, next_rows_last);\n        double diff = next_cost - current_cost;\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        double temp = start_temp + (end_temp - start_temp) * (elapsed / 1950.0);\n        if (diff <= 0 || (temp > 0 && exp(-diff / temp) > (double)rng() / rng.max())) {\n            current_cost = next_cost;\n            current_rows_last = next_rows_last;\n        } else {\n            current_d[k] = old_dir;\n        }\n    }\n\n    // Prepare final output shift values.\n    int L[N] = {0}, R[N] = {0}, U[N] = {0}, D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        if (current_d[i] == 0) L[onis[i].r] = max(L[onis[i].r], onis[i].c + 1);\n        else if (current_d[i] == 1) R[onis[i].r] = max(R[onis[i].r], N - onis[i].c);\n        else if (current_d[i] == 2) U[onis[i].c] = max(U[onis[i].c], onis[i].r + 1);\n        else if (current_d[i] == 3) D[onis[i].c] = max(D[onis[i].c], N - onis[i].r);\n    }\n\n    // Output movements based on the chosen optimal order.\n    if (current_rows_last) {\n        for (int j = 0; j < N; ++j) {\n            if (U[j] > 0 || D[j] > 0) {\n                for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                for (int k = 0; k < U[j] + D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                for (int k = 0; k < D[j]; ++k) cout << \"U \" << j << \"\\n\";\n            }\n        }\n        for (int i = 0; i < N; ++i) {\n            if (L[i] > 0 && R[i] > 0) {\n                if (2 * L[i] + R[i] < 2 * R[i] + L[i]) {\n                    for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                    for (int k = 0; k < L[i] + R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                } else {\n                    for (int k = 0; k < R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                    for (int k = 0; k < R[i] + L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                }\n            } else {\n                if (L[i] > 0) for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                if (R[i] > 0) for (int k = 0; k < R[i]; ++k) cout << \"R \" << i << \"\\n\";\n            }\n        }\n    } else {\n        for (int i = 0; i < N; ++i) {\n            if (L[i] > 0 || R[i] > 0) {\n                for (int k = 0; k < L[i]; ++k) cout << \"L \" << i << \"\\n\";\n                for (int k = 0; k < L[i] + R[i]; ++k) cout << \"R \" << i << \"\\n\";\n                for (int k = 0; k < R[i]; ++k) cout << \"L \" << i << \"\\n\";\n            }\n        }\n        for (int j = 0; j < N; ++j) {\n            if (U[j] > 0 && D[j] > 0) {\n                if (2 * U[j] + D[j] < 2 * D[j] + U[j]) {\n                    for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                    for (int k = 0; k < U[j] + D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                } else {\n                    for (int k = 0; k < D[j]; ++k) cout << \"D \" << j << \"\\n\";\n                    for (int k = 0; k < D[j] + U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                }\n            } else {\n                if (U[j] > 0) for (int k = 0; k < U[j]; ++k) cout << \"U \" << j << \"\\n\";\n                if (D[j] > 0) for (int k = 0; k < D[j]; ++k) cout << \"D \" << j << \"\\n\";\n            }\n        }\n    }\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We need to determine two integers a_i and b_i for each employee i (0 to N-1).\n * Weekly cleaners are decided by the previous cleaner's visit parity.\n * Objective: Minimize sum |actual_visit_count_i - target_T_i| over L weeks.\n *\n * Strategy:\n * 1. Proxy Cost Optimization:\n *    Use the flow balance equations based on parity:\n *    t_j \u2248 delta_{j,0} + sum_{i} (ceil(T_i/2) * [a_i=j] + floor(T_i/2) * [b_i=j])\n *    Minimize sum |t_j - target_T_j| using Simulated Annealing.\n *    This ensures the overall network structure supports the target counts.\n * 2. Fine-Tuning:\n *    Use Hill Climbing based on actual 500,000-week simulations to account for\n *    transient behavior and the exact L-week limit.\n */\n\nconst int N = 100;\nlong long target_T[N];\nint best_final_a[N], best_final_b[N];\nlong long min_actual_err = -1;\n\nlong long U_calls[N], V_calls[N];\n\n// Buffers for proxy cost calculation\nbool reachable[N];\nlong long cur_t_arr[N];\nint bfs_q[N];\nint sim_counts[N];\n\n/**\n * Calculates a proxy error based on target transitions.\n * If target_T[i] visits to node i occur, it sends ceil(target_T[i]/2) to a_i\n * and floor(target_T[i]/2) to b_i.\n */\nlong long get_proxy_cost(const int* a, const int* b) {\n    fill(reachable, reachable + N, false);\n    fill(cur_t_arr, cur_t_arr + N, 0);\n    \n    // Check reachability from starting node 0\n    int head = 0, tail = 0;\n    bfs_q[tail++] = 0;\n    reachable[0] = true;\n    while (head < tail) {\n        int u = bfs_q[head++];\n        int na = a[u];\n        if (!reachable[na]) {\n            reachable[na] = true;\n            bfs_q[tail++] = na;\n        }\n        int nb = b[u];\n        if (!reachable[nb]) {\n            reachable[nb] = true;\n            bfs_q[tail++] = nb;\n        }\n    }\n    \n    // Start count for week 1\n    cur_t_arr[0] = 1;\n    // Calculate expected inflows from reachable nodes\n    for (int i = 0; i < N; ++i) {\n        if (reachable[i]) {\n            cur_t_arr[a[i]] += U_calls[i];\n            cur_t_arr[b[i]] += V_calls[i];\n        }\n    }\n    \n    long long err = 0;\n    for (int i = 0; i < N; ++i) {\n        // Heavy penalty for unreachable nodes that should have cleanings\n        if (!reachable[i] && target_T[i] > 0) {\n            err += 1000000LL + target_T[i];\n        }\n        err += abs(cur_t_arr[i] - target_T[i]);\n    }\n    return err;\n}\n\n/**\n * Performs a full L-week simulation to calculate exact visit counts.\n * Complexity: O(L), where L = 500,000.\n */\nlong long get_actual_err(const int* a, const int* b, int L) {\n    fill(sim_counts, sim_counts + N, 0);\n    int curr = 0;\n    for (int w = 0; w < L; ++w) {\n        sim_counts[curr]++;\n        if (sim_counts[curr] & 1) curr = a[curr];\n        else curr = b[curr];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; ++i) err += abs((long long)sim_counts[i] - target_T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, l_in;\n    if (!(cin >> n_in >> l_in)) return 0;\n    for (int i = 0; i < N; ++i) cin >> target_T[i];\n\n    // Precompute call distributions for each node's target visit count\n    for (int i = 0; i < N; ++i) {\n        U_calls[i] = (target_T[i] + 1) / 2;\n        V_calls[i] = target_T[i] / 2;\n    }\n\n    mt19937 mt(1337);\n    int cur_a[N], cur_b[N];\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = mt() % N;\n        cur_b[i] = mt() % N;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Step 1: Simulated Annealing for proxy error optimization\n    long long cur_proxy_err = get_proxy_cost(cur_a, cur_b);\n    long long best_step1_err = cur_proxy_err;\n    int best_step1_a[N], best_step1_b[N];\n    for(int i=0; i<N; ++i) { best_step1_a[i] = cur_a[i]; best_step1_b[i] = cur_b[i]; }\n\n    const double duration_step1 = 1.0;\n    const double t_start = 2500.0, t_end = 0.1;\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > duration_step1) break;\n        }\n        iters++;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long next_proxy_err = get_proxy_cost(cur_a, cur_b);\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double temp = t_start * pow(t_end / t_start, elapsed / duration_step1);\n        \n        if (next_proxy_err <= cur_proxy_err || \n            (double)mt() / mt.max() < exp((double)(cur_proxy_err - next_proxy_err) / temp)) {\n            cur_proxy_err = next_proxy_err;\n            if (cur_proxy_err < best_step1_err) {\n                best_step1_err = cur_proxy_err;\n                for(int k=0; k<N; ++k) { best_step1_a[k] = cur_a[k]; best_step1_b[k] = cur_b[k]; }\n            }\n        } else {\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Initialize current state with the best found in Step 1\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = best_step1_a[i];\n        cur_b[i] = best_step1_b[i];\n        best_final_a[i] = cur_a[i];\n        best_final_b[i] = cur_b[i];\n    }\n    min_actual_err = get_actual_err(cur_a, cur_b, l_in);\n    \n    // Step 2: Hill Climbing with Actual Simulation for fine-tuning\n    const double duration_total = 1.95;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > duration_total) break;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long actual_err = get_actual_err(cur_a, cur_b, l_in);\n        if (actual_err <= min_actual_err) {\n            min_actual_err = actual_err;\n            for (int i = 0; i < N; ++i) {\n                best_final_a[i] = cur_a[i];\n                best_final_b[i] = cur_b[i];\n            }\n        } else {\n            // Revert on worse score\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Output the final optimal cleaning plan transitions\n    for (int i = 0; i < N; ++i) {\n        cout << best_final_a[i] << \" \" << best_final_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct DSU {\n    vector<int> p;\n    int comps;\n    DSU(int n) : p(n), comps(n) {\n        for (int i = 0; i < n; i++) p[i] = i;\n    }\n    int find(int i) {\n        if (p[i] == i) return i;\n        return p[i] = find(p[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            p[root_i] = root_j;\n            comps--;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v;\n    long long w;\n    bool operator<(const Edge& other) const {\n        if (w != other.w) return w < other.w;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\ndouble hat_x[800], hat_y[800];\nlong long center_dist[800][800];\nvector<int> groups[400];\nint group_id[800];\nint index_in_group[800];\ndouble sum_x[400], sum_y[400], sum_x2[400], sum_y2[400];\nbool is_query_tested[800][800];\nbool is_query_selected[800][800];\n\nvoid update_group_stats(int k, int city, bool adding) {\n    if (adding) {\n        sum_x[k] += hat_x[city];\n        sum_x2[k] += hat_x[city] * hat_x[city];\n        sum_y[k] += hat_y[city];\n        sum_y2[k] += hat_y[city] * hat_y[city];\n    } else {\n        sum_x[k] -= hat_x[city];\n        sum_x2[k] -= hat_x[city] * hat_x[city];\n        sum_y[k] -= hat_y[city];\n        sum_y2[k] -= hat_y[city] * hat_y[city];\n    }\n}\n\ndouble get_group_cost(int k) {\n    int n = G[k];\n    if (n == 0) return 0;\n    double cx2 = sum_x2[k] - (sum_x[k] * sum_x[k] / n);\n    double cy2 = sum_y2[k] - (sum_y[k] * sum_y[k] / n);\n    return max(0.0, cx2 + cy2);\n}\n\nvoid bisect(vector<int> cities, int g_start, int g_end, int depth) {\n    if (g_start + 1 == g_end) {\n        groups[g_start] = cities;\n        return;\n    }\n    int mid = (g_start + g_end) / 2;\n    int left_n = 0;\n    for (int i = g_start; i < mid; i++) left_n += G[i];\n    if (depth % 2 == 0) sort(cities.begin(), cities.end(), [&](int a, int b) { return hat_x[a] < hat_x[b]; });\n    else sort(cities.begin(), cities.end(), [&](int a, int b) { return hat_y[a] < hat_y[b]; });\n    vector<int> left_cities(cities.begin(), cities.begin() + left_n);\n    vector<int> right_cities(cities.begin() + left_n, cities.end());\n    bisect(left_cities, g_start, mid, depth + 1);\n    bisect(right_cities, mid, g_end, depth + 1);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(NULL);\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    for (int i = 0; i < N; i++) {\n        double lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        hat_x[i] = (lx + rx) / 2.0; hat_y[i] = (ly + ry) / 2.0;\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) center_dist[i][j] = 0;\n            else {\n                double dx = hat_x[i] - hat_x[j], dy = hat_y[i] - hat_y[j];\n                center_dist[i][j] = (long long)floor(sqrt(dx * dx + dy * dy) + 1e-9);\n            }\n        }\n    }\n    vector<int> all_cities(N);\n    for (int i = 0; i < N; i++) all_cities[i] = i;\n    bisect(all_cities, 0, M, 0);\n    for (int k = 0; k < M; k++) {\n        sum_x[k] = sum_y[k] = sum_x2[k] = sum_y2[k] = 0;\n        for (int i = 0; i < (int)groups[k].size(); i++) {\n            int c = groups[k][i]; group_id[c] = k; index_in_group[c] = i;\n            update_group_stats(k, c, true);\n        }\n    }\n    mt19937 rng(42);\n    auto sa_start = chrono::steady_clock::now();\n    double T_start = 1000000.0, T_end = 1.0;\n    int iterations = 0;\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - sa_start).count();\n            if (elapsed > 0.6) break;\n            double T = T_start * pow(T_end / T_start, elapsed / 0.6);\n            for (int step = 0; step < 1024; step++) {\n                int u = rng() % N, v = rng() % N;\n                int gU = group_id[u], gV = group_id[v];\n                if (gU == gV) continue;\n                double old_c = get_group_cost(gU) + get_group_cost(gV);\n                update_group_stats(gU, u, false); update_group_stats(gU, v, true);\n                update_group_stats(gV, v, false); update_group_stats(gV, u, true);\n                double new_c = get_group_cost(gU) + get_group_cost(gV);\n                if (new_c < old_c || uniform_real_distribution<double>(0, 1)(rng) < exp((old_c - new_c) / T)) {\n                    int idx_u = index_in_group[u], idx_v = index_in_group[v];\n                    groups[gU][idx_u] = v; groups[gV][idx_v] = u;\n                    group_id[u] = gV; group_id[v] = gU;\n                    index_in_group[u] = idx_v; index_in_group[v] = idx_u;\n                } else {\n                    update_group_stats(gU, v, false); update_group_stats(gU, u, true);\n                    update_group_stats(gV, u, false); update_group_stats(gV, v, true);\n                }\n            }\n            iterations += 1024;\n        }\n    }\n    vector<int> local_idx(N);\n    vector<DSU> dsus;\n    for (int k = 0; k < M; k++) {\n        dsus.emplace_back(G[k]);\n        for (int i = 0; i < (int)groups[k].size(); i++) local_idx[groups[k][i]] = i;\n    }\n    int q_made = 0;\n    bool changed = true;\n    while (q_made < Q && changed) {\n        changed = false;\n        for (int k = 0; k < M; k++) {\n            if (q_made >= Q) break;\n            if (G[k] < 2 || dsus[k].comps == 1) continue;\n            int u_b = -1, v_b = -1; long long d_m = 2e18;\n            for (int i = 0; i < G[k]; i++) {\n                for (int j = i + 1; j < G[k]; j++) {\n                    if (dsus[k].find(i) != dsus[k].find(j)) {\n                        if (center_dist[groups[k][i]][groups[k][j]] < d_m) {\n                            d_m = center_dist[groups[k][i]][groups[k][j]]; u_b = i; v_b = j;\n                        }\n                    }\n                }\n            }\n            if (u_b != -1) {\n                vector<int> C = {groups[k][u_b], groups[k][v_b]};\n                vector<bool> in_C(N, false); in_C[C[0]] = true; in_C[C[1]] = true;\n                while ((int)C.size() < min(L, G[k])) {\n                    int w_b = -1; long long d_w = 2e18;\n                    for (int city : groups[k]) if (!in_C[city]) {\n                        for (int cc : C) if (center_dist[city][cc] < d_w) { d_w = center_dist[city][cc]; w_b = city; }\n                    }\n                    if (w_b != -1) { C.push_back(w_b); in_C[w_b] = true; } else break;\n                }\n                sort(C.begin(), C.end()); cout << \"? \" << C.size();\n                for (int c : C) cout << \" \" << c; cout << endl;\n                q_made++;\n                for (int i = 0; i < (int)C.size(); i++) for (int j = i + 1; j < (int)C.size(); j++) \n                    is_query_tested[C[i]][C[j]] = is_query_tested[C[j]][C[i]] = true;\n                for (int i = 0; i < (int)C.size() - 1; i++) {\n                    int a, b; cin >> a >> b;\n                    is_query_selected[a][b] = is_query_selected[b][a] = true;\n                    dsus[k].unite(local_idx[a], local_idx[b]);\n                }\n                changed = true;\n            }\n        }\n    }\n    while (q_made < Q) {\n        int k = rng() % M; if (G[k] < 2) continue;\n        vector<int> C = groups[k]; shuffle(C.begin(), C.end(), rng);\n        if ((int)C.size() > L) C.resize(L); sort(C.begin(), C.end());\n        cout << \"? \" << C.size(); for (int c : C) cout << \" \" << c; cout << endl;\n        q_made++;\n        for (int i = 0; i < (int)C.size(); i++) for (int j = i + 1; j < (int)C.size(); j++) \n            is_query_tested[C[i]][C[j]] = is_query_tested[C[j]][C[i]] = true;\n        for (int i = 0; i < (int)C.size() - 1; i++) { int a, b; cin >> a >> b; is_query_selected[a][b] = is_query_selected[b][a] = true; }\n    }\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < G[k]; i++) cout << groups[k][i] << (i == G[k] - 1 ? \"\" : \" \"); cout << endl;\n        if (G[k] > 1) {\n            vector<Edge> c_e;\n            for (int i = 0; i < G[k]; i++) for (int j = i + 1; j < G[k]; j++) {\n                int u = min(groups[k][i], groups[k][j]), v = max(groups[k][i], groups[k][j]);\n                long long wc = is_query_selected[u][v] ? 0 : (!is_query_tested[u][v] ? 20000 : 40000);\n                c_e.push_back({u, v, (wc + center_dist[u][v]) * 1000000LL + (long long)u * 1000LL + v});\n            }\n            sort(c_e.begin(), c_e.end()); DSU final_dsu(G[k]);\n            int ed_c = 0;\n            for (auto& e : c_e) if (final_dsu.unite(local_idx[e.u], local_idx[e.v])) {\n                cout << e.u << \" \" << e.v << endl; if (++ed_c == G[k] - 1) break;\n            }\n        }\n    }\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n// Skating rink constants\nconst int N = 20;\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dchar[] = {'U', 'D', 'L', 'R'};\nconst int INF = 1e9;\n\n// To store the parent information for path reconstruction\nstruct Parent {\n    int r, c;\n    char type, dir;\n};\n\n// State for Dijkstra's algorithm\nstruct Node {\n    int r, c, cost;\n    bool operator>(const Node& other) const { return cost > other.cost; }\n};\n\n// Finds the shortest path cost from (start_r, start_c) to all other squares\n// using Move, Slide, and existing blocks.\nvector<vector<int>> dijkstra_all(int start_r, int start_c, const vector<vector<bool>>& grid, vector<vector<Parent>>& parents) {\n    vector<vector<int>> dists(N, vector<int>(N, INF));\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n\n    dists[start_r][start_c] = 0;\n    pq.push({start_r, start_c, 0});\n\n    while (!pq.empty()) {\n        Node curr = pq.top(); pq.pop();\n        if (curr.cost > dists[curr.r][curr.c]) continue;\n\n        // Move to adjacent cell\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) {\n                // If the target square has a block, it costs 1 to Alter + 1 to Move\n                int cost = 1 + (grid[nr][nc] ? 1 : 0);\n                if (dists[nr][nc] > curr.cost + cost) {\n                    dists[nr][nc] = curr.cost + cost;\n                    parents[nr][nc] = {curr.r, curr.c, 'M', dchar[i]};\n                    pq.push({nr, nc, dists[nr][nc]});\n                }\n            }\n        }\n\n        // Slide until hitting a block or boundary\n        for (int i = 0; i < 4; i++) {\n            int sr = curr.r, sc = curr.c;\n            while (true) {\n                int nr = sr + dr[i], nc = sc + dc[i];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N || grid[nr][nc]) break;\n                sr = nr; sc = nc;\n            }\n            if (sr != curr.r || sc != curr.c) {\n                if (dists[sr][sc] > curr.cost + 1) {\n                    dists[sr][sc] = curr.cost + 1;\n                    parents[sr][sc] = {curr.r, curr.c, 'S', dchar[i]};\n                    pq.push({sr, sc, dists[sr][sc]});\n                }\n            }\n        }\n    }\n    return dists;\n}\n\n// Reconstructs and outputs the sequence of actions from a starting position to a target\nvoid reconstruct(int start_r, int start_c, int end_r, int end_c, const vector<vector<Parent>>& parents, vector<vector<bool>>& current_grid, int& curr_r, int& curr_c) {\n    if (start_r == end_r && start_c == end_c) return;\n    vector<pair<char, char>> path;\n    int cr = end_r, cc = end_c;\n    while (cr != start_r || cc != start_c) {\n        Parent p = parents[cr][cc];\n        path.push_back({p.type, p.dir});\n        cr = p.r; cc = p.c;\n    }\n    reverse(path.begin(), path.end());\n\n    for (auto& p : path) {\n        int dr_val = (p.second == 'U' ? -1 : p.second == 'D' ? 1 : 0);\n        int dc_val = (p.second == 'L' ? -1 : p.second == 'R' ? 1 : 0);\n        if (p.first == 'M') {\n            // Check if we need to remove a block before moving\n            if (current_grid[curr_r + dr_val][curr_c + dc_val]) {\n                cout << \"A \" << p.second << \"\\n\";\n                current_grid[curr_r + dr_val][curr_c + dc_val] = false;\n            }\n            cout << \"M \" << p.second << \"\\n\";\n            curr_r += dr_val; curr_c += dc_val;\n        } else {\n            cout << \"S \" << p.second << \"\\n\";\n            // Update the current position after sliding\n            while (true) {\n                int nr = curr_r + dr_val, nc = curr_c + dc_val;\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N || current_grid[nr][nc]) break;\n                curr_r = nr; curr_c = nc;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    vector<pair<int, int>> targets(m_in);\n    for (int i = 0; i < m_in; i++) cin >> targets[i].first >> targets[i].second;\n\n    vector<vector<bool>> current_grid(N, vector<bool>(N, false));\n    int curr_r = targets[0].first, curr_c = targets[0].second;\n\n    // Iterate through each target square sequentially\n    for (int k = 1; k < m_in; k++) {\n        int tr = targets[k].first, tc = targets[k].second;\n\n        // Baseline: find path without flipping any extra blocks\n        vector<vector<Parent>> parents0(N, vector<Parent>(N));\n        vector<vector<int>> dists0 = dijkstra_all(curr_r, curr_c, current_grid, parents0);\n        int best_cost = dists0[tr][tc];\n        int best_br = -1, best_bc = -1, best_ar = -1, best_ac = -1;\n        char best_adir = ' ';\n\n        // Optimization: try flipping exactly one block anywhere on the grid\n        for (int br = 0; br < N; br++) {\n            for (int bc = 0; bc < N; bc++) {\n                if (br == tr && bc == tc) continue; // cannot block the target cell itself\n                current_grid[br][bc] = !current_grid[br][bc];\n                vector<vector<Parent>> dummy_parents(N, vector<Parent>(N));\n                vector<vector<int>> dists_from_target = dijkstra_all(tr, tc, current_grid, dummy_parents);\n                \n                // For each adjacent cell to the block being flipped\n                for (int d = 0; d < 4; d++) {\n                    int ar = br + dr[d], ac = bc + dc[d];\n                    if (ar >= 0 && ar < N && ac >= 0 && ac < N) {\n                        if (dists0[ar][ac] != INF && dists_from_target[ar][ac] != INF) {\n                            // Total cost: reach the adjacent cell + flip block + reach target with flipped block\n                            int cost = dists0[ar][ac] + 1 + dists_from_target[ar][ac];\n                            if (cost < best_cost) {\n                                best_cost = cost;\n                                best_br = br; best_bc = bc;\n                                best_ar = ar; best_ac = ac;\n                                best_adir = dchar[d ^ 1]; // direction to flip from adjacent cell\n                            }\n                        }\n                    }\n                }\n                current_grid[br][bc] = !current_grid[br][bc]; // flip back for next search\n            }\n        }\n\n        // Finalize movements to target\n        if (best_br == -1) {\n            reconstruct(curr_r, curr_c, tr, tc, parents0, current_grid, curr_r, curr_c);\n        } else {\n            // First leg: move to the square adjacent to the block to be flipped\n            reconstruct(curr_r, curr_c, best_ar, best_ac, parents0, current_grid, curr_r, curr_c);\n            // Flip the block\n            cout << \"A \" << best_adir << \"\\n\";\n            current_grid[best_br][best_bc] = !current_grid[best_br][best_bc];\n            // Second leg: move to target using the modified grid configuration\n            vector<vector<Parent>> parents2(N, vector<Parent>(N));\n            dijkstra_all(best_ar, best_ac, current_grid, parents2);\n            reconstruct(best_ar, best_ac, tr, tc, parents2, current_grid, curr_r, curr_c);\n        }\n    }\n\n    return 0;\n}\n"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <numeric>\n\nusing namespace std;\n\n// Structure for axis-parallel rectangles\nstruct Rect {\n    int a, b, c, d; // (a, b) is bottom-left, (c, d) is top-right\n};\n\n// Structure for company data\nstruct Company {\n    int x, y, r;\n    Rect rect;\n    double p;\n};\n\n// Calculate satisfaction p_i\ninline double get_p(int a, int b, int c, int d, int r) {\n    long long s = (long long)(c - a) * (d - b);\n    if (s <= 0) return 0.0;\n    double ratio = (s < (long long)r) ? (double)s / r : (double)r / s;\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Check if two rectangles overlap with positive area\ninline bool overlaps(const Rect& r1, const Rect& r2) {\n    return max(r1.a, r2.a) < min(r1.c, r2.c) &&\n           max(r1.b, r2.b) < min(r1.d, r2.d);\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<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        // Start with 1x1 rectangles containing the required points\n        companies[i].rect = {companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1};\n        companies[i].p = get_p(companies[i].rect.a, companies[i].rect.b, companies[i].rect.c, companies[i].rect.d, companies[i].r);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    // Phase 1: Initial Greedy Expansion (fast way to get a solid starting layout)\n    for (int iter = 0; iter < 150; ++iter) {\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3}; // 0:L, 1:B, 2:R, 3:T\n            shuffle(dirs, dirs + 4, rng);\n            for (int dir : dirs) {\n                Rect next = companies[i].rect;\n                if (dir == 0 && next.a > 0) next.a--;\n                else if (dir == 1 && next.b > 0) next.b--;\n                else if (dir == 2 && next.c < 10000) next.c++;\n                else if (dir == 3 && next.d < 10000) next.d++;\n                else continue;\n\n                // Ensure target point stays inside\n                if (next.a > companies[i].x || next.c <= companies[i].x ||\n                    next.b > companies[i].y || next.d <= companies[i].y) continue;\n\n                bool ok = true;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next, companies[j].rect)) { ok = false; break; }\n                }\n                if (ok) {\n                    companies[i].rect = next;\n                    companies[i].p = get_p(next.a, next.b, next.c, next.d, companies[i].r);\n                }\n            }\n        }\n    }\n\n    // Phase 2: Simulated Annealing with \"Push\" Moves\n    double current_total_p = 0;\n    for (int i = 0; i < n; ++i) current_total_p += companies[i].p;\n\n    double T_start = 0.01; // Initial temperature\n    double T_end = 0.0001;  // Final temperature\n    const double TIME_LIMIT = 4.8;\n\n    long long iter = 0;\n    vector<pair<int, Rect>> changes;\n    changes.reserve(n);\n\n    while (true) {\n        if ((iter & 1023) == 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            double progress = elapsed / TIME_LIMIT;\n            double T = T_start + (T_end - T_start) * progress; // Linear cooling\n\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            int side = uniform_int_distribution<int>(0, 3)(rng);\n            \n            int old_val;\n            if (side == 0) old_val = companies[i].rect.a;\n            else if (side == 1) old_val = companies[i].rect.b;\n            else if (side == 2) old_val = companies[i].rect.c;\n            else old_val = companies[i].rect.d;\n\n            int new_val;\n            int r_move = uniform_int_distribution<int>(0, 99)(rng);\n            if (r_move < 70) new_val = old_val + uniform_int_distribution<int>(-100, 100)(rng);\n            else if (r_move < 90) new_val = old_val + uniform_int_distribution<int>(-500, 500)(rng);\n            else if (r_move < 95) { // Try to reach target area\n                int current_w = companies[i].rect.c - companies[i].rect.a;\n                int current_h = companies[i].rect.d - companies[i].rect.b;\n                if (side == 0) new_val = companies[i].rect.c - (companies[i].r / max(1, current_h));\n                else if (side == 1) new_val = companies[i].rect.d - (companies[i].r / max(1, current_w));\n                else if (side == 2) new_val = companies[i].rect.a + (companies[i].r / max(1, current_h));\n                else new_val = companies[i].rect.b + (companies[i].r / max(1, current_w));\n            } else new_val = uniform_int_distribution<int>(0, 10000)(rng);\n\n            new_val = max(0, min(10000, new_val));\n            if (new_val == old_val) { iter++; continue; }\n\n            Rect next_i = companies[i].rect;\n            if (side == 0) next_i.a = new_val;\n            else if (side == 1) next_i.b = new_val;\n            else if (side == 2) next_i.c = new_val;\n            else next_i.d = new_val;\n\n            bool can_move = true;\n            // Validate basic rectangle properties and point inclusion\n            if (next_i.a >= next_i.c || next_i.b >= next_i.d ||\n                !(next_i.a <= companies[i].x && companies[i].x < next_i.c) ||\n                !(next_i.b <= companies[i].y && companies[i].y < next_i.d)) {\n                can_move = false;\n            }\n\n            changes.clear();\n            if (can_move) {\n                changes.push_back({i, next_i});\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next_i, companies[j].rect)) {\n                        Rect next_j = companies[j].rect;\n                        // Resolve overlap by shrinking j\n                        if (side == 0) next_j.c = next_i.a;\n                        else if (side == 1) next_j.d = next_i.b;\n                        else if (side == 2) next_j.a = next_i.c;\n                        else next_j.b = next_i.d;\n\n                        if (next_j.a >= next_j.c || next_j.b >= next_j.d ||\n                            !(next_j.a <= companies[j].x && companies[j].x < next_j.c) ||\n                            !(next_j.b <= companies[j].y && companies[j].y < next_j.d)) {\n                            can_move = false;\n                            break;\n                        }\n                        changes.push_back({j, next_j});\n                    }\n                }\n            }\n\n            if (can_move) {\n                double new_p_sum = current_total_p;\n                for (auto& ch : changes) {\n                    new_p_sum -= companies[ch.first].p;\n                    new_p_sum += get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                }\n\n                double delta = new_p_sum - current_total_p;\n                if (delta >= 0 || uniform_real_distribution<double>(0, 1)(rng) < exp(delta / T)) {\n                    current_total_p = new_p_sum;\n                    for (auto& ch : changes) {\n                        companies[ch.first].rect = ch.second;\n                        companies[ch.first].p = get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                    }\n                }\n            }\n        }\n        iter++;\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << companies[i].rect.a << \" \" << companies[i].rect.b << \" \"\n             << companies[i].rect.c << \" \" << companies[i].rect.d << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <bitset>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to find a path on a 50x50 grid with tile constraints.\n * - Each square belongs to a tile (1x1, 1x2, or 2x1).\n * - Each tile can be visited at most once.\n * - The goal is to maximize the sum of values p[i][j] of visited squares.\n * \n * Algorithm Improvement:\n * - Use Beam Search with a larger beam width (K=10000).\n * - Diversity constraint: keep at most B=10 paths per square at each step.\n * - Optimize bitset operations and state memory management.\n * - Use a history pointer system to reconstruct the path after the search.\n */\n\n// Grid and maximum tile constants\nconst int GRID_SIZE = 50;\nconst int MAX_TILES = 2500;\n\n// PathNode for reconstructing the final path from the search history\nstruct PathNode {\n    int parent_idx;\n    short r, c;\n    char move;\n};\n\n// State representing a partial path in the beam search\nstruct State {\n    int score;\n    int history_idx;\n    short r, c;\n    bitset<MAX_TILES> visited;\n};\n\n// Candidate for the next step of the path\nstruct Candidate {\n    int score;\n    int parent_beam_idx;\n    short ni, nj;\n    char move;\n\n    // Comparator for sorting candidates by total score in descending order.\n    // Ties are broken using coordinate values to ensure deterministic results.\n    bool operator>(const Candidate& other) const {\n        if (score != other.score) return score > other.score;\n        if (ni != other.ni) return ni > other.ni;\n        return nj > other.nj;\n    }\n};\n\nint main() {\n    // Fast I/O for better performance\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    // Read initial position\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    // Read tile configurations\n    int t[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> t[i][j];\n\n    // Read square scores\n    int p[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> p[i][j];\n\n    // Beam search configuration\n    const int K = 10000; // Maximum number of states to maintain in the beam\n    const int B = 10;    // Diversity: max number of paths allowed to end at the same grid square\n\n    // Store the history of path expansions to reconstruct the final path\n    // Using a flat vector for history to optimize memory allocation and access speed\n    vector<PathNode> history;\n    history.reserve(15000000);\n\n    // Current beam of states representing paths of the current length\n    vector<State> current_beam;\n    current_beam.reserve(K);\n\n    // Initial state: Takahashi starts at (si, sj)\n    bitset<MAX_TILES> initial_visited;\n    initial_visited.set(t[si][sj]);\n    current_beam.push_back({p[si][sj], 0, (short)si, (short)sj, initial_visited});\n    history.push_back({-1, (short)si, (short)sj, ' '});\n\n    int best_score = p[si][sj];\n    int best_history_idx = 0;\n\n    // Movement directions\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    // Candidate list for the next beam expansion\n    vector<Candidate> candidates;\n    candidates.reserve(K * 4);\n\n    // Array to track diversity per cell\n    int counts[GRID_SIZE * GRID_SIZE];\n\n    // Main Beam Search loop\n    while (true) {\n        // Exit search if time limit (2s) is nearing (leaving some margin)\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        candidates.clear();\n        // For each state in the current beam, explore all 4 adjacent moves\n        for (int i = 0; i < (int)current_beam.size(); ++i) {\n            const auto& s = current_beam[i];\n            for (int d = 0; d < 4; ++d) {\n                int ni = s.r + dr[d];\n                int nj = s.c + dc[d];\n                // Check grid boundaries\n                if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE) {\n                    // Check if the tile at the destination has already been visited\n                    if (!s.visited.test(t[ni][nj])) {\n                        candidates.push_back({s.score + p[ni][nj], i, (short)ni, (short)nj, move_chars[d]});\n                    }\n                }\n            }\n        }\n\n        // If no more valid expansions are found, stop the search\n        if (candidates.empty()) break;\n\n        // Sort all possible next moves by score to select the best states for the next beam\n        sort(candidates.begin(), candidates.end(), greater<Candidate>());\n\n        vector<State> next_beam;\n        next_beam.reserve(K);\n        memset(counts, 0, sizeof(counts));\n\n        // Fill the next beam with the top K candidates, respecting the diversity constraint B\n        for (const auto& cand : candidates) {\n            int pos = cand.ni * GRID_SIZE + cand.nj;\n            if (counts[pos] < B) {\n                if (next_beam.size() >= K) break;\n\n                State next_s;\n                next_s.score = cand.score;\n                next_s.r = cand.ni;\n                next_s.c = cand.nj;\n                // Inherit visited bitset from parent and mark the new tile\n                next_s.visited = current_beam[cand.parent_beam_idx].visited;\n                next_s.visited.set(t[cand.ni][cand.nj]);\n                next_s.history_idx = (int)history.size();\n                \n                // Track expansion history\n                history.push_back({current_beam[cand.parent_beam_idx].history_idx, cand.ni, cand.nj, cand.move});\n                \n                // Update overall best path found\n                if (next_s.score > best_score) {\n                    best_score = next_s.score;\n                    best_history_idx = next_s.history_idx;\n                }\n\n                next_beam.push_back(std::move(next_s));\n                counts[pos]++;\n            }\n        }\n\n        // Move to the next step\n        if (next_beam.empty()) break;\n        current_beam = std::move(next_beam);\n    }\n\n    // Trace back through history to reconstruct the sequence of moves for the best path\n    string result_path = \"\";\n    int curr_node_idx = best_history_idx;\n    while (history[curr_node_idx].parent_idx != -1) {\n        result_path += history[curr_node_idx].move;\n        curr_node_idx = history[curr_node_idx].parent_idx;\n    }\n    // Reverse moves as we traced from finish to start\n    reverse(result_path.begin(), result_path.end());\n    \n    // Output the resulting path string\n    cout << result_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 * Strategy Summary:\n * 1. Road Network: 30x30 undirected grid graph with unknown edge lengths.\n * 2. Edge structure: Either M=1 (constant base length per row/column) or M=2 (two base lengths).\n * 3. Learning: Use feedback from noisy measurements (~10% error) to estimate edge lengths.\n * 4. Algorithm: Dijkstra's for shortest path queries, updated with kernel-smoothing to exploit \n *    the grid's structure.\n * 5. Weights: Exponentially weight later queries more (0.998^(1000-k)).\n */\n\n// Grid dimensions\nconst int N = 30;\n// Known possible range for edge lengths\nconst double MIN_WEIGHT = 1000.0;\nconst double MAX_WEIGHT = 9000.0;\nconst double INIT_WEIGHT = 5000.0;\n\n// Struct to track edges used in a path for subsequent weight updates\nstruct EdgeInfo {\n    int type; // 0 for horizontal (h_weights), 1 for vertical (v_weights)\n    int i, j;\n};\n\n// Global weight estimates and visit statistics\ndouble h_weights[N][N - 1];\ndouble v_weights[N - 1][N];\nint h_counts[N][N - 1];\nint v_counts[N - 1][N];\ndouble gamma_pow[N + 1];\n\n/**\n * Initializes the grid with expected average weights and precomputes \n * kernel smoothing factors.\n */\nvoid init() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            h_weights[i][j] = INIT_WEIGHT;\n            h_counts[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = INIT_WEIGHT;\n            v_counts[i][j] = 0;\n        }\n    }\n    // gamma determines the spatial influence of a weight update along a row or column.\n    double gamma = 0.94;\n    gamma_pow[0] = 1.0;\n    for (int i = 1; i <= N; ++i) {\n        gamma_pow[i] = gamma_pow[i - 1] * gamma;\n    }\n}\n\n/**\n * Adjusts the estimated weight for the shortest path search.\n * Early on (first 200 queries), we reduce weights of less-visited edges to encourage exploration.\n */\ndouble get_dijkstra_weight(int type, int i, int j, int k) {\n    double w = (type == 0) ? h_weights[i][j] : v_weights[i][j];\n    if (k < 200) {\n        int count = (type == 0) ? h_counts[i][j] : v_counts[i][j];\n        double bias = 0.20 * (1.0 - (double)k / 200.0) / (1.0 + (double)count);\n        return w * (1.0 - bias);\n    }\n    return w;\n}\n\n/**\n * Uses Dijkstra's algorithm to find the best path based on current knowledge.\n */\nstring find_path(int si, int sj, int ti, int tj, int k, vector<EdgeInfo>& path_edges) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<pair<int, int>, char>>> parent(N, vector<pair<pair<int, int>, char>>(N, {{-1, -1}, ' '}));\n    using P = pair<double, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int i = pq.top().second.first;\n        int j = pq.top().second.second;\n        pq.pop();\n\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        // Neighbor check: Up, Down, Left, Right\n        // Vertical edges connect (i, j) and (i+1, j)\n        // Horizontal edges connect (i, j) and (i, j+1)\n        if (i > 0) { // Up\n            double w = get_dijkstra_weight(1, i - 1, j, k);\n            if (dist[i - 1][j] > d + w) {\n                dist[i - 1][j] = d + w;\n                parent[i - 1][j] = {{i, j}, 'U'};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (i < N - 1) { // Down\n            double w = get_dijkstra_weight(1, i, j, k);\n            if (dist[i + 1][j] > d + w) {\n                dist[i + 1][j] = d + w;\n                parent[i + 1][j] = {{i, j}, 'D'};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (j > 0) { // Left\n            double w = get_dijkstra_weight(0, i, j - 1, k);\n            if (dist[i][j - 1] > d + w) {\n                dist[i][j - 1] = d + w;\n                parent[i][j - 1] = {{i, j}, 'L'};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        if (j < N - 1) { // Right\n            double w = get_dijkstra_weight(0, i, j, k);\n            if (dist[i][j + 1] > d + w) {\n                dist[i][j + 1] = d + w;\n                parent[i][j + 1] = {{i, j}, 'R'};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    // Reconstruction of the optimal path found.\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char dir = parent[ci][cj].second;\n        path += dir;\n        int pi = parent[ci][cj].first.first;\n        int pj = parent[ci][cj].first.second;\n        if (dir == 'U') {\n            path_edges.push_back({1, ci, cj});\n            v_counts[ci][cj]++;\n        } else if (dir == 'D') {\n            path_edges.push_back({1, pi, pj});\n            v_counts[pi][pj]++;\n        } else if (dir == 'L') {\n            path_edges.push_back({0, ci, cj});\n            h_counts[ci][cj]++;\n        } else if (dir == 'R') {\n            path_edges.push_back({0, pi, pj});\n            h_counts[pi][pj]++;\n        }\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/**\n * Updates estimated edge weights by comparing predicted path length with judge feedback.\n * Kernel smoothing distributes the error correction along rows/columns.\n */\nvoid update_weights(const vector<EdgeInfo>& path_edges, int result, int k) {\n    double predicted = 0;\n    for (const auto& e : path_edges) {\n        predicted += (e.type == 0) ? h_weights[e.i][e.j] : v_weights[e.i][e.j];\n    }\n\n    double error = (double)result - predicted;\n    // Decaying learning rate for long-term stability.\n    double lr = 0.48 * pow(0.9995, (double)k);\n\n    vector<vector<double>> coeff_h(N, vector<double>(N - 1, 0.0));\n    vector<vector<double>> coeff_v(N - 1, vector<double>(N, 0.0));\n\n    // Calculate update coefficients based on proximity to used edges in the grid.\n    for (const auto& e : path_edges) {\n        if (e.type == 0) {\n            for (int jp = 0; jp < N - 1; ++jp) coeff_h[e.i][jp] += gamma_pow[abs(e.j - jp)];\n        } else {\n            for (int ip = 0; ip < N - 1; ++ip) coeff_v[ip][e.j] += gamma_pow[abs(e.i - ip)];\n        }\n    }\n\n    // Normalize the step size based on total contribution to the measured path.\n    double total_coeff = 0;\n    for (const auto& e : path_edges) {\n        total_coeff += (e.type == 0) ? coeff_h[e.i][e.j] : coeff_v[e.i][e.j];\n    }\n\n    if (total_coeff > 0) {\n        double step = (error * lr) / total_coeff;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                if (coeff_h[i][j] > 0) {\n                    h_weights[i][j] += step * coeff_h[i][j];\n                    h_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, h_weights[i][j]));\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (coeff_v[i][j] > 0) {\n                    v_weights[i][j] += step * coeff_v[i][j];\n                    v_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, v_weights[i][j]));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    init();\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        vector<EdgeInfo> path_edges;\n        string path = find_path(si, sj, ti, tj, k, path_edges);\n        cout << path << endl; // Endl flushes the output.\n\n        int result;\n        if (!(cin >> result)) break;\n        update_weights(path_edges, result, k);\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <cmath>\n#include <cstring>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Fast xorshift random number generator for better performance in Simulated Annealing\nuint32_t xorshift() {\n    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t t = x ^ (x << 11);\n    x = y; y = z; z = w;\n    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n}\n\nconst int N = 20;\nint M;\nint A[N][N];\nint best_A[N][N];\nint current_c = 0;\nint current_d = 0;\nint count_in_matrix[1000]; // Max number of unique strings (k_unique <= M)\nint weights[1000];\nbool length_exists[13];\n\n// Simple and fast Hash Table for storing packed strings\nstruct HashTable {\n    static const int SIZE = 1 << 15;\n    long long keys[SIZE];\n    int values[SIZE];\n    HashTable() { memset(keys, -1, sizeof(keys)); }\n    inline void insert(long long key, int val) {\n        uint32_t h = ((uint64_t)key * 11400714819323198485ULL) >> (64 - 15);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return;\n            h = (h + 1) & (SIZE - 1);\n        }\n        keys[h] = key;\n        values[h] = val;\n    }\n    inline int query(long long key) {\n        uint32_t h = ((uint64_t)key * 11400714819323198485ULL) >> (64 - 15);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return values[h];\n            h = (h + 1) & (SIZE - 1);\n        }\n        return -1;\n    }\n} id_map;\n\n// Pack a string into a 64-bit integer\ninline long long pack_str(uint64_t val, int len) {\n    return (long long)((val << 4) | (uint64_t)len);\n}\n\n// Update the coverage stats when cell A[r][c] changes\nvoid modify_stats(int r, int c, int delta) {\n    // Horizontal substrings of length 1 to 12 containing cell (r, c)\n    for (int k = 0; k < 12; k++) {\n        int sc = (c - k + N) % N;\n        uint64_t val = 0;\n        for (int len = 1; len <= 12; len++) {\n            int j = sc + len - 1; if (j >= N) j -= N;\n            int v = A[r][j];\n            if (v == 0) break;\n            val = (val << 3) | (v - 1);\n            if (len > k && length_exists[len]) {\n                int id = id_map.query(pack_str(val, len));\n                if (id != -1) {\n                    if (delta == 1) {\n                        if (count_in_matrix[id]++ == 0) current_c += weights[id];\n                    } else {\n                        if (--count_in_matrix[id] == 0) current_c -= weights[id];\n                    }\n                }\n            }\n        }\n    }\n    // Vertical substrings of length 1 to 12 containing cell (r, c)\n    for (int k = 0; k < 12; k++) {\n        int sr = (r - k + N) % N;\n        uint64_t val = 0;\n        for (int len = 1; len <= 12; len++) {\n            int i = sr + len - 1; if (i >= N) i -= N;\n            int v = A[i][c];\n            if (v == 0) break;\n            val = (val << 3) | (v - 1);\n            if (len > k && length_exists[len]) {\n                int id = id_map.query(pack_str(val, len));\n                if (id != -1) {\n                    if (delta == 1) {\n                        if (count_in_matrix[id]++ == 0) current_c += weights[id];\n                    } else {\n                        if (--count_in_matrix[id] == 0) current_c -= weights[id];\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Scoring function for Simulated Annealing\ninline double get_sa_score(int c, int d) {\n    if (c < M) return (double)c;\n    return (double)M * 800.0 / (800.0 - d);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n_input; if (!(cin >> n_input >> M)) return 0;\n    vector<string> s_list(M);\n    map<string, int> string_counts;\n    memset(length_exists, false, sizeof(length_exists));\n    for (int i = 0; i < M; i++) {\n        cin >> s_list[i];\n        string_counts[s_list[i]]++;\n        length_exists[s_list[i].length()] = true;\n    }\n    int k_unique = 0;\n    for (auto const& [str, weight] : string_counts) {\n        weights[k_unique] = weight;\n        uint64_t val = 0;\n        for (char ch : str) val = (val << 3) | (ch - 'A');\n        id_map.insert(pack_str(val, str.length()), k_unique);\n        k_unique++;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) A[i][j] = 0;\n    \n    vector<string> sorted_s = s_list;\n    sort(sorted_s.begin(), sorted_s.end(), [](const string& a, const string& b) {\n        return a.length() > b.length();\n    });\n\n    // Greedy initialization to satisfy as many strings as possible\n    for (const string& str : sorted_s) {\n        int best_r = -1, best_c = -1, best_dir = -1;\n        long long best_val = -2e18;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int dir = 0; dir < 2; dir++) {\n                    long long score = 0;\n                    for (int k = 0; k < (int)str.length(); k++) {\n                        int rr = (dir == 0 ? r : (r + k) % N), cc = (dir == 0 ? (c + k) % N : c);\n                        if (A[rr][cc] == 0) score += 1;\n                        else if (A[rr][cc] == str[k] - 'A' + 1) score += 10;\n                        else { score = -1e15; break; }\n                    }\n                    if (score > best_val) { best_val = score; best_r = r; best_c = c; best_dir = dir; }\n                }\n            }\n        }\n        if (best_val > -1e14) {\n            for (int k = 0; k < (int)str.length(); k++) {\n                int rr = (best_dir == 0 ? best_r : (best_r + k) % N), cc = (best_dir == 0 ? (best_c + k) % N : best_c);\n                A[rr][cc] = str[k] - 'A' + 1;\n            }\n        }\n    }\n    // Fill remaining empty cells with random characters\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (A[i][j] == 0) A[i][j] = (xorshift() % 8) + 1;\n\n    // Initial evaluation\n    memset(count_in_matrix, 0, sizeof(count_in_matrix));\n    current_c = 0; current_d = 0;\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (A[r][c] == 0) current_d++;\n            for (int L = 2; L <= 12; L++) {\n                if (!length_exists[L]) continue;\n                uint64_t v_h = 0; bool ok_h = true;\n                for (int i = 0; i < L; i++) {\n                    int v = A[r][(c + i) % N]; if (v == 0) { ok_h = false; break; }\n                    v_h = (v_h << 3) | (v - 1);\n                }\n                if (ok_h) {\n                    int id = id_map.query(pack_str(v_h, L));\n                    if (id != -1) { if (count_in_matrix[id]++ == 0) current_c += weights[id]; }\n                }\n                uint64_t v_v = 0; bool ok_v = true;\n                for (int i = 0; i < L; i++) {\n                    int v = A[(r + i) % N][c]; if (v == 0) { ok_v = false; break; }\n                    v_v = (v_v << 3) | (v - 1);\n                }\n                if (ok_v) {\n                    int id = id_map.query(pack_str(v_v, L));\n                    if (id != -1) { if (count_in_matrix[id]++ == 0) current_c += weights[id]; }\n                }\n            }\n        }\n    }\n\n    double old_s = get_sa_score(current_c, current_d);\n    double best_s = old_s;\n    memcpy(best_A, A, sizeof(A));\n\n    // Simulated Annealing\n    double T_start = 1.0, T_end = 0.01;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.9) break;\n        double T = T_start * pow(T_end / T_start, elapsed / 2.9);\n\n        for (int sub = 0; sub < 50; sub++) {\n            int r = xorshift() % N, c = xorshift() % N;\n            int old_v = A[r][c], new_v;\n            // Adaptive sampling: when unsatisfied strings exist, favor letters. Otherwise, favor dots.\n            if (current_c < M) {\n                if (xorshift() % 100 < 95) new_v = (xorshift() % 8) + 1;\n                else new_v = 0;\n            } else {\n                if (xorshift() % 100 < 10) new_v = (xorshift() % 8) + 1;\n                else new_v = 0;\n            }\n            if (new_v == old_v) continue;\n\n            int pre_c = current_c, pre_d = current_d;\n            modify_stats(r, c, -1);\n            A[r][c] = new_v;\n            modify_stats(r, c, 1);\n            current_d += (new_v == 0) - (old_v == 0);\n\n            double cur_s = get_sa_score(current_c, current_d);\n            if (cur_s >= old_s || exp((cur_s - old_s) / T) > (double)xorshift() / 4294967295.0) {\n                old_s = cur_s;\n                if (cur_s > best_s) { best_s = cur_s; memcpy(best_A, A, sizeof(A)); }\n            } else {\n                // Revert step\n                modify_stats(r, c, -1);\n                A[r][c] = old_v;\n                modify_stats(r, c, 1);\n                current_c = pre_c; current_d = pre_d;\n            }\n        }\n    }\n\n    // Output final results\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) cout << (best_A[i][j] == 0 ? '.' : (char)('A' + best_A[i][j] - 1));\n        cout << \"\\n\";\n    }\n    return 0;\n}\n","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Maximum number of road squares in N x N grid (70x70)\nconst int INF = 1e9;\nconst int MAXR = 5000;\nint N, SI, SJ;\nvector<string> grid;\nstruct Road { int r, c, cost; };\nvector<Road> roads;\nint road_idx_map[70][70];\nvector<pair<int, int>> adj[MAXR];\nint dists[MAXR][MAXR];\nshort parents[MAXR][MAXR];\n\n// Dial's algorithm for finding shortest paths in a graph with small integer edge weights (5-9)\nvoid dial(int start, int* d, short* p, int R) {\n    for (int i = 0; i < R; ++i) d[i] = INF;\n    d[start] = 0;\n    p[start] = -1;\n    static vector<int> buckets[10]; // Edge weights 5-9, so 10 buckets are sufficient\n    for (int i = 0; i < 10; ++i) buckets[i].clear();\n    buckets[0].push_back(start);\n    int cur_dist = 0, num_visited = 0;\n    while (num_visited < R) {\n        int b_idx = cur_dist % 10;\n        while (!buckets[b_idx].empty()) {\n            int u = buckets[b_idx].back();\n            buckets[b_idx].pop_back();\n            if (d[u] < cur_dist) continue;\n            num_visited++;\n            for (auto& edge : adj[u]) {\n                int v = edge.first, w = edge.second;\n                if (d[v] > cur_dist + w) {\n                    d[v] = cur_dist + w;\n                    p[v] = (short)u;\n                    buckets[d[v] % 10].push_back(v);\n                }\n            }\n        }\n        cur_dist++;\n        if (cur_dist > 100000) break; // Safety break for disconnected components\n    }\n}\n\n// Bipartite matching helper\nbool match_dfs(int u, const vector<vector<int>>& b_adj, vector<int>& match_v, vector<bool>& vis) {\n    for (int v : b_adj[u]) {\n        if (vis[v]) continue;\n        vis[v] = true;\n        if (match_v[v] == -1 || match_dfs(match_v[v], b_adj, match_v, vis)) {\n            match_v[v] = u;\n            return true;\n        }\n    }\n    return false;\n}\n\n// Struct representing a task square in the tour\nstruct VisitTask {\n    int current_sq;\n    int h_seg; // index of horizontal segment covered (-1 if none)\n    int v_seg; // index of vertical segment covered (-1 if none)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> SI >> SJ)) return 0;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // Grid road indexing\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_idx_map[i][j] = (int)roads.size();\n                roads.push_back({i, j, grid[i][j] - '0'});\n            } else road_idx_map[i][j] = -1;\n        }\n    }\n    int R = (int)roads.size();\n    for (int i = 0; i < R; ++i) {\n        int r = roads[i].r, c = roads[i].c;\n        int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != '#') {\n                adj[i].push_back({road_idx_map[nr][nc], grid[nr][nc] - '0'});\n            }\n        }\n    }\n\n    // Precompute all-pairs shortest paths\n    for (int i = 0; i < R; ++i) dial(i, dists[i], parents[i], R);\n\n    // Identify maximal segments\n    vector<vector<int>> h_segs, v_segs;\n    vector<int> h_seg_of(R), v_seg_of(R);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                if (j == 0 || grid[i][j - 1] == '#') {\n                    int sid = (int)h_segs.size(); h_segs.push_back({});\n                    for (int k = j; k < N && grid[i][k] != '#'; ++k) {\n                        h_segs[sid].push_back(road_idx_map[i][k]);\n                        h_seg_of[road_idx_map[i][k]] = sid;\n                    }\n                }\n                if (i == 0 || grid[i - 1][j] == '#') {\n                    int sid = (int)v_segs.size(); v_segs.push_back({});\n                    for (int k = i; k < N && grid[k][j] != '#'; ++k) {\n                        v_segs[sid].push_back(road_idx_map[k][j]);\n                        v_seg_of[road_idx_map[k][j]] = sid;\n                    }\n                }\n            }\n        }\n    }\n\n    // Find Minimum Vertex Cover to select essential segments\n    int n_h = (int)h_segs.size(), n_v = (int)v_segs.size();\n    vector<vector<int>> b1_adj(n_h);\n    for (int i = 0; i < R; ++i) b1_adj[h_seg_of[i]].push_back(v_seg_of[i]);\n    for (int i = 0; i < n_h; ++i) {\n        sort(b1_adj[i].begin(), b1_adj[i].end());\n        b1_adj[i].erase(unique(b1_adj[i].begin(), b1_adj[i].end()), b1_adj[i].end());\n    }\n    vector<int> match1_v(n_v, -1), match1_h(n_h, -1);\n    for (int i = 0; i < n_h; ++i) { vector<bool> vis(n_v, false); match_dfs(i, b1_adj, match1_v, vis); }\n    for (int i = 0; i < n_v; ++i) if (match1_v[i] != -1) match1_h[match1_v[i]] = i;\n\n    vector<bool> vis_l(n_h, false), vis_r(n_v, false);\n    vector<int> q_mvc;\n    for (int i = 0; i < n_h; ++i) if (match1_h[i] == -1) { vis_l[i] = true; q_mvc.push_back(i); }\n    int head = 0;\n    while (head < (int)q_mvc.size()) {\n        int u = q_mvc[head++];\n        for (int v : b1_adj[u]) if (!vis_r[v]) {\n            vis_r[v] = true;\n            int next_u = match1_v[v];\n            if (next_u != -1 && !vis_l[next_u]) { vis_l[next_u] = true; q_mvc.push_back(next_u); }\n        }\n    }\n    vector<int> MVC_H, MVC_V;\n    for (int i = 0; i < n_h; ++i) if (!vis_l[i]) MVC_H.push_back(i);\n    for (int i = 0; i < n_v; ++i) if (vis_r[i]) MVC_V.push_back(i);\n\n    int start_node = road_idx_map[SI][SJ];\n    int h_start = h_seg_of[start_node], v_start = v_seg_of[start_node];\n    vector<int> M_rem_H, M_rem_V;\n    for (int h : MVC_H) if (h != h_start) M_rem_H.push_back(h);\n    for (int v : MVC_V) if (v != v_start) M_rem_V.push_back(v);\n\n    // Initial square matching for segments\n    vector<vector<int>> b2_adj(n_h);\n    for (int h : M_rem_H) for (int v : M_rem_V)\n        for (int r_idx : h_segs[h]) if (v_seg_of[r_idx] == v) { b2_adj[h].push_back(v); break; }\n\n    vector<int> m2_v(n_v, -1), m2_h(n_h, -1);\n    for (int h : M_rem_H) { vector<bool> vis(n_v, false); match_dfs(h, b2_adj, m2_v, vis); }\n    for (int i = 0; i < n_v; ++i) if (m2_v[i] != -1) m2_h[m2_v[i]] = i;\n\n    vector<VisitTask> tour;\n    tour.push_back({start_node, -1, -1});\n    vector<bool> h_covered(n_h, false), v_covered(n_v, false);\n    h_covered[h_start] = v_covered[v_start] = true;\n    for (int h : M_rem_H) if (m2_h[h] != -1) {\n        int v = m2_h[h], sq = -1;\n        for (int r_idx : h_segs[h]) if (v_seg_of[r_idx] == v) { sq = r_idx; break; }\n        tour.push_back({sq, h, v}); h_covered[h] = v_covered[v] = true;\n    }\n    for (int h : M_rem_H) if (!h_covered[h]) tour.push_back({h_segs[h][0], h, -1});\n    for (int v : M_rem_V) if (!v_covered[v]) tour.push_back({v_segs[v][0], -1, v});\n\n    mt19937 rng(42);\n    auto start_time = chrono::high_resolution_clock::now();\n    double duration_limit = 2.85;\n\n    auto calculate_dist = [&](const vector<VisitTask>& t) {\n        int d = 0, K = (int)t.size();\n        for (int i = 0; i < K; ++i) d += dists[t[i].current_sq][t[(i + 1) % K].current_sq];\n        return d;\n    };\n\n    int current_dist = calculate_dist(tour);\n    int best_dist = current_dist;\n    vector<VisitTask> best_tour = tour;\n\n    int iter = 0;\n    while (true) {\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n            if (elapsed > duration_limit) break;\n        }\n        iter++;\n        double t_norm = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count() / duration_limit;\n        double temp = 50.0 * (1.0 - t_norm);\n        int K = (int)tour.size();\n        int move = uniform_int_distribution<>(0, 3)(rng);\n        if (move == 0 && K > 2) { // 2-opt\n            int i = uniform_int_distribution<>(1, K - 1)(rng), j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i >= j) continue;\n            int p = i - 1, n = (j + 1) % K;\n            int d_old = dists[tour[p].current_sq][tour[i].current_sq] + dists[tour[j].current_sq][tour[n].current_sq];\n            int d_new = dists[tour[p].current_sq][tour[j].current_sq] + dists[tour[i].current_sq][tour[n].current_sq];\n            if (d_new < d_old || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((double)(d_old - d_new) / temp))) {\n                reverse(tour.begin() + i, tour.begin() + j + 1); current_dist += (d_new - d_old);\n            }\n        } else if (move == 1 && K > 2) { // Relocation\n            int i = uniform_int_distribution<>(1, K - 1)(rng), j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i == j) continue;\n            vector<VisitTask> next_tour = tour; VisitTask task = next_tour[i];\n            next_tour.erase(next_tour.begin() + i); next_tour.insert(next_tour.begin() + j, task);\n            int next_dist = calculate_dist(next_tour);\n            if (next_dist < current_dist || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((double)(current_dist - next_dist) / temp))) {\n                tour = next_tour; current_dist = next_dist;\n            }\n        } else if (move == 2) { // Move within segment\n            int i = uniform_int_distribution<>(1, K - 1)(rng), next_sq = -1;\n            if (tour[i].h_seg != -1 && tour[i].v_seg == -1) next_sq = h_segs[tour[i].h_seg][uniform_int_distribution<>(0, (int)h_segs[tour[i].h_seg].size() - 1)(rng)];\n            else if (tour[i].v_seg != -1 && tour[i].h_seg == -1) next_sq = v_segs[tour[i].v_seg][uniform_int_distribution<>(0, (int)v_segs[tour[i].v_seg].size() - 1)(rng)];\n            else continue;\n            int p = (i - 1 + K) % K, n = (i + 1) % K;\n            int d_old = dists[tour[p].current_sq][tour[i].current_sq] + dists[tour[i].current_sq][tour[n].current_sq];\n            int d_new = dists[tour[p].current_sq][next_sq] + dists[next_sq][tour[n].current_sq];\n            if (d_new < d_old || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((double)(d_old - d_new) / temp))) {\n                tour[i].current_sq = next_sq; current_dist += (d_new - d_old);\n            }\n        } else { // Merge / Split\n            if (uniform_int_distribution<>(0, 1)(rng) == 0) {\n                int i = uniform_int_distribution<>(1, K - 1)(rng), j = uniform_int_distribution<>(1, K - 1)(rng);\n                if (i != j && tour[i].h_seg != -1 && tour[i].v_seg == -1 && tour[j].h_seg == -1 && tour[j].v_seg != -1) {\n                    int h = tour[i].h_seg, v = tour[j].v_seg, sq = -1;\n                    for (int r_idx : h_segs[h]) if (v_seg_of[r_idx] == v) { sq = r_idx; break; }\n                    if (sq != -1) {\n                        vector<VisitTask> next_tour = tour;\n                        if (i < j) { next_tour.erase(next_tour.begin() + j); next_tour[i] = {sq, h, v}; }\n                        else { next_tour.erase(next_tour.begin() + i); next_tour[j] = {sq, h, v}; }\n                        int next_dist = calculate_dist(next_tour);\n                        if (next_dist < current_dist || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((double)(current_dist - next_dist) / temp))) {\n                            tour = next_tour; current_dist = next_dist;\n                        }\n                    }\n                }\n            } else {\n                int i = uniform_int_distribution<>(1, K - 1)(rng);\n                if (tour[i].h_seg != -1 && tour[i].v_seg != -1) {\n                    vector<VisitTask> next_tour = tour; int h = tour[i].h_seg, v = tour[i].v_seg;\n                    next_tour[i] = {h_segs[h][0], h, -1}; next_tour.insert(next_tour.begin() + i + 1, {v_segs[v][0], -1, v});\n                    int next_dist = calculate_dist(next_tour);\n                    if (next_dist < current_dist || (temp > 0 && uniform_real_distribution<>(0, 1)(rng) < exp((double)(current_dist - next_dist) / temp))) {\n                        tour = next_tour; current_dist = next_dist;\n                    }\n                }\n            }\n        }\n        if (current_dist < best_dist) { best_dist = current_dist; best_tour = tour; }\n    }\n\n    string res = \"\"; int finalK = (int)best_tour.size();\n    for (int i = 0; i < finalK; ++i) {\n        int u = best_tour[i].current_sq, v = best_tour[(i + 1) % finalK].current_sq, pre = u;\n        vector<int> path; for (int cur = v; cur != u; cur = (int)parents[u][cur]) path.push_back(cur);\n        reverse(path.begin(), path.end());\n        for (int node : path) {\n            if (roads[node].r < roads[pre].r) res += 'U'; else if (roads[node].r > roads[pre].r) res += 'D';\n            else if (roads[node].c < roads[pre].c) res += 'L'; else res += 'R';\n            pre = node;\n        }\n    }\n    cout << res << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\n// Configuration based on problem statement\nconst int MAX_DAYS = 2000;\nconst int N_TASKS = 1000;\nconst int M_MEMBERS = 20;\n\nstruct History {\n    vector<int> d;\n    int t;\n};\n\nstruct Task {\n    int id;\n    vector<int> d;\n    vector<int> deps;\n    vector<int> rev_deps;\n    double height;\n    int descendants;\n    int status; // -1: not ready, 0: ready, 1: ongoing, 2: completed\n};\n\nstruct Member {\n    int id;\n    vector<double> s;\n    int current_task;\n    int start_day;\n    vector<History> history;\n};\n\nint N, M, K, R;\nvector<Task> tasks;\nvector<Member> members;\n\n// Calculate the difficulty term w_i,j = sum(max(0, d_i,k - s_j,k))\ndouble get_w(const vector<double>& s, const vector<int>& d) {\n    double w = 0;\n    for (int k = 0; k < K; ++k) {\n        if ((double)d[k] > s[k]) w += (double)d[k] - s[k];\n    }\n    return w;\n}\n\n// Calculate the expected number of days for completion based on w_i,j and the random integer r\ndouble expected_duration(double w) {\n    if (w <= 0.0) return 1.0;\n    double sum = 0;\n    for (int r = -3; r <= 3; ++r) {\n        sum += max(1.0, w + (double)r);\n    }\n    return sum / 7.0;\n}\n\n// Re-calculate task heights for critical path prioritization\nvoid calculate_heights() {\n    double avg_s_val = 32.0 / sqrt((double)K);\n    vector<double> avg_s(K, avg_s_val);\n    \n    vector<double> duration_ests(N);\n    for (int i = 0; i < N; ++i) {\n        duration_ests[i] = expected_duration(get_w(avg_s, tasks[i].d));\n    }\n\n    for (int i = 0; i < N; ++i) tasks[i].height = 0;\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; ++i) out_degree[i] = (int)tasks[i].rev_deps.size();\n    \n    vector<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (out_degree[i] == 0) {\n            q.push_back(i);\n            tasks[i].height = duration_ests[i];\n        }\n    }\n    \n    int head = 0;\n    while(head < (int)q.size()){\n        int v = q[head++];\n        for(int u : tasks[v].deps){\n            tasks[u].height = max(tasks[u].height, tasks[v].height + duration_ests[u]);\n            if(--out_degree[u] == 0) q.push_back(u);\n        }\n    }\n}\n\n// Calculate total task descendants for secondary prioritization\nvoid calculate_descendants() {\n    for (int i = 0; i < N; ++i) {\n        vector<bool> visited(N, false);\n        vector<int> q_d;\n        q_d.push_back(i);\n        visited[i] = true;\n        int count = 0;\n        int head = 0;\n        while(head < (int)q_d.size()){\n            int v = q_d[head++];\n            for(int next_v : tasks[v].rev_deps){\n                if(!visited[next_v]){\n                    visited[next_v] = true;\n                    q_d.push_back(next_v);\n                    count++;\n                }\n            }\n        }\n        tasks[i].descendants = count;\n    }\n}\n\n// Update skill estimates using gradient descent based on task completion history\nvoid update_skills(int m_idx) {\n    auto& m = members[m_idx];\n    if (m.history.empty()) return;\n    \n    for (int iter = 0; iter < 400; ++iter) {\n        double eta = 0.1 / (1.0 + iter * 0.01);\n        vector<double> grad(K, 0.0);\n        for (const auto& h : m.history) {\n            double w = get_w(m.s, h.d);\n            double target_w = (h.t == 1) ? 0.0 : (double)h.t;\n            double diff = w - target_w;\n            // For t=1, we only know w is small, so we don't penalize if w is already 0\n            if (h.t == 1 && diff < 0) diff = 0;\n            for (int k = 0; k < K; ++k) {\n                if ((double)h.d[k] > m.s[k]) grad[k] -= diff;\n            }\n        }\n        for (int k = 0; k < K; ++k) {\n            m.s[k] -= eta * grad[k] / (double)m.history.size();\n            m.s[k] = max(0.0, m.s[k]);\n        }\n        // Project onto norm constraints [20, 60]\n        double norm2 = 0;\n        for (int k = 0; k < K; ++k) norm2 += m.s[k] * m.s[k];\n        double norm = sqrt(norm2);\n        if (norm < 20.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 20.0 / (norm + 1e-9);\n        } else if (norm > 60.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 60.0 / norm;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    tasks.resize(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].id = i;\n        tasks[i].d.resize(K);\n        for (int k = 0; k < K; ++k) cin >> tasks[i].d[k];\n        tasks[i].status = -1;\n    }\n    \n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        tasks[v].deps.push_back(u);\n        tasks[u].rev_deps.push_back(v);\n    }\n    \n    calculate_heights();\n    calculate_descendants();\n    \n    members.resize(M);\n    for (int j = 0; j < M; ++j) {\n        members[j].id = j;\n        members[j].s.assign(K, 32.0 / sqrt((double)K));\n        members[j].current_task = -1;\n    }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        \n        for (int i = 0; i < N; ++i) {\n            if (tasks[i].status == -1) {\n                bool ok = true;\n                for (int dep : tasks[i].deps) {\n                    if (tasks[dep].status != 2) { ok = false; break; }\n                }\n                if (ok) tasks[i].status = 0;\n            }\n        }\n        \n        vector<int> idle_members, ready_tasks;\n        for (int j = 0; j < M; ++j) if (members[j].current_task == -1) idle_members.push_back(j);\n        for (int i = 0; i < N; ++i) if (tasks[i].status == 0) ready_tasks.push_back(i);\n        \n        vector<pair<int, int>> assignments;\n        while (!idle_members.empty() && !ready_tasks.empty()) {\n            double best_score = -1e18;\n            int best_m_idx = -1, best_t_idx = -1, best_mi = -1, best_ti = -1;\n\n            for (int mi = 0; mi < (int)idle_members.size(); ++mi) {\n                int j = idle_members[mi];\n                for (int ti = 0; ti < (int)ready_tasks.size(); ++ti) {\n                    int i = ready_tasks[ti];\n                    double w_est = get_w(members[j].s, tasks[i].d);\n                    double dur = expected_duration(w_est);\n                    // Standard scheduling priority: (critical_path_importance) * (efficiency)\n                    double score = (tasks[i].height * 100.0 + (double)tasks[i].descendants) / dur;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m_idx = j;\n                        best_t_idx = i;\n                        best_mi = mi;\n                        best_ti = ti;\n                    }\n                }\n            }\n            \n            if (best_m_idx != -1) {\n                assignments.push_back({best_m_idx, best_t_idx});\n                tasks[best_t_idx].status = 1;\n                members[best_m_idx].current_task = best_t_idx;\n                members[best_m_idx].start_day = current_day;\n                idle_members.erase(idle_members.begin() + best_mi);\n                ready_tasks.erase(ready_tasks.begin() + best_ti);\n            } else break;\n        }\n        \n        cout << (int)assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        cout << endl;\n        \n        int n_completed;\n        if (!(cin >> n_completed) || n_completed == -1) break;\n        for (int i = 0; i < n_completed; ++i) {\n            int m_id; cin >> m_id; --m_id;\n            int t_idx = members[m_id].current_task;\n            int duration = current_day - members[m_id].start_day + 1;\n            members[m_id].history.push_back({tasks[t_idx].d, duration});\n            tasks[t_idx].status = 2;\n            members[m_id].current_task = -1;\n            update_skills(m_id);\n        }\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// Order information and state arrays\nint orders_a[1000], orders_b[1000], orders_c[1000], orders_d[1000];\nint order_in_s[50];\nbool in_s[1000];\nint route[102];\nint pos[101]; // position of point index 0-99 in route\nint cur_x[101], cur_y[101]; // coords of point 0-99, and point 100 is the office (400, 400)\n\n// Calculate Manhattan distance between two points by their index in cur_x/cur_y\ninline int dist_points(int p1, int p2) {\n    return abs(cur_x[p1] - cur_x[p2]) + abs(cur_y[p1] - cur_y[p2]);\n}\n\n// Calculate Manhattan distance between a route index and specific coordinates\ninline int dist_to_coord(int r_idx, int x, int y) {\n    return abs(cur_x[route[r_idx]] - x) + abs(cur_y[route[r_idx]] - y);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read 1000 orders\n    for (int i = 0; i < 1000; i++) {\n        if (!(cin >> orders_a[i] >> orders_b[i] >> orders_c[i] >> orders_d[i])) break;\n    }\n\n    // Heuristic: Pick a pool of candidates closest to the office center (400, 400)\n    vector<pair<int, int>> pool_candidates;\n    for (int i = 0; i < 1000; i++) {\n        int d = abs(orders_a[i] - 400) + abs(orders_b[i] - 400) + abs(orders_c[i] - 400) + abs(orders_d[i] - 400);\n        pool_candidates.push_back({d, i});\n    }\n    sort(pool_candidates.begin(), pool_candidates.end());\n\n    // Use a subset of size 400 for selection\n    int pool_size = 400;\n    vector<int> pool;\n    for (int i = 0; i < pool_size; i++) {\n        pool.push_back(pool_candidates[i].second);\n    }\n\n    // Initialize chosen orders S with the first 50 closest orders\n    for (int i = 0; i < 50; i++) {\n        int order_idx = pool[i];\n        order_in_s[i] = order_idx;\n        in_s[order_idx] = true;\n        cur_x[i] = orders_a[order_idx];      // Pickup coordinate x\n        cur_y[i] = orders_b[order_idx];      // Pickup coordinate y\n        cur_x[i + 50] = orders_c[order_idx]; // Delivery coordinate x\n        cur_y[i + 50] = orders_d[order_idx]; // Delivery coordinate y\n    }\n    cur_x[100] = 400; cur_y[100] = 400; // Office coordinate\n\n    // Build an initial route using a Greedy Pickup-Delivery heuristic\n    int current_x = 400, current_y = 400;\n    vector<bool> visited_p(100, false);\n    route[0] = 100; route[101] = 100;\n    for (int step = 1; step <= 100; step++) {\n        int best_dist = 1e9, best_p = -1;\n        for (int p = 0; p < 100; p++) {\n            if (visited_p[p]) continue;\n            if (p >= 50 && !visited_p[p - 50]) continue; // Cannot deliver before pickup\n            int d = abs(current_x - cur_x[p]) + abs(current_y - cur_y[p]);\n            if (d < best_dist) { best_dist = d; best_p = p; }\n        }\n        route[step] = best_p;\n        pos[best_p] = step;\n        visited_p[best_p] = true;\n        current_x = cur_x[best_p]; current_y = cur_y[best_p];\n    }\n\n    // Initial total travel time\n    int current_t = 0;\n    for (int i = 0; i <= 100; i++) {\n        current_t += dist_points(route[i], route[i+1]);\n    }\n\n    // Simulated Annealing setup\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double t_start = 30.0, t_end = 0.1;\n    long long total_iter = 0;\n\n    while (true) {\n        // Limit total execution time to 1.96 seconds\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.96) break;\n\n        double progress = elapsed / 1.96;\n        double temp = t_start * pow(t_end / t_start, progress);\n\n        // Perform chunks of iterations\n        for (int j = 0; j < 2000; j++) {\n            int move_type = rng() % 100;\n\n            if (move_type < 45) { // Relocate point Move\n                int i = 1 + rng() % 100;\n                int k_pos = 1 + rng() % 100;\n                if (i == k_pos) continue;\n\n                int vi = route[i];\n                // Precedence Constraint Check\n                if (vi < 50) { if (i < k_pos && k_pos >= pos[vi + 50]) continue; }\n                else { if (i > k_pos && k_pos <= pos[vi - 50]) continue; }\n\n                // Distance Delta Calculation\n                int d_before, d_after;\n                if (i < k_pos) {\n                    d_before = dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]) + dist_points(route[k_pos], route[k_pos+1]);\n                    d_after = dist_points(route[i-1], route[i+1]) + dist_points(route[k_pos], route[i]) + dist_points(route[i], route[k_pos+1]);\n                } else {\n                    d_before = dist_points(route[k_pos-1], route[k_pos]) + dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]);\n                    d_after = dist_points(route[k_pos-1], route[i]) + dist_points(route[i], route[k_pos]) + dist_points(route[i-1], route[i+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    int v = route[i];\n                    if (i < k_pos) {\n                        for (int k = i; k < k_pos; k++) { route[k] = route[k+1]; pos[route[k]] = k; }\n                    } else {\n                        for (int k = i; k > k_pos; k--) { route[k] = route[k-1]; pos[route[k]] = k; }\n                    }\n                    route[k_pos] = v; pos[v] = k_pos;\n                }\n            } else if (move_type < 90) { // Swap two points Move\n                int i = 1 + rng() % 100;\n                int j = 1 + rng() % 100;\n                if (i == j) continue;\n                int vi = route[i], vj = route[j];\n\n                // Precedence Constraint Check\n                if (vi < 50) { if (j >= pos[vi + 50]) continue; }\n                else { if (j <= pos[vi - 50]) continue; }\n                if (vj < 50) { if (i >= pos[vj + 50]) continue; }\n                else { if (i <= pos[vj - 50]) continue; }\n\n                int d_before, d_after;\n                int i_low = min(i, j), i_high = max(i, j);\n                if (i_high == i_low + 1) {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                } else {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_low+1]) +\n                               dist_points(route[i_high-1], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low+1]) +\n                              dist_points(route[i_high-1], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    swap(route[i], route[j]);\n                    pos[route[i]] = i; pos[route[j]] = j;\n                }\n            } else { // Replace one order in S Move\n                int k = rng() % 50;\n                int old_idx = order_in_s[k];\n                int new_idx = pool[rng() % pool_size];\n                if (in_s[new_idx]) continue;\n\n                int pk_pos = pos[k], dk_pos = pos[k+50];\n                int nax = orders_a[new_idx], nay = orders_b[new_idx], ncx = orders_c[new_idx], ncy = orders_d[new_idx];\n\n                int d_before = dist_points(route[pk_pos-1], k) + dist_points(k, route[pk_pos+1]) +\n                               dist_points(route[dk_pos-1], k+50) + dist_points(k+50, route[dk_pos+1]);\n                if (pk_pos + 1 == dk_pos) {\n                    d_before = dist_points(route[pk_pos-1], k) + dist_points(k, k+50) + dist_points(k+50, route[dk_pos+1]);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_before = dist_points(route[dk_pos-1], k+50) + dist_points(k+50, k) + dist_points(k, route[pk_pos+1]);\n                }\n\n                int d_after = dist_to_coord(pk_pos-1, nax, nay) + dist_to_coord(pk_pos+1, nax, nay) +\n                              dist_to_coord(dk_pos-1, ncx, ncy) + dist_to_coord(dk_pos+1, ncx, ncy);\n                if (pk_pos + 1 == dk_pos) {\n                    d_after = dist_to_coord(pk_pos-1, nax, nay) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(dk_pos+1, ncx, ncy);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_after = dist_to_coord(dk_pos-1, ncx, ncy) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(pk_pos+1, nax, nay);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    in_s[old_idx] = false; in_s[new_idx] = true;\n                    order_in_s[k] = new_idx;\n                    cur_x[k] = nax; cur_y[k] = nay;\n                    cur_x[k+50] = ncx; cur_y[k+50] = ncy;\n                }\n            }\n        }\n        total_iter++;\n    }\n\n    // Final Output: Number of orders and their 1-indexed IDs\n    cout << 50;\n    for (int i = 0; i < 50; i++) cout << \" \" << order_in_s[i] + 1;\n    cout << \"\\n\";\n\n    // Final Output: Route coordinates (start office, pickups/deliveries, end office)\n    cout << 102;\n    for (int i = 0; i <= 101; i++) {\n        int x, y;\n        if (i == 0 || i == 101) { x = 400; y = 400; }\n        else {\n            int p = route[i];\n            if (p < 50) { x = orders_a[order_in_s[p]]; y = orders_b[order_in_s[p]]; }\n            else { x = orders_c[order_in_s[p - 50]]; y = orders_d[order_in_s[p - 50]]; }\n        }\n        cout << \" \" << x << \" \" << y;\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Strategy:\n * This is an online Minimum Spanning Tree (MST) problem with unknown edge weights revealed sequentially.\n * \n * Algorithm:\n * 1. For each edge revealed (u_i, v_i) with weight l_i:\n *    a. If u_i and v_i are already in the same connected component, reject the edge.\n *    b. Mandatory Check: Use a Disjoint Set Union (DSU) to check if u_i and v_i can be connected \n *       by any of the remaining future edges (j > i). If not, this edge is a bridge and MUST be adopted.\n *    c. Monte Carlo Simulation: Sample K scenarios where unknown weights are drawn from [d_j, 3*d_j].\n *       In each scenario, check if the current edge i is part of the MST.\n *       The edge is in the MST if there is no path between its endpoints using only edges with weight < l_i.\n *    d. If the edge is part of the MST in more than 50% of the simulations, adopt it.\n * \n * Performance Optimizations:\n * - Pre-sort edge scenarios by sampled weight to speed up MST checking.\n * - Map current components to a range [0, n_comp-1] for faster simulation DSU operations.\n * - Use adaptive time control to skip simulations if the 2.0s time limit is approaching.\n */\n\nstruct FastDSU {\n    int parent[400];\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    void unite(int i, int j) {\n        int ri = find(i);\n        int rj = find(j);\n        if (ri != rj) parent[ri] = rj;\n    }\n};\n\nstruct SimDSU {\n    int parent[400];\n    inline void reset(int n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\n    }\n    inline int find(int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]];\n            i = parent[i];\n        }\n        return i;\n    }\n};\n\nstruct ScenarioEdge {\n    int index;\n    int weight;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> x[i] >> y[i])) break;\n    }\n\n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; ++i) {\n        if (!(cin >> u[i] >> v[i])) break;\n        double dist = sqrt(pow((double)x[u[i]] - x[v[i]], 2) + pow((double)y[u[i]] - y[v[i]], 2));\n        d[i] = (int)round(dist);\n    }\n\n    // Prepare K independent scenarios for Monte Carlo simulation.\n    const int K = 80;\n    mt19937 rng(42);\n    vector<vector<ScenarioEdge>> sorted_scenarios(K, vector<ScenarioEdge>(M));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 0; i < M; ++i) {\n            sorted_scenarios[k][i].index = i;\n            sorted_scenarios[k][i].weight = d[i] + (rng() % (2 * d[i] + 1));\n        }\n        // Pre-sorting allows early exit in the simulation loop.\n        sort(sorted_scenarios[k].begin(), sorted_scenarios[k].end(), [](const ScenarioEdge& a, const ScenarioEdge& b) {\n            return a.weight < b.weight;\n        });\n    }\n\n    FastDSU dsu_base;\n    dsu_base.init(N);\n    SimDSU sim;\n    \n    auto start_time = chrono::steady_clock::now();\n    bool time_limit_reached = false;\n\n    // Helper arrays for component mapping and simulation.\n    int root_of_node[N], comp_map[N], mu_j[M], mv_j[M];\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n\n        // Path compression ensures we deal with roots of components.\n        for (int n = 0; n < N; ++n) root_of_node[n] = dsu_base.find(n);\n\n        int r_ui = root_of_node[u[i]];\n        int r_vi = root_of_node[v[i]];\n\n        if (r_ui == r_vi) {\n            cout << 0 << endl; // Redundant edge\n            continue;\n        }\n\n        // Map component roots to ID space [0, n_comp-1] to minimize DSU overhead.\n        int n_comp = 0;\n        for (int n = 0; n < N; ++n) {\n            if (root_of_node[n] == n) {\n                comp_map[n] = n_comp++;\n            }\n        }\n        int mru = comp_map[r_ui];\n        int mrv = comp_map[r_vi];\n\n        // 1. Mandatory Check:\n        // Use a temporary simulation to check if (u_i, v_i) is a bridge relative to future edges.\n        sim.reset(n_comp);\n        for (int j = i + 1; j < M; ++j) {\n            int r1 = sim.find(comp_map[root_of_node[u[j]]]);\n            int r2 = sim.find(comp_map[root_of_node[v[j]]]);\n            if (r1 != r2) {\n                sim.parent[r1] = r2;\n                if (sim.find(mru) == sim.find(mrv)) break;\n            }\n        }\n        \n        bool pick = false;\n        if (sim.find(mru) != sim.find(mrv)) {\n            // No combination of future edges can connect these components. Must pick.\n            pick = true;\n        } else {\n            // 2. Monte Carlo Simulation:\n            // Check time every 32 steps. If approaching 2.0s, stop running MC.\n            if ((i & 31) == 0) {\n                auto current_time = chrono::steady_clock::now();\n                if (chrono::duration<double>(current_time - start_time).count() > 1.85) {\n                    time_limit_reached = true;\n                }\n            }\n            \n            if (!time_limit_reached) {\n                // Pre-map endpoints of future edges for speed.\n                for (int j = i + 1; j < M; ++j) {\n                    mu_j[j] = comp_map[root_of_node[u[j]]];\n                    mv_j[j] = comp_map[root_of_node[v[j]]];\n                }\n\n                int in_mst_count = 0;\n                for (int k = 0; k < K; ++k) {\n                    sim.reset(n_comp);\n                    bool path_found = false;\n                    for (const auto& e : sorted_scenarios[k]) {\n                        // Ignore edges with larger weight or edges from the past.\n                        if (e.weight >= l_i) break;\n                        if (e.index <= i) continue;\n                        \n                        int m_u = mu_j[e.index];\n                        int m_v = mv_j[e.index];\n                        if (m_u != m_v) {\n                            int sr1 = sim.find(m_u);\n                            int sr2 = sim.find(m_v);\n                            if (sr1 != sr2) {\n                                sim.parent[sr1] = sr2;\n                                // If endpoints connect via cheaper edges, edge i is not in this scenario's MST.\n                                if (sim.find(mru) == sim.find(mrv)) {\n                                    path_found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    if (!path_found) in_mst_count++;\n                }\n                // Adopt edge if it is statistically beneficial.\n                if (in_mst_count * 2 > K) pick = true;\n            }\n        }\n\n        if (pick) {\n            dsu_base.unite(r_ui, r_vi);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int TURNS = 300;\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y; };\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nbool is_blocked[32][32];\n\n// Check if a square (tx, ty) can be blocked according to the contest rules\nbool can_block(int tx, int ty, const vector<Human>& current_humans) {\n    if (tx < 1 || tx > 30 || ty < 1 || ty > 30) return false;\n    if (is_blocked[tx][ty]) return false;\n    // Rule: Cannot block if square contains humans at the start of the turn\n    for (int i = 0; i < M; i++) {\n        if (current_humans[i].x == tx && current_humans[i].y == ty) return false;\n    }\n    // Rule: Cannot block if square contains a pet or is adjacent to a pet at the start of the turn\n    for (int i = 0; i < N; i++) {\n        if (abs(pets[i].x - tx) + abs(pets[i].y - ty) <= 1) return false;\n    }\n    return true;\n}\n\n// BFS to find the shortest path move for human i while avoiding blocked squares\nstring get_move(int i, int tx, int ty, const vector<Human>& current_humans, const bool being_blocked[32][32]) {\n    if (current_humans[i].x == tx && current_humans[i].y == ty) return \".\";\n\n    queue<pair<int, int>> q;\n    q.push({current_humans[i].x, current_humans[i].y});\n    int dist[32][32];\n    pair<int, int> parent[32][32];\n    for (int r = 0; r < 32; r++) for (int c = 0; c < 32; c++) dist[r][c] = -1;\n\n    dist[current_humans[i].x][current_humans[i].y] = 0;\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!q.empty()) {\n        pair<int, int> curr = q.front(); q.pop();\n        if (curr.first == tx && curr.second == ty) {\n            pair<int, int> p = {tx, ty};\n            // Trace back to the first move\n            while (parent[p.first][p.second].first != current_humans[i].x || parent[p.first][p.second].second != current_humans[i].y) {\n                p = parent[p.first][p.second];\n            }\n            if (p.first < current_humans[i].x) return \"U\";\n            if (p.first > current_humans[i].x) return \"D\";\n            if (p.second < current_humans[i].y) return \"L\";\n            if (p.second > current_humans[i].y) return \"R\";\n        }\n\n        for (int k = 0; k < 4; k++) {\n            int nx = curr.first + dx[k], ny = curr.second + dy[k];\n            if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n            // Avoid already impassable squares and those chosen to be blocked this turn\n            if (is_blocked[nx][ny] || being_blocked[nx][ny]) continue;\n\n            if (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    return \".\";\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int r = 0; r < 32; r++) for (int c = 0; c < 32; c++) is_blocked[r][c] = false;\n\n    if (!(cin >> N)) return 0;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) cin >> humans[i].x >> humans[i].y;\n\n    // Define target vertical wall columns to partition the grid\n    vector<int> wall_cols = {2, 5, 8, 11, 14, 17, 20, 23, 26, 29};\n    vector<int> wall_progress(10, 1);\n\n    for (int t = 0; t < TURNS; t++) {\n        vector<pair<int, int>> will_block(M, {0, 0});\n        bool being_blocked_this_turn[32][32];\n        for (int r = 0; r < 32; r++) for (int c = 0; c < 32; c++) being_blocked_this_turn[r][c] = false;\n\n        // Step 1: Identify all humans who will choose to block a square this turn\n        for (int i = 0; i < M; i++) {\n            for (int k = 0; k < (int)wall_cols.size(); k++) {\n                if (k % M != i || wall_progress[k] > 30) continue;\n                int tx = wall_progress[k], ty = wall_cols[k];\n                int sx = tx, sy = ty - 1; // Standard position to stand next to the wall square\n                if (humans[i].x == sx && humans[i].y == sy) {\n                    if (can_block(tx, ty, humans)) {\n                        will_block[i] = {tx, ty};\n                        being_blocked_this_turn[tx][ty] = true;\n                    }\n                }\n                break; // Each human focuses on their assigned walls sequentially\n            }\n        }\n\n        // Step 2: Determine movement or block actions for each human\n        string actions = \"\";\n        vector<Human> next_humans = humans;\n        for (int i = 0; i < M; i++) {\n            if (will_block[i].first != 0) {\n                int tx = will_block[i].first, ty = will_block[i].second;\n                if (tx < humans[i].x) actions += \"u\";\n                else if (tx > humans[i].x) actions += \"d\";\n                else if (ty < humans[i].y) actions += \"l\";\n                else actions += \"r\";\n            } else {\n                int tx = -1, ty = -1;\n                // Identify the next target for the human who isn't blocking this turn\n                for (int k = 0; k < (int)wall_cols.size(); k++) {\n                    if (k % M == i && wall_progress[k] <= 30) {\n                        tx = wall_progress[k];\n                        ty = wall_cols[k] - 1;\n                        break;\n                    }\n                }\n                if (tx != -1) {\n                    // All movers avoid squares currently chosen to be blocked this turn\n                    string mv = get_move(i, tx, ty, humans, being_blocked_this_turn);\n                    actions += mv;\n                    if (mv == \"U\") next_humans[i].x--;\n                    else if (mv == \"D\") next_humans[i].x++;\n                    else if (mv == \"L\") next_humans[i].y--;\n                    else if (mv == \"R\") next_humans[i].y++;\n                } else {\n                    actions += \".\";\n                }\n            }\n        }\n\n        // Step 3: Execute actions and update global status\n        cout << actions << endl;\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u') is_blocked[humans[i].x - 1][humans[i].y] = true;\n            else if (actions[i] == 'd') is_blocked[humans[i].x + 1][humans[i].y] = true;\n            else if (actions[i] == 'l') is_blocked[humans[i].x][humans[i].y - 1] = true;\n            else if (actions[i] == 'r') is_blocked[humans[i].x][humans[i].y + 1] = true;\n        }\n        // Update wall construction progress\n        for (int k = 0; k < (int)wall_cols.size(); k++) {\n            while (wall_progress[k] <= 30 && is_blocked[wall_progress[k]][wall_cols[k]]) {\n                wall_progress[k]++;\n            }\n        }\n        humans = next_humans;\n\n        // Step 4: Synchronize pet positions with game state\n        for (int i = 0; i < N; i++) {\n            string pm; if (!(cin >> pm)) break;\n            for (char c : pm) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <cstring>\n\nusing namespace std;\n\n// Directional moves: 0: Up (U), 1: Down (D), 2: Left (L), 3: Right (R)\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nint si, sj, ti, tj;\ndouble p_prob;\nstring h_wall[20], v_wall[19];\nint move_to[400][4];\ndouble V[400][202];\ndouble ValueMat[201][4][400];\ndouble ReachProb[400][4];\n\n// Utility function to check if movement from (i, j) in a direction is possible (no walls)\nbool can_move_func(int i, int j, int dir) {\n    if (dir == 0) return (i > 0 && v_wall[i - 1][j] == '0');\n    if (dir == 1) return (i < 19 && v_wall[i][j] == '0');\n    if (dir == 2) return (j > 0 && h_wall[i][j - 1] == '0');\n    if (dir == 3) return (j < 19 && h_wall[i][j] == '0');\n    return false;\n}\n\n// Precompute the expected future score using Dynamic Programming.\n// V[i][t] represents the maximum expected score Takahashi can obtain starting from cell i at turn t.\nvoid precompute() {\n    int target = ti * 20 + tj;\n    for (int i = 0; i < 400; i++) {\n        for (int d = 0; d < 4; d++) {\n            if (can_move_func(i / 20, i % 20, d))\n                move_to[i][d] = (i / 20 + di[d]) * 20 + (i % 20 + dj[d]);\n            else\n                move_to[i][d] = -1;\n            ReachProb[i][d] = (move_to[i][d] == target) ? (1.0 - p_prob) : 0.0;\n        }\n    }\n\n    memset(V, 0, sizeof(V));\n    for (int t = 200; t >= 1; t--) {\n        for (int i = 0; i < 400; i++) {\n            if (i == target) continue;\n            double max_v = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = move_to[i][d];\n                double res;\n                if (ni == -1) res = V[i][t + 1];\n                else if (ni == target) res = (1.0 - p_prob) * (401.0 - (double)t) + p_prob * V[i][t + 1];\n                else res = (1.0 - p_prob) * V[ni][t + 1] + p_prob * V[i][t + 1];\n                ValueMat[t][d][i] = res;\n                if (res > max_v) max_v = res;\n            }\n            V[i][t] = max_v;\n        }\n    }\n}\n\nstruct State {\n    double P[400];\n    int nonzero[400];\n    int num_nonzero;\n    double current_E_S;\n    double score;\n    string s;\n\n    State() : num_nonzero(0), current_E_S(0), score(0), s(\"\") {\n        memset(P, 0, sizeof(P));\n    }\n};\n\nstruct Candidate {\n    double score;\n    double p_reached_k;\n    int b_idx;\n    int dir;\n    bool operator>(const Candidate& o) const { return score > o.score; }\n};\n\ndouble tmp_P[400];\nbool used[400];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p_prob)) return 0;\n    for (int i = 0; i < 20; i++) cin >> h_wall[i];\n    for (int i = 0; i < 19; i++) cin >> v_wall[i];\n\n    precompute();\n\n    vector<State> beam;\n    State initial;\n    int start = si * 20 + sj;\n    initial.P[start] = 1.0;\n    initial.nonzero[0] = start;\n    initial.num_nonzero = 1;\n    initial.score = V[start][1];\n    beam.push_back(move(initial));\n\n    const int B = 1600; // Beam Width\n    const double EPS = 1e-15;\n    int target = ti * 20 + tj;\n\n    for (int k = 1; k <= 200; k++) {\n        vector<Candidate> cands;\n        cands.reserve(beam.size() * 4);\n        for (int b = 0; b < (int)beam.size(); b++) {\n            const State& st = beam[b];\n            for (int d = 0; d < 4; d++) {\n                double s_score = st.current_E_S;\n                double s_p_reach = 0;\n                const double* vm_k_d = ValueMat[k][d];\n                for (int i = 0; i < st.num_nonzero; i++) {\n                    int idx = st.nonzero[i];\n                    double p = st.P[idx];\n                    s_score += p * vm_k_d[idx];\n                    s_p_reach += p * ReachProb[idx][d];\n                }\n                cands.push_back({s_score, s_p_reach, b, d});\n            }\n        }\n\n        // Keep top B candidates to extend the beam\n        sort(cands.begin(), cands.end(), greater<Candidate>());\n        if ((int)cands.size() > B) cands.resize(B);\n\n        vector<State> next_beam;\n        next_beam.reserve(cands.size());\n        for (auto& c : cands) {\n            const State& prev = beam[c.b_idx];\n            State next_st;\n            next_st.s = prev.s + dc[c.dir];\n            next_st.current_E_S = prev.current_E_S + (401.0 - (double)k) * c.p_reached_k;\n            next_st.score = c.score;\n\n            for (int i = 0; i < prev.num_nonzero; i++) {\n                int idx = prev.nonzero[i];\n                double p = prev.P[idx];\n                int ni = move_to[idx][c.dir];\n                if (ni != -1) {\n                    if (!used[idx]) { used[idx] = true; next_st.nonzero[next_st.num_nonzero++] = idx; }\n                    tmp_P[idx] += p * p_prob;\n                    if (ni != target) {\n                        if (!used[ni]) { used[ni] = true; next_st.nonzero[next_st.num_nonzero++] = ni; }\n                        tmp_P[ni] += p * (1.0 - p_prob);\n                    }\n                } else {\n                    if (!used[idx]) { used[idx] = true; next_st.nonzero[next_st.num_nonzero++] = idx; }\n                    tmp_P[idx] += p;\n                }\n            }\n\n            int nn = 0;\n            for (int i = 0; i < next_st.num_nonzero; i++) {\n                int idx = next_st.nonzero[i];\n                if (tmp_P[idx] > EPS) {\n                    next_st.P[idx] = tmp_P[idx];\n                    next_st.nonzero[nn++] = idx;\n                }\n                tmp_P[idx] = 0;\n                used[idx] = false;\n            }\n            next_st.num_nonzero = nn;\n            next_beam.push_back(move(next_st));\n        }\n        beam = move(next_beam);\n    }\n\n    // Output the string from the most promising state\n    cout << beam[0].s << endl;\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 30;\n\n// Port directions: 0: Left, 1: Up, 2: Right, 3: Down\n// Direction change vectors\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Tile connection mapping\n// to_tbl[tile_type][port_direction] = partner_port_on_the_same_tile\nint to_tbl[8][4] = {\n    {1, 0, -1, -1}, // Tile 0: Left (0) <-> Top (1)\n    {3, -1, -1, 0}, // Tile 1: Left (0) <-> Bottom (3)\n    {-1, -1, 3, 2}, // Tile 2: Right (2) <-> Bottom (3)\n    {-1, 2, 1, -1}, // Tile 3: Right (2) <-> Top (1)\n    {1, 0, 3, 2},   // Tile 4: (0-1) and (2-3)\n    {3, 2, 1, 0},   // Tile 5: (0-3) and (1-2)\n    {2, -1, 0, -1}, // Tile 6: Left (0) <-> Right (2)\n    {-1, 3, -1, 1}  // Tile 7: Top (1) <-> Bottom (3)\n};\n\n// Global application state\nint initial_grid[N][N];\nint current_tiles[N][N];\nint rot[N][N];\nint best_rot[N][N];\nint visited[N][N][4];\nint timer = 0;\n\n// Map rotations (0-3 counterclockwise) to tile types based on input generation\ninline int get_tile_type(int initial_type, int rotation) {\n    if (initial_type <= 3) return (initial_type + rotation) % 4;\n    if (initial_type <= 5) return 4 + (initial_type - 4 + rotation) % 2;\n    if (initial_type <= 7) return 6 + (initial_type - 6 + rotation) % 2;\n    return initial_type;\n}\n\n// Optimized evaluation of loop lengths across the entire grid\n// Returns an efficiency score used as energy in Simulated Annealing\nlong long get_eff_score(int& m1, int& m2) {\n    timer++;\n    m1 = 0; m2 = 0;\n    long long sum_all = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int tile = current_tiles[i][j];\n            for (int d = 0; d < 4; ++d) {\n                // Skip if this port is not connected or already part of a processed component\n                if (to_tbl[tile][d] == -1 || visited[i][j][d] == timer) continue;\n                \n                int ci = i, cj = j, cd = d, len = 0;\n                bool is_loop = false;\n                while (true) {\n                    int dout = to_tbl[current_tiles[ci][cj]][cd];\n                    if (dout == -1) break;\n                    \n                    visited[ci][cj][cd] = timer;\n                    visited[ci][cj][dout] = timer;\n                    \n                    int ni = ci + di[dout], nj = cj + dj[dout];\n                    len++;\n                    \n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    \n                    int nd = dout ^ 2; // Enter the next tile from the opposite port\n                    if (ni == i && nj == j && nd == d) {\n                        is_loop = true;\n                        break;\n                    }\n                    if (visited[ni][nj][nd] == timer) break;\n                    \n                    ci = ni; cj = nj; cd = nd;\n                }\n                \n                if (is_loop) {\n                    sum_all += len;\n                    if (len > m1) {\n                        m2 = m1;\n                        m1 = len;\n                    } else if (len > m2) {\n                        m2 = len;\n                    }\n                }\n            }\n        }\n    }\n    // Strategic potential for SA: reward product of longest loops and sum of all loops\n    if (m1 > 0 && m2 > 0) return (long long)m1 * m2 * 1000000LL + sum_all;\n    else return (long long)m1 + m2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Parse grid\n    for (int i = 0; i < N; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < N; ++j) initial_grid[i][j] = s[j] - '0';\n    }\n\n    // Initialize with random rotations\n    mt19937 rng(12345);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rot[i][j] = rng() % 4;\n            current_tiles[i][j] = get_tile_type(initial_grid[i][j], rot[i][j]);\n        }\n    }\n\n    int m1, m2;\n    long long current_eff = get_eff_score(m1, m2);\n    long long best_actual_score = (long long)m1 * m2;\n    int best_sum_m1m2 = m1 + m2;\n    for(int r=0; r<N; ++r) for(int c=0; c<N; ++c) best_rot[r][c] = rot[r][c];\n\n    // SA parameters\n    auto start_time = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.95;\n    double T_start = 100000.0, T_end = 100.0;\n    double T = T_start;\n    uniform_real_distribution<double> dist_u(0.0, 1.0);\n\n    // Annealing loop\n    for (int iter = 0; ; ++iter) {\n        // Temperature cooling and time check every 256 steps\n        if ((iter & 255) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n            T = T_start * pow(T_end / T_start, elapsed / TIME_LIMIT);\n        }\n\n        // Neighbor: Rotate a single tile randomly\n        int ri = rng() % N;\n        int rj = rng() % N;\n        int old_r = rot[ri][rj];\n        rot[ri][rj] = (old_r + (rng() % 3) + 1) % 4;\n        current_tiles[ri][rj] = get_tile_type(initial_grid[ri][rj], rot[ri][rj]);\n\n        int nm1, nm2;\n        long long next_eff = get_eff_score(nm1, nm2);\n\n        // Metropolis acceptance criterion\n        if (next_eff >= current_eff || dist_u(rng) < exp((double)(next_eff - current_eff) / T)) {\n            current_eff = next_eff;\n            long long actual = (long long)nm1 * nm2;\n            if (actual > best_actual_score) {\n                best_actual_score = actual;\n                for(int r=0; r<N; ++r) for(int c=0; c<N; ++c) best_rot[r][c] = rot[r][c];\n            } else if (best_actual_score == 0 && (nm1 + nm2) > best_sum_m1m2) {\n                best_sum_m1m2 = nm1 + nm2;\n                for(int r=0; r<N; ++r) for(int c=0; c<N; ++c) best_rot[r][c] = rot[r][c];\n            }\n        } else {\n            // Revert state change\n            rot[ri][rj] = old_r;\n            current_tiles[ri][rj] = get_tile_type(initial_grid[ri][rj], old_r);\n        }\n    }\n\n    // Final output: string of rotation counts for each tile\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 <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nint N, T_max;\nint id_to_type[101];\nint initial_empty_r, initial_empty_c;\n\nstruct DSU {\n    int parent[100];\n    int sz[100];\n    int edges[100];\n    void init(int n) {\n        for (int i = 0; i < n; ++i) {\n            parent[i] = i;\n            sz[i] = 1;\n            edges[i] = 0;\n        }\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            parent[root_i] = root_j;\n            sz[root_j] += sz[root_i];\n            edges[root_j] += edges[root_i] + 1;\n        } else {\n            edges[root_i]++;\n        }\n    }\n};\n\nDSU dsu;\n\nint get_tree_score(const vector<int>& p) {\n    int total_tiles = N * N;\n    dsu.init(total_tiles);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int u = r * N + c;\n            int type_u = id_to_type[p[u]];\n            if (type_u == 0) continue;\n            if (c + 1 < N) {\n                int v = u + 1;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 4) && (type_v & 1)) dsu.unite(u, v);\n            }\n            if (r + 1 < N) {\n                int v = u + N;\n                int type_v = id_to_type[p[v]];\n                if (type_v != 0 && (type_u & 8) && (type_v & 2)) dsu.unite(u, v);\n            }\n        }\n    }\n    int max_s = 0;\n    for (int i = 0; i < total_tiles; ++i) {\n        if (dsu.parent[i] == i && id_to_type[p[i]] != 0) {\n            if (dsu.edges[i] == dsu.sz[i] - 1) {\n                if (dsu.sz[i] > max_s) max_s = dsu.sz[i];\n            }\n        }\n    }\n    return max_s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> T_max)) return 0;\n    vector<int> initial_p(N * N);\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            int type;\n            if (row[j] >= 'a') type = row[j] - 'a' + 10;\n            else type = row[j] - '0';\n            int tile_id = i * N + j;\n            id_to_type[tile_id] = type;\n            initial_p[tile_id] = tile_id;\n            if (type == 0) {\n                initial_empty_r = i;\n                initial_empty_c = j;\n            }\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(12345);\n    string current_moves = \"\";\n    vector<int> current_p = initial_p;\n    int current_s = get_tree_score(current_p);\n\n    string best_moves = current_moves;\n    int best_s = current_s;\n\n    const double time_limit = 2.85;\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit) {\n        string next_moves = current_moves;\n        int action = rng() % 3;\n        if (action == 0 && next_moves.size() < (size_t)T_max) {\n            next_moves += \"UDLR\"[rng() % 4];\n        } else if (action == 1 && !next_moves.empty()) {\n            next_moves.pop_back();\n        } else if (action == 2 && !next_moves.empty()) {\n            next_moves[rng() % next_moves.size()] = \"UDLR\"[rng() % 4];\n        } else {\n            continue;\n        }\n\n        vector<int> p = initial_p;\n        int er = initial_empty_r, ec = initial_empty_c;\n        bool possible = true;\n        for (char m : next_moves) {\n            int nr = er, nc = ec;\n            if (m == 'U') nr--;\n            else if (m == 'D') nr++;\n            else if (m == 'L') nc--;\n            else if (m == 'R') nc++;\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                swap(p[er * N + ec], p[nr * N + nc]);\n                er = nr; ec = nc;\n            } else {\n                possible = false;\n                break;\n            }\n        }\n\n        if (possible) {\n            int s = get_tree_score(p);\n            // Optimization for the target: larger tree is always better,\n            // if size is equal, a shorter sequence is better to potentially solve it or get a higher bonus.\n            bool accept = false;\n            if (s > current_s) {\n                accept = true;\n            } else if (s == current_s) {\n                if (next_moves.size() <= current_moves.size()) accept = true;\n                else if (rng() % 100 < 5) accept = true; // Limited random walk\n            } else {\n                if (rng() % 1000 < 1) accept = true; // SA-like behavior\n            }\n\n            if (accept) {\n                current_moves = next_moves;\n                current_s = s;\n                if (current_s > best_s || (current_s == best_s && current_moves.size() < best_moves.size())) {\n                    best_s = current_s;\n                    best_moves = current_moves;\n                }\n            }\n        }\n    }\n\n    cout << best_moves << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Strawberry structure to keep track of its coordinates and its grid cell\nstruct Strawberry {\n    int x, y;\n    int sx, sy;\n    int posInSlabX;\n    int posInSlabY;\n};\n\n// Global counts and pieces\nint count_grid[52][52];\nint b[5505];\nint a[11];\nint current_sum_min = 0;\n\n// Efficient update of b_d and the score sum(min(a_d, b_d))\nvoid update_b(int d, int delta) {\n    if (d >= 1 && d <= 10) current_sum_min -= min(a[d], b[d]);\n    b[d] += delta;\n    if (d >= 1 && d <= 10) current_sum_min += min(a[d], b[d]);\n}\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K_limit;\n    if (!(cin >> N >> K_limit)) return 0;\n\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Strawberry> strawberries(N);\n    vector<int> all_x, all_y;\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        all_x.push_back(strawberries[i].x);\n        all_y.push_back(strawberries[i].y);\n    }\n\n    // kx and ky are the number of vertical and horizontal cuts, kx+ky <= 100\n    int kx = 50, ky = 50;\n    vector<int> X(kx + 2), Y(ky + 2);\n    X[0] = -1000000; X[kx + 1] = 1000000;\n    Y[0] = -1000000; Y[ky + 1] = 1000000;\n\n    // Initialize cuts based on strawberry density\n    sort(all_x.begin(), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    for (int i = 1; i <= kx; ++i) X[i] = all_x[i * N / (kx + 1)];\n    for (int j = 1; j <= ky; ++j) Y[j] = all_y[j * N / (ky + 1)];\n\n    // Ensure all cuts are strictly increasing and within integer point boundaries\n    for (int i = 1; i <= kx; ++i) if (X[i] <= X[i - 1]) X[i] = X[i - 1] + 1;\n    for (int i = kx; i >= 1; --i) if (X[i] >= X[i + 1]) X[i] = X[i + 1] - 1;\n    for (int j = 1; j <= ky; ++j) if (Y[j] <= Y[j - 1]) Y[j] = Y[j - 1] + 1;\n    for (int j = ky; j >= 1; --j) if (Y[j] >= Y[j + 1]) Y[j] = Y[j + 1] - 1;\n\n    vector<vector<int>> SlabX(kx + 1), SlabY(ky + 1);\n    for (int d = 0; d <= N; ++d) b[d] = 0;\n\n    // Assign strawberries to slabs and grid cells\n    for (int i = 0; i < N; ++i) {\n        int sx = 0;\n        while (sx < kx && strawberries[i].x > X[sx + 1]) sx++;\n        int sy = 0;\n        while (sy < ky && strawberries[i].y > Y[sy + 1]) sy++;\n\n        strawberries[i].sx = sx;\n        strawberries[i].sy = sy;\n        strawberries[i].posInSlabX = SlabX[sx].size();\n        SlabX[sx].push_back(i);\n        strawberries[i].posInSlabY = SlabY[sy].size();\n        SlabY[sy].push_back(i);\n\n        update_b(count_grid[sx][sy], -1);\n        count_grid[sx][sy]++;\n        update_b(count_grid[sx][sy], 1);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    long long iterations = 0;\n\n    // Optimization through Hill Climbing\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n        }\n        iterations++;\n\n        bool is_x = rng() % 2 == 0;\n        if (is_x) {\n            int i = rng() % kx + 1;\n            int oldX = X[i];\n            int range = X[i + 1] - X[i - 1] - 1;\n            if (range <= 0) continue;\n\n            int newX;\n            int r = rng() % 100;\n            if (r < 50) newX = X[i] + (rng() % 21 - 10);\n            else if (r < 80) newX = strawberries[rng() % N].x;\n            else newX = X[i - 1] + 1 + rng() % range;\n            if (newX <= X[i - 1] || newX >= X[i + 1]) newX = X[i - 1] + 1 + (rng() % range);\n            if (newX == oldX) continue;\n\n            vector<int> moved_k;\n            if (newX > oldX) {\n                for (int k : SlabX[i]) if (strawberries[k].x <= newX) moved_k.push_back(k);\n            } else {\n                for (int k : SlabX[i - 1]) if (strawberries[k].x > newX) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sy = strawberries[k].sy;\n                if (newX > oldX) { // move from SlabX[i] to SlabX[i-1]\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                } else { // move from SlabX[i-1] to SlabX[i]\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                }\n            }\n\n            // Accept if score improved or stayed the same (plateau-walking)\n            if (current_sum_min >= prev_sum) {\n                X[i] = newX;\n                for (int k : moved_k) {\n                    int old_sx = strawberries[k].sx;\n                    int new_sx = (newX > oldX) ? i - 1 : i;\n                    // Slab update: O(1) remove/add\n                    int pos = strawberries[k].posInSlabX;\n                    int last_k = SlabX[old_sx].back();\n                    SlabX[old_sx][pos] = last_k;\n                    strawberries[last_k].posInSlabX = pos;\n                    SlabX[old_sx].pop_back();\n                    strawberries[k].sx = new_sx;\n                    strawberries[k].posInSlabX = SlabX[new_sx].size();\n                    SlabX[new_sx].push_back(k);\n                }\n            } else { // Undo changes if rejected\n                for (int k : moved_k) {\n                    int sy = strawberries[k].sy;\n                    if (newX > oldX) {\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                    } else {\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                    }\n                }\n            }\n        } else {\n            // Symmetrical horizontal move\n            int j = rng() % ky + 1;\n            int oldY = Y[j];\n            int range = Y[j + 1] - Y[j - 1] - 1;\n            if (range <= 0) continue;\n\n            int newY;\n            int r = rng() % 100;\n            if (r < 50) newY = Y[j] + (rng() % 21 - 10);\n            else if (r < 80) newY = strawberries[rng() % N].y;\n            else newY = Y[j - 1] + 1 + rng() % range;\n            if (newY <= Y[j - 1] || newY >= Y[j + 1]) newY = Y[j - 1] + 1 + (rng() % range);\n            if (newY == oldY) continue;\n\n            vector<int> moved_k;\n            if (newY > oldY) {\n                for (int k : SlabY[j]) if (strawberries[k].y <= newY) moved_k.push_back(k);\n            } else {\n                for (int k : SlabY[j - 1]) if (strawberries[k].y > newY) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sx = strawberries[k].sx;\n                if (newY > oldY) { // move from SlabY[j] to SlabY[j-1]\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                } else { // move from SlabY[j-1] to SlabY[j]\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                }\n            }\n\n            if (current_sum_min >= prev_sum) {\n                Y[j] = newY;\n                for (int k : moved_k) {\n                    int old_sy = strawberries[k].sy;\n                    int new_sy = (newY > oldY) ? j - 1 : j;\n                    int pos = strawberries[k].posInSlabY;\n                    int last_k = SlabY[old_sy].back();\n                    SlabY[old_sy][pos] = last_k;\n                    strawberries[last_k].posInSlabY = pos;\n                    SlabY[old_sy].pop_back();\n                    strawberries[k].sy = new_sy;\n                    strawberries[k].posInSlabY = SlabY[new_sy].size();\n                    SlabY[new_sy].push_back(k);\n                }\n            } else {\n                for (int k : moved_k) {\n                    int sx = strawberries[k].sx;\n                    if (newY > oldY) {\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                    } else {\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                    }\n                }\n            }\n        }\n    }\n\n    // Output formatting\n    cout << kx + ky << endl;\n    for (int i = 1; i <= kx; ++i) {\n        // Vertical lines x ~ X[i] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << X[i] << \" -1000000000 \" << X[i] + 1 << \" 1000000000\" << endl;\n    }\n    for (int j = 1; j <= ky; ++j) {\n        // Horizontal lines y ~ Y[j] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << \"-1000000000 \" << Y[j] << \" 1000000000 \" << Y[j] + 1 << endl;\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Operation structure for storing the four chosen grid points.\nstruct Op {\n    int x1, y1, x2, y2, x3, y3, x4, y4;\n};\n\n// Direction vectors for axis-parallel and 45-degree diagonal movements.\nconst int dx[] = {1, 1, 0, -1, -1, -1, 0, 1};\nconst int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};\n\n// Corner direction pairs for forming rectangles.\nconst pair<int, int> ortho[] = {\n    {0, 2}, {2, 4}, {4, 6}, {6, 0},\n    {1, 3}, {3, 5}, {5, 7}, {7, 1}\n};\n\nint N, M;\nlong long weights[61][61];\nbool init_has_dot[61][61];\nbool has_dot[61][61];\nbool used[61][61][8]; // Segment usage: used[x][y][d] means the segment (x,y) to (x+dx[d],y+dy[d]) is used.\n\n// Checks if any part of the segment between two dots is already part of a drawn rectangle perimeter.\ninline bool is_path_clear(int x1, int y1, int x2, int y2, int d) {\n    int cx = x1, cy = y1;\n    while (cx != x2 || cy != y2) {\n        if (used[cx][cy][d]) return false;\n        cx += dx[d]; cy += dy[d];\n    }\n    return true;\n}\n\n// Marks the segments of a new rectangle as part of the drawn perimeters.\ninline void mark_used(int x1, int y1, int x2, int y2, int d) {\n    int cx = x1, cy = y1;\n    while (cx != x2 || cy != y2) {\n        used[cx][cy][d] = true;\n        int nx = cx + dx[d], ny = cy + dy[d];\n        used[nx][ny][(d + 4) % 8] = true; // Bi-directional marking.\n        cx = nx; cy = ny;\n    }\n}\n\n// Finds the closest grid point containing a dot in a given direction.\ninline pair<int, int> find_nearest(int x, int y, int d) {\n    int cx = x + dx[d], cy = y + dy[d];\n    while (cx >= 0 && cx < N && cy >= 0 && cy < N) {\n        if (has_dot[cx][cy]) return {cx, cy};\n        cx += dx[d]; cy += dy[d];\n    }\n    return {-1, -1};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initial grid state and point weights.\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) init_has_dot[i][j] = false;\n    }\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        init_has_dot[x][y] = true;\n    }\n\n    int center = (N - 1) / 2;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            weights[x][y] = (long long)(x - center) * (x - center) + (long long)(y - center) * (y - center) + 1;\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    long long best_total_weight = -1;\n    vector<Op> best_ops;\n\n    // Potential candidates for the new dot p1 (initially all empty points).\n    vector<pair<int, int>> p1_candidates;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (!init_has_dot[x][y]) p1_candidates.push_back({x, y});\n        }\n    }\n\n    int trial = 0;\n    // Multi-start greedy approach: explore different sequences of dot placements within time limit.\n    while (true) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 4700) break;\n\n        // Reset state for the current trial.\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                has_dot[i][j] = init_has_dot[i][j];\n                for (int d = 0; d < 8; d++) used[i][j][d] = false;\n            }\n        }\n\n        vector<Op> current_ops;\n        long long current_total_weight = 0;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (has_dot[x][y]) current_total_weight += weights[x][y];\n            }\n        }\n\n        double alpha, w_bias;\n        // Diverse heuristic strategies across trials.\n        if (trial == 0) {\n            sort(p1_candidates.begin(), p1_candidates.end(), [&](pair<int, int> a, pair<int, int> b) {\n                return weights[a.first][a.second] < weights[b.first][b.second];\n            });\n            alpha = 2.0; w_bias = 1.0;\n        } else if (trial == 1) {\n            sort(p1_candidates.begin(), p1_candidates.end(), [&](pair<int, int> a, pair<int, int> b) {\n                return weights[a.first][a.second] < weights[b.first][b.second];\n            });\n            alpha = 1.0; w_bias = 1.0;\n        } else if (trial == 2) {\n            sort(p1_candidates.begin(), p1_candidates.end(), [&](pair<int, int> a, pair<int, int> b) {\n                return weights[a.first][a.second] > weights[b.first][b.second];\n            });\n            alpha = 1.5; w_bias = 1.0;\n        } else {\n            shuffle(p1_candidates.begin(), p1_candidates.end(), rng);\n            alpha = 0.5 + (rng() % 2501) / 1000.0;\n            w_bias = 0.5 + (rng() % 1501) / 1000.0;\n        }\n\n        // Greedy loop for the current trial.\n        while (true) {\n            bool changed_any = false;\n            for (auto& p : p1_candidates) {\n                int x = p.first, y = p.second;\n                if (has_dot[x][y]) continue;\n\n                int best_d1 = -1, best_d2 = -1;\n                int bp2x, bp2y, bp3x, bp3y, bp4x, bp4y;\n                double max_score = -1.0;\n\n                // For each point p1, check all 8 possible rectangle corners.\n                for (int i = 0; i < 8; i++) {\n                    int d1 = ortho[i].first, d2 = ortho[i].second;\n                    pair<int, int> p2 = find_nearest(x, y, d1);\n                    if (p2.first == -1) continue;\n                    pair<int, int> p4 = find_nearest(x, y, d2);\n                    if (p4.first == -1) continue;\n\n                    int p3x = p2.first + p4.first - x, p3y = p2.second + p4.second - y;\n                    if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N || !has_dot[p3x][p3y]) continue;\n\n                    // Condition 2 check (no extra dots on perimeter).\n                    if (find_nearest(p2.first, p2.second, d2) != make_pair(p3x, p3y)) continue;\n                    if (find_nearest(p4.first, p4.second, d1) != make_pair(p3x, p3y)) continue;\n\n                    // Condition 3 check (no shared perimeter segments).\n                    if (!is_path_clear(x, y, p2.first, p2.second, d1)) continue;\n                    if (!is_path_clear(p2.first, p2.second, p3x, p3y, d2)) continue;\n                    if (!is_path_clear(p3x, p3y, p4.first, p4.second, (d1+4)%8)) continue;\n                    if (!is_path_clear(p4.first, p4.second, x, y, (d2+4)%8)) continue;\n\n                    // Heuristic scoring to balance point weight and rectangle size.\n                    double d_sq = (double)((x-p2.first)*(x-p2.first) + (y-p2.second)*(y-p2.second) + (x-p4.first)*(x-p4.first) + (y-p4.second)*(y-p4.second));\n                    double score = pow((double)weights[x][y], w_bias) / pow(d_sq, alpha);\n                    if (score > max_score) {\n                        max_score = score;\n                        best_d1 = d1; best_d2 = d2;\n                        bp2x = p2.first; bp2y = p2.second; bp3x = p3x; bp3y = p3y; bp4x = p4.first; bp4y = p4.second;\n                    }\n                }\n\n                // Apply the move if a valid rectangle was found.\n                if (best_d1 != -1) {\n                    has_dot[x][y] = true;\n                    mark_used(x, y, bp2x, bp2y, best_d1);\n                    mark_used(bp2x, bp2y, bp3x, bp3y, best_d2);\n                    mark_used(bp3x, bp3y, bp4x, bp4y, (best_d1 + 4) % 8);\n                    mark_used(bp4x, bp4y, x, y, (best_d2 + 4) % 8);\n                    current_ops.push_back({x, y, bp2x, bp2y, bp3x, bp3y, bp4x, bp4y});\n                    current_total_weight += weights[x][y];\n                    changed_any = true;\n                }\n            }\n            if (!changed_any) break;\n            shuffle(p1_candidates.begin(), p1_candidates.end(), rng);\n        }\n\n        // Keep track of the best sequence of operations found across all trials.\n        if (current_total_weight > best_total_weight) {\n            best_total_weight = current_total_weight;\n            best_ops = current_ops;\n        }\n        trial++;\n    }\n\n    // Output results.\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.x1 << \" \" << op.y1 << \" \" << op.x2 << \" \" << op.y2 << \" \"\n             << op.x3 << \" \" << op.y3 << \" \" << op.x4 << \" \" << op.y4 << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <chrono>\n#include <algorithm>\n#include <cstdint>\n\nusing namespace std;\nusing namespace std::chrono;\n\n/**\n * Xorshift algorithm for fast pseudo-random number generation.\n * Essential for getting more Monte Carlo trials within the time limit.\n */\nstruct Xorshift {\n    uint32_t x;\n    Xorshift(uint32_t seed = 123456789) : x(seed) {}\n    uint32_t next() {\n        x ^= (x << 13);\n        x ^= (x >> 17);\n        x ^= (x << 5);\n        return x;\n    }\n};\n\n/**\n * Represents the 10x10 candy box grid.\n * We use a 1D array of 100 elements for better cache performance.\n */\nstruct Board {\n    int8_t grid[100]; // 0: empty, 1-3: flavors\n\n    Board() {\n        for (int i = 0; i < 100; ++i) grid[i] = 0;\n    }\n\n    /**\n     * Tilts the box in the specified direction.\n     * 0: Forward (Up), 1: Backward (Down), 2: Left, 3: Right.\n     */\n    bool tilt(int dir) {\n        bool changed = false;\n        if (dir == 0) { // Up\n            for (int j = 0; j < 10; ++j) {\n                int last = 0;\n                for (int i = 0; i < 10; ++i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 1) { // Down\n            for (int j = 0; j < 10; ++j) {\n                int last = 9;\n                for (int i = 9; i >= 0; --i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        } else if (dir == 2) { // Left\n            for (int i = 0; i < 10; ++i) {\n                int last = 0;\n                for (int j = 0; j < 10; ++j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 3) { // Right\n            for (int i = 0; i < 10; ++i) {\n                int last = 9;\n                for (int j = 9; j >= 0; --j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * Places the actual candy received into the p-th available empty cell.\n     */\n    void place_actual(int p, int flavor) {\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                if (++count == p) {\n                    grid[i] = (int8_t)flavor;\n                    return;\n                }\n            }\n        }\n    }\n\n    /**\n     * Randomly places a candy of the given flavor into an empty cell.\n     */\n    void place_randomly(int flavor, Xorshift& rng) {\n        int empty_indices[100], num_empty = 0;\n        for (int i = 0; i < 100; ++i) if (grid[i] == 0) empty_indices[num_empty++] = i;\n        if (num_empty > 0) {\n            grid[empty_indices[rng.next() % num_empty]] = (int8_t)flavor;\n        }\n    }\n\n    /**\n     * Calculates the sum of squares of connected component sizes.\n     * Note: This function modifies the grid to mark visited nodes.\n     */\n    int eval_score_and_destroy() {\n        int sum_sq = 0;\n        int q[100];\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] <= 0) continue;\n            int head = 0, tail = 0, flavor = grid[i];\n            q[tail++] = i;\n            grid[i] = -flavor; // Mark as visited\n            while (head < tail) {\n                int cur = q[head++];\n                if (cur >= 10 && grid[cur - 10] == flavor) { grid[cur - 10] = -flavor; q[tail++] = cur - 10; }\n                if (cur < 90 && grid[cur + 10] == flavor) { grid[cur + 10] = -flavor; q[tail++] = cur + 10; }\n                if (cur % 10 > 0 && grid[cur - 1] == flavor) { grid[cur - 1] = -flavor; q[tail++] = cur - 1; }\n                if (cur % 10 < 9 && grid[cur + 1] == flavor) { grid[cur + 1] = -flavor; q[tail++] = cur + 1; }\n            }\n            sum_sq += tail * tail;\n        }\n        return sum_sq;\n    }\n};\n\n// 4 different corner-clustering strategies for rollouts\nconst int policies[4][4] = {\n    {0, 2, 3, 1}, // Up, Left priority (Top-Left corner)\n    {0, 3, 2, 1}, // Up, Right priority (Top-Right corner)\n    {1, 2, 3, 0}, // Down, Left priority (Bottom-Left corner)\n    {1, 3, 2, 0}  // Down, Right priority (Bottom-Right corner)\n};\n\ninline void apply_policy(Board& b, int p_idx) {\n    const int* p = policies[p_idx];\n    if (b.tilt(p[0])) return;\n    if (b.tilt(p[1])) return;\n    if (b.tilt(p[2])) return;\n    b.tilt(p[3]);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Xorshift rng;\n    Board current_board;\n    char d_chars[] = {'F', 'B', 'L', 'R'};\n    auto start_prog = steady_clock::now();\n\n    for (int t = 0; t < 100; ++t) {\n        int p; cin >> p;\n        current_board.place_actual(p, flavors[t]);\n\n        auto turn_start = steady_clock::now();\n        double elapsed = duration<double>(turn_start - start_prog).count();\n        double turn_time = (1.95 - elapsed) / (100.0 - t);\n        if (turn_time < 0.002) turn_time = 0.002;\n\n        double scores[4] = {0};\n        int trials[4] = {0};\n        int total_trials = 0;\n        int d_idx = rng.next() % 4;\n\n        while (true) {\n            if (total_trials % 32 == 0) {\n                if (duration<double>(steady_clock::now() - turn_start).count() > turn_time) break;\n            }\n\n            int d = d_idx % 4;\n            Board sim = current_board;\n            sim.tilt(d);\n\n            int p_idx = rng.next() % 4; // Use one of the 4 corner policies\n            for (int k = t + 1; k < 100; ++k) {\n                sim.place_randomly(flavors[k], rng);\n                apply_policy(sim, p_idx);\n            }\n\n            scores[d] += sim.eval_score_and_destroy();\n            trials[d]++;\n            total_trials++;\n            d_idx++;\n        }\n\n        int best_d = 0;\n        double max_avg = -1.0;\n        for (int d = 0; d < 4; ++d) {\n            if (trials[d] > 0) {\n                double avg = scores[d] / trials[d];\n                if (avg > max_avg) {\n                    max_avg = avg;\n                    best_d = d;\n                }\n            }\n        }\n\n        cout << d_chars[best_d] << endl;\n        current_board.tilt(best_d);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Normal CDF function: Phi(x) = 0.5 * (1 + erf((x - mean) / (sigma * sqrt(2))))\n * This function calculates the probability that a random variable following a normal \n * distribution with the given mean and sigma is less than x.\n */\ndouble normal_cdf(double x, double mean, double sigma) {\n    if (sigma < 1e-9) {\n        if (x < mean) return 0.0;\n        if (x > mean) return 1.0;\n        return 0.5;\n    }\n    return 0.5 * (1.0 + erf((x - mean) / (sigma * sqrt(2.0))));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double eps;\n    // Read the number of graphs M and the error rate epsilon.\n    if (!(cin >> M >> eps)) return 0;\n\n    int bestN = 4;\n    double bestExpectedScore = -1.0;\n\n    // Iterate through all possible values for N (the number of vertices) to find the one that \n    // maximizes the expected score. The score is calculated based on the expected number of \n    // errors using an edge count encoding/decoding method.\n    for (int N = 4; N <= 100; ++N) {\n        int K = N * (N - 1) / 2; // Maximum number of possible edges.\n        vector<int> Es(M);\n        for (int s = 0; s < M; ++s) {\n            // Encode the number of edges for each graph G_s.\n            Es[s] = (int)round((double)s * K / (M - 1));\n        }\n\n        // Standard deviation of the edge count after noise (Binomial sum approximation).\n        double sigma = sqrt((double)K * eps * (1.0 - eps));\n        double P_avg = 0.0;\n\n        for (int s = 0; s < M; ++s) {\n            // Count how many graphs have the same number of edges as G_s.\n            int c = 0;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] == Es[s]) c++;\n            }\n\n            // The expected mean number of edges in the noisy graph H generated from G_s.\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n\n            // Find the closest different edge counts to identify the decision boundaries.\n            double E_prev = -1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] < Es[s]) {\n                    if (E_prev < -1e17 || Es[j] > E_prev) {\n                        E_prev = (double)Es[j];\n                    }\n                }\n            }\n\n            double E_next = 1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] > Es[s]) {\n                    if (E_next > 1e17 || Es[j] < E_next) {\n                        E_next = (double)Es[j];\n                    }\n                }\n            }\n\n            double low, high;\n            if (E_prev < -1e17) {\n                low = -1e18; // No lower bound for the first category.\n            } else {\n                double mu_prev = E_prev * (1.0 - 2.0 * eps) + (double)K * eps;\n                low = (mu_s + mu_prev) / 2.0;\n            }\n\n            if (E_next > 1e17) {\n                high = 1e18; // No upper bound for the last category.\n            } else {\n                double mu_next = E_next * (1.0 - 2.0 * eps) + (double)K * eps;\n                high = (mu_s + mu_next) / 2.0;\n            }\n\n            // Estimate the probability of correct decoding for the s-th graph.\n            double prob_correct_in_range;\n            if (sigma < 1e-9) {\n                prob_correct_in_range = 1.0;\n            } else {\n                prob_correct_in_range = normal_cdf(high, mu_s, sigma) - normal_cdf(low, mu_s, sigma);\n            }\n            // If multiple graphs have the same edge count, they are indistinguishable.\n            P_avg += prob_correct_in_range / (double)c;\n        }\n\n        // Calculate the overall expected probability of a correct prediction.\n        P_avg /= (double)M;\n        double p_error = 1.0 - P_avg;\n        // Expected absolute score formula: (1 - 0.1 * p_error)^100 / N.\n        double expectedScore = pow(1.0 - 0.1 * p_error, 100) / (double)N;\n\n        if (expectedScore > bestExpectedScore) {\n            bestExpectedScore = expectedScore;\n            bestN = N;\n        }\n    }\n\n    // Set up the selected N and the corresponding graphs G_0, ..., G_{M-1}.\n    int N = bestN;\n    int K = N * (N - 1) / 2;\n    vector<int> Es(M);\n    for (int s = 0; s < M; ++s) {\n        Es[s] = (int)round((double)s * K / (M - 1));\n    }\n\n    // Output the chosen number of vertices N.\n    cout << N << endl;\n    // Output the string representations for the M graphs.\n    for (int s = 0; s < M; ++s) {\n        string g(K, '0');\n        for (int i = 0; i < Es[s]; ++i) {\n            g[i] = '1';\n        }\n        cout << g << endl;\n    }\n    cout.flush();\n\n    // Process 100 noisy graph queries.\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        if (!(cin >> H)) break;\n        // Count the number of edges in the received graph H.\n        int EH = 0;\n        for (char c : H) {\n            if (c == '1') EH++;\n        }\n\n        // Find the graph s whose expected noisy edge count mean is closest to EH.\n        int best_s = 0;\n        double min_diff = 1e18;\n        for (int s = 0; s < M; ++s) {\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n            double diff = abs((double)EH - mu_s);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        // Output the prediction for the current query.\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Takahashi City Road Repair Problem\n * \n * Objective: Minimize the average frustration level for road repairs over D days.\n * Frustration is defined as the expected increase in the shortest path distance\n * between vertices when some edges are closed for repair.\n * \n * Strategy:\n * 1. Initial Assignment: Sort edges based on their spatial orientation (angle from \n *    the centroid of the city). Distribute them across D days using round-robin. \n *    This ensures that roads under repair on any given day are spread out spatially.\n * 2. Proxy Frustration Function: Instead of all-pairs shortest paths, calculate \n *    shortest paths from a set of S=12 source vertices chosen via Farthest Point \n *    Sampling (FPS) for better coverage.\n * 3. Local Optimization (Hill Climbing): Perform as many iterations as possible \n *    within the time limit (5.8s). Iterations involve swapping repair days for \n *    two edges or moving an edge from one day to another, targeted at reducing \n *    the frustration of the worst days.\n */\n\nconst int INF_VAL = 1000000000;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int to, weight, id;\n};\n\n// Global problem and graph data structures\nvector<Edge> adj[MAXN];\nint edge_u[MAXM], edge_v[MAXM], edge_w[MAXM];\nint edge_day_arr[MAXM];\nint base_dists[15][MAXN]; // Stores original distances from selected sources\nint X[MAXN], Y[MAXN];\nint N, M, D, K;\n\n// Reusable Dijkstra state\nint dists[MAXN];\nint vis[MAXN];\nint timer = 0;\nvector<int> sources;\n\n/**\n * Optimized Dijkstra's algorithm.\n * Skips edges assigned to be repaired on 'repair_day'.\n */\nvoid dijkstra(int start, int repair_day) {\n    timer++;\n    dists[start] = 0;\n    vis[start] = timer;\n    using P = pair<int, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, start});\n    \n    while (!pq.empty()) {\n        P top = pq.top(); pq.pop();\n        int d = top.first;\n        int u = top.second;\n        if (d > dists[u]) continue;\n        \n        for (const auto& e : adj[u]) {\n            if (edge_day_arr[e.id] == repair_day) continue;\n            int vd = d + e.weight;\n            if (vis[e.to] != timer || vd < dists[e.to]) {\n                dists[e.to] = vd;\n                vis[e.to] = timer;\n                pq.push({vd, e.to});\n            }\n        }\n    }\n}\n\n/**\n * Proxy for day's frustration: sum over source nodes of path distance increases.\n */\nlong long compute_frustration(int day) {\n    long long total = 0;\n    for (int i = 0; i < (int)sources.size(); ++i) {\n        dijkstra(sources[i], day);\n        for (int j = 1; j <= N; ++j) {\n            int d_orig = base_dists[i][j];\n            int d_new = (vis[j] == timer) ? min(dists[j], INF_VAL) : INF_VAL;\n            total += (long long)(d_new - d_orig);\n        }\n    }\n    return total;\n}\n\nstruct EdgeInfo {\n    int id;\n    double angle;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    for (int i = 1; i <= M; ++i) {\n        cin >> edge_u[i] >> edge_v[i] >> edge_w[i];\n        adj[edge_u[i]].push_back({edge_v[i], edge_w[i], i});\n        adj[edge_v[i]].push_back({edge_u[i], edge_w[i], i});\n    }\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    mt19937 rng(1337);\n\n    // 1. Select representative source vertices for proxy scoring via FPS.\n    int S_count = 12;\n    sources.push_back(1);\n    for (int i = 1; i < S_count; ++i) {\n        int best_v = -1;\n        long long max_d = -1;\n        for (int v = 1; v <= N; ++v) {\n            long long min_d = 1e18;\n            for (int s : sources) {\n                long long d = (long long)(X[v]-X[s])*(X[v]-X[s]) + (long long)(Y[v]-Y[s])*(Y[v]-Y[s]);\n                if (d < min_d) min_d = d;\n            }\n            if (min_d > max_d) {\n                max_d = min_d;\n                best_v = v;\n            }\n        }\n        sources.push_back(best_v);\n    }\n\n    // 2. Precompute original shortest paths from sources in the full graph.\n    for (int j = 1; j <= M; j++) edge_day_arr[j] = -1;\n    for (int i = 0; i < S_count; ++i) {\n        dijkstra(sources[i], -2);\n        for (int j = 1; j <= N; ++j) {\n            base_dists[i][j] = (vis[j] == timer) ? min(dists[j], INF_VAL) : INF_VAL;\n        }\n    }\n\n    // 3. Spatially sorted initial assignment.\n    double cx = 0, cy = 0;\n    for (int i = 1; i <= N; ++i) { cx += X[i]; cy += Y[i]; }\n    cx /= N; cy /= N;\n    vector<EdgeInfo> sorted_edges(M);\n    for (int i = 1; i <= M; ++i) {\n        double mx = (X[edge_u[i]] + X[edge_v[i]]) / 2.0;\n        double my = (Y[edge_u[i]] + Y[edge_v[i]]) / 2.0;\n        sorted_edges[i-1] = {i, atan2(my - cy, mx - cx)};\n    }\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const EdgeInfo& a, const EdgeInfo& b) {\n        return a.angle < b.angle;\n    });\n\n    vector<vector<int>> day_lists(D + 1);\n    for (int i = 0; i < M; ++i) {\n        int d = (i % D) + 1;\n        edge_day_arr[sorted_edges[i].id] = d;\n        day_lists[d].push_back(sorted_edges[i].id);\n    }\n\n    // 4. Optimization Loop (Hill Climbing).\n    vector<long long> day_frust(D + 1);\n    for (int d = 1; d <= D; ++d) day_frust[d] = compute_frustration(d);\n\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    while (true) {\n        if ((++iterations & 31) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5850) break;\n        }\n\n        int d1, d2;\n        if (uniform_int_distribution<int>(0, 9)(rng) < 8) {\n            int best_d = 1;\n            for (int d = 2; d <= D; d++) if (day_frust[d] > day_frust[best_d]) best_d = d;\n            d1 = best_d;\n        } else {\n            d1 = uniform_int_distribution<int>(1, D)(rng);\n        }\n        d2 = uniform_int_distribution<int>(1, D)(rng);\n        while (d1 == d2) d2 = uniform_int_distribution<int>(1, D)(rng);\n\n        if (day_lists[d1].empty()) continue;\n\n        int op = uniform_int_distribution<int>(0, 4)(rng);\n        if (op == 0 && (int)day_lists[d2].size() < K) {\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            edge_day_arr[e1] = d2;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1; day_frust[d2] = nf2;\n                day_lists[d2].push_back(e1);\n                day_lists[d1][idx1] = day_lists[d1].back();\n                day_lists[d1].pop_back();\n            } else {\n                edge_day_arr[e1] = d1;\n            }\n        } else if (!day_lists[d2].empty()) {\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int idx2 = uniform_int_distribution<int>(0, (int)day_lists[d2].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            int e2 = day_lists[d2][idx2];\n            edge_day_arr[e1] = d2;\n            edge_day_arr[e2] = d1;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1; day_frust[d2] = nf2;\n                day_lists[d1][idx1] = e2;\n                day_lists[d2][idx2] = e1;\n            } else {\n                edge_day_arr[e1] = d1; edge_day_arr[e2] = d2;\n            }\n        }\n    }\n\n    for (int i = 1; i <= M; ++i) {\n        cout << edge_day_arr[i] << (i == M ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <chrono>\n\nusing namespace std;\n\n// Voxel coordinates in a 3D grid\nstruct Voxel {\n    int8_t x, y, z;\n};\n\n// Proper 90-degree rotations using a 3x3 matrix\nstruct Matrix {\n    int8_t m[3][3];\n    Voxel apply(const Voxel& v) const {\n        return {\n            (int8_t)(m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z),\n            (int8_t)(m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z),\n            (int8_t)(m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z)\n        };\n    }\n    // Determinant filters out reflections, keeping only proper rotations\n    int det() const {\n        return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -\n               m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) +\n               m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);\n    }\n};\n\n// All 24 rotational variants of a cube\nvector<Matrix> rotations;\nvoid generate_rotations() {\n    int p[] = {0, 1, 2};\n    do {\n        for (int sx : {-1, 1}) {\n            for (int sy : {-1, 1}) {\n                for (int sz : {-1, 1}) {\n                    Matrix mat = {{{(int8_t)(sx * (p[0] == 0)), (int8_t)(sy * (p[1] == 0)), (int8_t)(sz * (p[2] == 0))},\n                                   {(int8_t)(sx * (p[0] == 1)), (int8_t)(sy * (p[1] == 1)), (int8_t)(sz * (p[2] == 1))},\n                                   {(int8_t)(sx * (p[0] == 2)), (int8_t)(sy * (p[1] == 2)), (int8_t)(sz * (p[2] == 2))}}};\n                    if (mat.det() == 1) rotations.push_back(mat);\n                }\n            }\n        }\n    } while (next_permutation(p, p + 3));\n}\n\nint D;\nstring f[2][14], r[2][14];\nbool q_grid[2][14][14][14];\nvector<Voxel> q_voxels[2];\n\n// Structure to store and sort possible shared blocks\nstruct Potential {\n    int volume;\n    int r_idx;\n    int8_t dx, dy, dz;\n    int8_t sx, sy, sz;\n    bool operator<(const Potential& o) const {\n        return volume < o.volume;\n    }\n};\n\nbool used[2][14][14][14];\nint b_array[2][14][14][14];\nstatic int count_t[24][40][40][40];\nstatic bool in_S[14][14][14], visited[14][14][14], temp_visited[14][14][14];\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(NULL);\n    auto start_time = chrono::steady_clock::now();\n\n    if (!(cin >> D)) return 0;\n    for (int i = 0; i < 2; ++i) {\n        for (int j = 0; j < D; ++j) cin >> f[i][j];\n        for (int j = 0; j < D; ++j) cin >> r[i][j];\n        for (int x = 0; x < D; ++x) {\n            for (int y = 0; y < D; ++y) {\n                for (int z = 0; z < D; ++z) {\n                    if (f[i][z][x] == '1' && r[i][z][y] == '1') {\n                        q_grid[i][x][y][z] = true;\n                        q_voxels[i].push_back({(int8_t)x, (int8_t)y, (int8_t)z});\n                    }\n                }\n            }\n        }\n    }\n    generate_rotations();\n\n    // Mapping translations that allow voxel overlap between the two silhouette constructions\n    for (int ri = 0; ri < 24; ++ri) {\n        for (auto& v1 : q_voxels[0]) {\n            Voxel v1r = rotations[ri].apply(v1);\n            for (auto& v2 : q_voxels[1]) {\n                count_t[ri][v2.x - v1r.x + 13][v2.y - v1r.y + 13][v2.z - v1r.z + 13]++;\n            }\n        }\n    }\n\n    priority_queue<Potential> pq;\n    Voxel rv1[2744];\n    for (int ri = 0; ri < 24; ++ri) {\n        int Q1_size = q_voxels[0].size();\n        for (int i = 0; i < Q1_size; ++i) rv1[i] = rotations[ri].apply(q_voxels[0][i]);\n        for (int dx = -13; dx <= 26; ++dx) {\n            for (int dy = -13; dy <= 26; ++dy) {\n                for (int dz = -13; dz <= 26; ++dz) {\n                    if (count_t[ri][dx + 13][dy + 13][dz + 13] < 2) continue;\n                    vector<Voxel> S;\n                    for (int i = 0; i < Q1_size; ++i) {\n                        int nx = rv1[i].x + dx, ny = rv1[i].y + dy, nz = rv1[i].z + dz;\n                        if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && q_grid[1][nx][ny][nz]) {\n                            in_S[q_voxels[0][i].x][q_voxels[0][i].y][q_voxels[0][i].z] = true;\n                            S.push_back(q_voxels[0][i]);\n                        }\n                    }\n                    for (auto& start_v : S) {\n                        if (!visited[start_v.x][start_v.y][start_v.z]) {\n                            int count = 0; queue<Voxel> q; q.push(start_v); visited[start_v.x][start_v.y][start_v.z] = true;\n                            while (!q.empty()) {\n                                Voxel curr = q.front(); q.pop(); count++;\n                                int di[] = {-1, 1, 0, 0, 0, 0}, dj[] = {0, 0, -1, 1, 0, 0}, dk[] = {0, 0, 0, 0, -1, 1};\n                                for (int d = 0; d < 6; ++d) {\n                                    int nx = curr.x + di[d], ny = curr.y + dj[d], nz = curr.z + dk[d];\n                                    if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && in_S[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                        visited[nx][ny][nz] = true; q.push({(int8_t)nx, (int8_t)ny, (int8_t)nz});\n                                    }\n                                }\n                            }\n                            if (count >= 2) pq.push({count, ri, (int8_t)dx, (int8_t)dy, (int8_t)dz, start_v.x, start_v.y, start_v.z});\n                        }\n                    }\n                    for (auto& v : S) { in_S[v.x][v.y][v.z] = false; visited[v.x][v.y][v.z] = false; }\n                }\n            }\n        }\n    }\n\n    int block_id = 1;\n    while (!pq.empty()) {\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration<double>(current_time - start_time).count() > 5.5) break;\n\n        Potential p = pq.top(); pq.pop();\n        if (used[0][p.sx][p.sy][p.sz]) continue;\n        Matrix rot = rotations[p.r_idx];\n        Voxel v2_start = rot.apply({p.sx, p.sy, p.sz}); v2_start.x += p.dx; v2_start.y += p.dy; v2_start.z += p.dz;\n        if (used[1][v2_start.x][v2_start.y][v2_start.z]) continue;\n        \n        vector<Voxel> comp; queue<Voxel> q; q.push({p.sx, p.sy, p.sz});\n        vector<Voxel> visited_voxels;\n        temp_visited[p.sx][p.sy][p.sz] = true; visited_voxels.push_back({p.sx, p.sy, p.sz});\n        while (!q.empty()) {\n            Voxel v1 = q.front(); q.pop(); comp.push_back(v1);\n            int di[] = {-1, 1, 0, 0, 0, 0}, dj[] = {0, 0, -1, 1, 0, 0}, dk[] = {0, 0, 0, 0, -1, 1};\n            for (int d = 0; d < 6; ++d) {\n                int nx = v1.x + di[d], ny = v1.y + dj[d], nz = v1.z + dk[d];\n                if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D && q_grid[0][nx][ny][nz] && !used[0][nx][ny][nz] && !temp_visited[nx][ny][nz]) {\n                    Voxel nv2 = rot.apply({(int8_t)nx, (int8_t)ny, (int8_t)nz}); nv2.x += p.dx; nv2.y += p.dy; nv2.z += p.dz;\n                    if (nv2.x >= 0 && nv2.x < D && nv2.y >= 0 && nv2.y < D && nv2.z >= 0 && nv2.z < D && q_grid[1][nv2.x][nv2.y][nv2.z] && !used[1][nv2.x][nv2.y][nv2.z]) {\n                        temp_visited[nx][ny][nz] = true; visited_voxels.push_back({(int8_t)nx, (int8_t)ny, (int8_t)nz}); q.push({(int8_t)nx, (int8_t)ny, (int8_t)nz});\n                    }\n                }\n            }\n        }\n        if (comp.size() >= 2) {\n            for (auto& v1 : comp) {\n                used[0][v1.x][v1.y][v1.z] = true; b_array[0][v1.x][v1.y][v1.z] = block_id;\n                Voxel v2 = rot.apply(v1); v2.x += p.dx; v2.y += p.dy; v2.z += p.dz;\n                used[1][v2.x][v2.y][v2.z] = true; b_array[1][v2.x][v2.y][v2.z] = block_id;\n            }\n            block_id++;\n        }\n        for (auto& v : visited_voxels) temp_visited[v.x][v.y][v.z] = false;\n    }\n\n    // Assign remaining voxels as shared single-unit blocks if possible, or non-shared single-unit blocks\n    vector<Voxel> rem[2];\n    for (int i = 0; i < 2; ++i) {\n        bool sil_covered_f[14][14] = {false}, sil_covered_r[14][14] = {false};\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z) if(b_array[i][x][y][z]>0) { sil_covered_f[z][x]=true; sil_covered_r[z][y]=true; }\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x) if (f[i][z][x] == '1' && !sil_covered_f[z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y) if (r[i][z][y] == '1' && !sil_covered_r[z][y]) Y.push_back(y);\n            if (X.empty() && Y.empty()) continue;\n            int any_x = -1, any_y = -1;\n            for (int x = 0; x < D; ++x) if (f[i][z][x] == '1') any_x = x;\n            for (int y = 0; y < D; ++y) if (r[i][z][y] == '1') any_y = y;\n            for (int j = 0; j < max((int)X.size(), (int)Y.size()); ++j) {\n                int x = (j < (int)X.size()) ? X[j] : any_x;\n                int y = (j < (int)Y.size()) ? Y[j] : any_y;\n                if (!used[i][x][y][z]) { rem[i].push_back({(int8_t)x, (int8_t)y, (int8_t)z}); used[i][x][y][z] = true; }\n            }\n        }\n    }\n    int n_shared = min(rem[0].size(), rem[1].size());\n    for (int i = 0; i < n_shared; ++i) {\n        b_array[0][rem[0][i].x][rem[0][i].y][rem[0][i].z] = block_id;\n        b_array[1][rem[1][i].x][rem[1][i].y][rem[1][i].z] = block_id;\n        block_id++;\n    }\n    for (int i = n_shared; i < (int)rem[0].size(); ++i) b_array[0][rem[0][i].x][rem[0][i].y][rem[0][i].z] = block_id++;\n    for (int i = n_shared; i < (int)rem[1].size(); ++i) b_array[1][rem[1][i].x][rem[1][i].y][rem[1][i].z] = block_id++;\n\n    cout << block_id - 1 << endl;\n    for (int i = 0; i < 2; ++i) {\n        for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) for (int z = 0; z < D; ++z)\n            cout << b_array[i][x][y][z] << (x == D - 1 && y == D - 1 && z == D - 1 ? \"\" : \" \");\n        cout << endl;\n    }\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\n// Struct to represent an edge in the graph\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\n// Disjoint Set Union (DSU) for connectivity\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n + 1);\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    void reset(int n) {\n        for (int i = 0; i <= n; ++i) parent[i] = i;\n    }\n};\n\n// Calculate squared Euclidean distance between two points\ninline long long dist2_pts(int x1, int y1, int x2, int y2) {\n    return (long long)(x1 - x2) * (x1 - x2) + (long long)(y1 - y2) * (y1 - y2);\n}\n\nconst long long PENALTY = 1e16;\n\nint main() {\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<pair<int, int>> vertices(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> vertices[i].first >> vertices[i].second;\n\n    vector<Edge> edges(M);\n    vector<vector<int>> adj(N + 1);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) cin >> residents[k].first >> residents[k].second;\n\n    // Floyd-Warshall for shortest path distances between all vertices\n    vector<vector<long long>> dist(N + 1, vector<long long>(N + 1, 1e15));\n    for (int i = 1; i <= N; ++i) dist[i][i] = 0;\n    for (int j = 0; j < M; ++j) {\n        dist[edges[j].u][edges[j].v] = min(dist[edges[j].u][edges[j].v], edges[j].w);\n        dist[edges[j].v][edges[j].u] = min(dist[edges[j].v][edges[j].u], edges[j].w);\n    }\n\n    for (int k = 1; k <= N; ++k)\n        for (int i = 1; i <= N; ++i)\n            for (int j = 1; j <= N; ++j)\n                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n\n    // Precompute shortest path edges for every pair of stations\n    vector<int> path_edges[101][101];\n    for (int i = 1; i <= N; ++i) {\n        for (int j = 1; j <= N; ++j) {\n            if (i == j) continue;\n            int curr = i;\n            while (curr != j) {\n                bool found = false;\n                for (int e_idx : adj[curr]) {\n                    int next = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);\n                    if (edges[e_idx].w + dist[next][j] == dist[curr][j]) {\n                        path_edges[i][j].push_back(e_idx);\n                        curr = next;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n    }\n\n    // Precompute distances and proximity rankings of vertices for each resident\n    vector<vector<long long>> dist2_v_r(N + 1, vector<long long>(K));\n    vector<vector<int>> sorted_v_for_r(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 1; i <= N; ++i) dist2_v_r[i][k] = dist2_pts(vertices[i].first, vertices[i].second, residents[k].first, residents[k].second);\n        iota(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), 1);\n        sort(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), [&](int a, int b) { return dist2_v_r[a][k] < dist2_v_r[b][k]; });\n    }\n\n    vector<int> sorted_all_edge_indices(M);\n    iota(sorted_all_edge_indices.begin(), sorted_all_edge_indices.end(), 0);\n    sort(sorted_all_edge_indices.begin(), sorted_all_edge_indices.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n\n    vector<bool> is_active(N + 1, true);\n    vector<int> nearest_v(K);\n    for (int k = 0; k < K; ++k) nearest_v[k] = sorted_v_for_r[k][0];\n\n    auto start_time = chrono::steady_clock::now();\n    static long long max_d2[101];\n    static int v_req_list[101], prim_parent[101], edge_used_at[301] = {0}, ts = 0;\n    static long long prim_min_d[101];\n    static bool prim_visited[101];\n    DSU tree_dsu(N);\n\n    // Accurate cost estimation used in SA\n    auto get_total_cost = [&]() {\n        for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n        for (int k = 0; k < K; ++k) max_d2[nearest_v[k]] = max(max_d2[nearest_v[k]], dist2_v_r[nearest_v[k]][k]);\n\n        long long coverage_cost = 0;\n        int n_req = 0;\n        v_req_list[n_req++] = 1;\n        for (int i = 1; i <= N; ++i) {\n            if (max_d2[i] > 0) {\n                if (i != 1) v_req_list[n_req++] = i;\n                if (max_d2[i] > 25000000LL) coverage_cost += PENALTY;\n                else {\n                    long long p = (long long)sqrt(max_d2[i]);\n                    while (p * p < max_d2[i]) p++;\n                    coverage_cost += p * p;\n                }\n            }\n        }\n\n        long long tree_cost = 0;\n        if (n_req > 1) {\n            for (int i = 0; i < n_req; ++i) { prim_min_d[i] = 1e16; prim_visited[i] = false; }\n            prim_min_d[0] = 0; prim_parent[0] = -1;\n            ts++;\n            for (int i = 0; i < n_req; ++i) {\n                int u = -1;\n                for (int j = 0; j < n_req; ++j) if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n                if (u == -1) break;\n                prim_visited[u] = true;\n                if (prim_parent[u] != -1) {\n                    for (int e_id : path_edges[v_req_list[u]][v_req_list[prim_parent[u]]]) edge_used_at[e_id] = ts;\n                }\n                for (int v = 0; v < n_req; ++v) if (!prim_visited[v]) {\n                    long long d = dist[v_req_list[u]][v_req_list[v]];\n                    if (d < prim_min_d[v]) { prim_min_d[v] = d; prim_parent[v] = u; }\n                }\n            }\n            tree_dsu.reset(N);\n            for (int e_idx : sorted_all_edge_indices) {\n                if (edge_used_at[e_idx] == ts) {\n                    if (tree_dsu.unite(edges[e_idx].u, edges[e_idx].v)) tree_cost += edges[e_idx].w;\n                }\n            }\n        }\n        return coverage_cost + tree_cost;\n    };\n\n    long long cur_cost = get_total_cost(), best_cost = cur_cost;\n    vector<bool> best_is_active = is_active;\n    mt19937 rng(42);\n    uniform_real_distribution<double> dist_unif(0, 1);\n    uniform_int_distribution<int> dist_v(2, N);\n\n    double T_start = 1e7, T_end = 1e4;\n    int iter = 0;\n    while (true) {\n        if ((iter & 511) == 0) {\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > 1850.0) break;\n        }\n        iter++;\n        int v = dist_v(rng);\n        bool was_active = is_active[v];\n        is_active[v] = !was_active;\n        vector<pair<int, int>> changes;\n        if (is_active[v]) {\n            for (int k = 0; k < K; ++k) if (dist2_v_r[v][k] < dist2_v_r[nearest_v[k]][k]) { changes.push_back({k, nearest_v[k]}); nearest_v[k] = v; }\n        } else {\n            for (int k = 0; k < K; ++k) if (nearest_v[k] == v) {\n                changes.push_back({k, v});\n                for (int nv : sorted_v_for_r[k]) if (is_active[nv]) { nearest_v[k] = nv; break; }\n            }\n        }\n        long long next_cost = get_total_cost();\n        double elapsed_inner = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n        double T = T_start * pow(T_end / T_start, elapsed_inner / 1850.0);\n        if (next_cost < cur_cost || dist_unif(rng) < exp((double)(cur_cost - next_cost) / T)) {\n            cur_cost = next_cost;\n            if (cur_cost < best_cost) { best_cost = cur_cost; best_is_active = is_active; }\n        } else {\n            is_active[v] = was_active;\n            for (auto& p : changes) nearest_v[p.first] = p.second;\n        }\n    }\n\n    // Reconstruction phase with greedy radius refinement\n    is_active = best_is_active;\n    for (int k = 0; k < K; ++k) for (int nv : sorted_v_for_r[k]) if (is_active[nv]) { nearest_v[k] = nv; break; }\n    for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n    for (int k = 0; k < K; ++k) max_d2[nearest_v[k]] = max(max_d2[nearest_v[k]], dist2_v_r[nearest_v[k]][k]);\n    int n_req = 0; v_req_list[n_req++] = 1;\n    for (int i = 2; i <= N; ++i) if (max_d2[i] > 0) v_req_list[n_req++] = i;\n    vector<int> final_B(M, 0);\n    if (n_req > 1) {\n        ts++;\n        for (int i = 0; i < n_req; ++i) { prim_min_d[i] = 1e16; prim_visited[i] = false; }\n        prim_min_d[0] = 0; prim_parent[0] = -1;\n        for (int i = 0; i < n_req; ++i) {\n            int u = -1;\n            for (int j = 0; j < n_req; ++j) if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n            if (u == -1) break;\n            prim_visited[u] = true;\n            if (prim_parent[u] != -1) {\n                for (int e_id : path_edges[v_req_list[u]][v_req_list[prim_parent[u]]]) edge_used_at[e_id] = ts;\n            }\n            for (int v = 0; v < n_req; ++v) if (!prim_visited[v]) {\n                long long d = dist[v_req_list[u]][v_req_list[v]];\n                if (d < prim_min_d[v]) { prim_min_d[v] = d; prim_parent[v] = u; }\n            }\n        }\n        tree_dsu.reset(N);\n        for (int e_idx : sorted_all_edge_indices) if (edge_used_at[e_idx] == ts) {\n            if (tree_dsu.unite(edges[e_idx].u, edges[e_idx].v)) final_B[e_idx] = 1;\n        }\n    }\n    vector<int> reach; vector<int> q_vec = {1}; vector<bool> vis_vec(N + 1, false); vis_vec[1] = true;\n    int h_idx = 0;\n    while(h_idx < (int)q_vec.size()){\n        int u_node = q_vec[h_idx++]; reach.push_back(u_node);\n        for(int e_idx : adj[u_node]) if(final_B[e_idx]){\n            int v_node = (edges[e_idx].u == u_node ? edges[e_idx].v : edges[e_idx].u);\n            if(!vis_vec[v_node]) { vis_vec[v_node] = true; q_vec.push_back(v_node); }\n        }\n    }\n    vector<long long> f_max_d2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        long long md = 8e18; int bv = -1;\n        for (int v_node : reach) { long long d = dist2_v_r[v_node][k]; if (d < md) { md = d; bv = v_node; } }\n        if (bv != -1) f_max_d2[bv] = max(f_max_d2[bv], md);\n    }\n    vector<int> final_P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) if (f_max_d2[i] > 0) {\n        long long p_val = (long long)sqrt(f_max_d2[i]);\n        while (p_val * p_val < f_max_d2[i]) p_val++;\n        final_P[i] = (int)p_val;\n    }\n    while (true) {\n        bool changed_flag = false; vector<int> d_deg(N + 1, 0);\n        for (int j = 0; j < M; ++j) if (final_B[j]) { d_deg[edges[j].u]++; d_deg[edges[j].v]++; }\n        for (int i = 2; i <= N; ++i) if (d_deg[i] == 1 && final_P[i] == 0) {\n            for (int j = 0; j < M; ++j) if (final_B[j] && (edges[j].u == i || edges[j].v == i)) { final_B[j] = 0; changed_flag = true; break; }\n        }\n        if (!changed_flag) break;\n    }\n    for (int i = 1; i <= N; ++i) cout << min(final_P[i], 5000) << (i == N ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) cout << final_B[j] << (j == M - 1 ? \"\" : \" \");\n    cout << endl;\n    return 0;\n}\n","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Pyramid dimension: The problem fixes N=30 for all inputs.\nconst int N = 30;\n// Total number of balls: N(N+1)/2 = 465.\nconst int NUM_BALLS = N * (N + 1) / 2;\n\n// Structure to store a single swap operation's coordinates.\nstruct Move {\n    int x1, y1, x2, y2;\n};\n\n// Global arrays for storing pyramid state and ball positions.\nint initial_pyramid[N][N];\nint pyramid[N][N];\nint pos_x[NUM_BALLS];\nint pos_y[NUM_BALLS];\nint ideal_row[NUM_BALLS];\n\n// Precompute the \"ideal\" row for each ball value (0 to 464).\n// Since values are unique and heap property implies sorting by depth,\n// value v belongs in row r such that r(r+1)/2 <= v < (r+1)(r+2)/2.\nvoid precompute_ideal_rows() {\n    for (int v = 0; v < NUM_BALLS; ++v) {\n        ideal_row[v] = (int)((sqrt(8.0 * v + 1.0) - 1.0) / 2.0);\n    }\n}\n\nint main() {\n    // Fast I/O to handle 10,000 potential output lines quickly.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial pyramid configuration from stdin.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> initial_pyramid[i][j])) break;\n        }\n    }\n\n    precompute_ideal_rows();\n\n    auto start_time = chrono::high_resolution_clock::now();\n    // Fixed seed for reproducible behavior across multiple simulation runs.\n    mt19937 rng(1337);\n\n    vector<Move> best_moves;\n    int min_K = 10001; // Maximum allowed swap operations is 10,000.\n\n    int trials = 0;\n    // Perform randomized simulations until the 2.0s time limit is almost reached.\n    while (true) {\n        trials++;\n        // Check elapsed time periodically.\n        if ((trials & 63) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n        }\n\n        // Reset the current pyramid state for each new simulation trial.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j <= i; ++j) {\n                pyramid[i][j] = initial_pyramid[i][j];\n                pos_x[pyramid[i][j]] = i;\n                pos_y[pyramid[i][j]] = j;\n            }\n        }\n\n        vector<Move> current_moves;\n        int current_K = 0;\n\n        // Introduce randomization into the choice of heuristic direction and weights.\n        bool is_bubble_up = (rng() % 2 == 0);\n        double alpha = uniform_real_distribution<double>(0.0, 60.0)(rng);\n        double noise_val = uniform_real_distribution<double>(0.0, 30.0)(rng);\n\n        if (is_bubble_up) {\n            // Strategy 1: Systematic Bubble-Up. Process balls from smallest to largest value.\n            // Move value v up toward row 0 as long as it is smaller than its parents.\n            for (int v = 0; v < NUM_BALLS; ++v) {\n                while (true) {\n                    int x = pos_x[v], y = pos_y[v];\n                    if (x == 0) break; // Cannot bubble up from top tier.\n\n                    // Identify potential parents in row above.\n                    int p1x = x - 1, p1y = y - 1, p2x = x - 1, p2y = y;\n                    int v1 = (p1y >= 0) ? pyramid[p1x][p1y] : -1;\n                    int v2 = (p2y <= x - 1) ? pyramid[p2x][p2y] : -1;\n\n                    bool p1_violates = (v1 > v);\n                    bool p2_violates = (v2 > v);\n                    // Satisfied locally if both parents are already smaller than v.\n                    if (!p1_violates && !p2_violates) break;\n\n                    int tx, ty;\n                    if (p1_violates && p2_violates) {\n                        // Heuristic: pick the parent that is \"most out of place\" or has a larger value to move down.\n                        double s1 = v1 + alpha * (ideal_row[v1] - p1x) + uniform_real_distribution<double>(0, noise_val)(rng);\n                        double s2 = v2 + alpha * (ideal_row[v2] - p2x) + uniform_real_distribution<double>(0, noise_val)(rng);\n                        if (s1 > s2) { tx = p1x; ty = p1y; }\n                        else { tx = p2x; ty = p2y; }\n                    } else if (p1_violates) {\n                        tx = p1x; ty = p1y;\n                    } else {\n                        tx = p2x; ty = p2y;\n                    }\n\n                    int other_v = pyramid[tx][ty];\n                    swap(pyramid[x][y], pyramid[tx][ty]);\n                    pos_x[v] = tx; pos_y[v] = ty;\n                    pos_x[other_v] = x; pos_y[other_v] = y;\n                    current_moves.push_back({x, y, tx, ty});\n                    current_K++;\n                    if (current_K >= min_K) break;\n                }\n                if (current_K >= min_K) break;\n            }\n        } else {\n            // Strategy 2: Systematic Sink-Down. Process balls from largest to smallest value.\n            // Move value v down toward the bottom row as long as it is larger than its children.\n            for (int v = NUM_BALLS - 1; v >= 0; --v) {\n                while (true) {\n                    int x = pos_x[v], y = pos_y[v];\n                    if (x == N - 1) break; // Cannot sink down from bottom tier.\n\n                    // Identify potential children in row below.\n                    int c1x = x + 1, c1y = y, c2x = x + 1, c2y = y + 1;\n                    int v1 = (c1y <= c1x) ? pyramid[c1x][c1y] : 1000;\n                    int v2 = (c2y <= c2x) ? pyramid[c2x][c2y] : 1000;\n\n                    bool c1_violates = (v1 < v);\n                    bool c2_violates = (v2 < v);\n                    // Satisfied locally if both children are already larger than v.\n                    if (!c1_violates && !c2_violates) break;\n\n                    int tx, ty;\n                    if (c1_violates && c2_violates) {\n                        // Heuristic: pick the child that is \"more out of place\" or has a smaller value to move up.\n                        double s1 = v1 + alpha * (ideal_row[v1] - c1x) - uniform_real_distribution<double>(0, noise_val)(rng);\n                        double s2 = v2 + alpha * (ideal_row[v2] - c2x) - uniform_real_distribution<double>(0, noise_val)(rng);\n                        if (s1 < s2) { tx = c1x; ty = c1y; }\n                        else { tx = c2x; ty = c2y; }\n                    } else if (c1_violates) {\n                        tx = c1x; ty = c1y;\n                    } else {\n                        tx = c2x; ty = c2y;\n                    }\n\n                    int other_v = pyramid[tx][ty];\n                    swap(pyramid[x][y], pyramid[tx][ty]);\n                    pos_x[v] = tx; pos_y[v] = ty;\n                    pos_x[other_v] = x; pos_y[other_v] = y;\n                    current_moves.push_back({x, y, tx, ty});\n                    current_K++;\n                    if (current_K >= min_K) break;\n                }\n                if (current_K >= min_K) break;\n            }\n        }\n\n        // Store the sequence of moves if it is the best found so far.\n        if (current_K < min_K) {\n            min_K = current_K;\n            best_moves = current_moves;\n        }\n    }\n\n    // Output result: Total operations followed by coordinates for each swap.\n    cout << best_moves.size() << \"\\n\";\n    for (const auto& m : best_moves) {\n        cout << m.x1 << \" \" << m.y1 << \" \" << m.x2 << \" \" << m.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// Warehouse dimensions and constants\nconst int D = 9;\nconst int ENTRANCE_I = 0;\nconst int ENTRANCE_J = 4; // Center of the northernmost row\n\n// Represents a square in the DxD warehouse grid\nstruct Square {\n    int i, j;\n    bool operator<(const Square& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Square& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint V[D][D];         // Storage/Removal priority rank (higher = deeper, remove later)\nbool obstacle[D][D]; // Grid status: true if square is an obstacle\nint grid[D][D];      // Current grid state: -3=entrance, -2=obstacle, -1=empty, >=0=container ID\n\n/**\n * Precalculates the ideal removal order (V ranks) for each storage square.\n * This simulation identifies squares that can be removed as \"leaves\" (not blocking others)\n * and assigns them higher ranks based on their distance from the entrance.\n */\nvoid precalculate_V(int M) {\n    int dist_bfs[D][D];\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) dist_bfs[i][j] = -1;\n\n    // Initial BFS to calculate minimal distance from the entrance for all squares\n    queue<Square> q;\n    q.push({ENTRANCE_I, ENTRANCE_J});\n    dist_bfs[ENTRANCE_I][ENTRANCE_J] = 0;\n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n    while (!q.empty()) {\n        Square curr = q.front(); q.pop();\n        for (int k = 0; k < 4; ++k) {\n            int ni = curr.i + di[k], nj = curr.j + dj[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && dist_bfs[ni][nj] == -1) {\n                dist_bfs[ni][nj] = dist_bfs[curr.i][curr.j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Determine the ideal sequence of retrieval using a greedy approach\n    set<Square> E_v;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j)\n            if (!obstacle[i][j] && !(i == ENTRANCE_I && j == ENTRANCE_J)) E_v.insert({i, j});\n\n    // We simulate retrieval in reverse order (M-1 down to 0) to assign ranks\n    for (int k = M - 1; k >= 0; --k) {\n        Square best_s = {-1, -1};\n        int max_score = -1;\n        for (auto const& s : E_v) {\n            // Check connectivity: removing square 's' shouldn't isolate any other empty square\n            int count = 0;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int ni = curr.i + di[d], nj = curr.j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && \n                        E_v.count({ni, nj}) && !visited[ni][nj] && !(ni == s.i && nj == s.j)) {\n                        visited[ni][nj] = true;\n                        q_safe.push({ni, nj});\n                        count++;\n                    }\n                }\n            }\n            if (count == (int)E_v.size() - 1) {\n                // Tie-breaker prioritizing deeper/further squares for higher ranks\n                int score = dist_bfs[s.i][s.j] * 1000 + abs(s.j - ENTRANCE_J) * 10 + s.i;\n                if (score > max_score) { max_score = score; best_s = s; }\n            }\n        }\n        if (best_s.i != -1) {\n            V[best_s.i][best_s.j] = k;\n            E_v.erase(best_s);\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) obstacle[i][j] = false;\n    for (int i = 0; i < N; ++i) {\n        int r, c; cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n\n    int M = D * D - 1 - N; // Total containers\n    precalculate_V(M);\n\n    vector<int> remaining_t;\n    for (int i = 0; i < M; ++i) remaining_t.push_back(i);\n\n    set<Square> E; // Set of currently empty storage squares\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == ENTRANCE_I && j == ENTRANCE_J) grid[i][j] = -3;\n            else if (obstacle[i][j]) grid[i][j] = -2;\n            else { grid[i][j] = -1; E.insert({i, j}); }\n        }\n    }\n\n    // 1. Online Storage Phase\n    for (int d = 0; d < M; ++d) {\n        int t_d; cin >> t_d;\n        int t_rank = 0;\n        for (int t : remaining_t) if (t < t_d) t_rank++;\n\n        // Find all reachable empty squares that are also \"safe\" (not blocking others)\n        vector<Square> safe_reachable;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n        for (auto const& s : E) {\n            int count = 0;\n            bool s_reachable = false;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int ni = curr.i + di[k], nj = curr.j + dj[k];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] != -2 && !visited[ni][nj]) {\n                        if (ni == s.i && nj == s.j) { s_reachable = true; visited[ni][nj] = true; }\n                        else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                            visited[ni][nj] = true; q_safe.push({ni, nj});\n                            if (grid[ni][nj] == -1) count++;\n                        }\n                    }\n                }\n            }\n            if (s_reachable && count == (int)E.size() - 1) safe_reachable.push_back(s);\n        }\n\n        // Match the current container's rank to the available storage square ranks\n        Square best_s = {-1, -1};\n        int min_diff = 1e9;\n        for (auto const& s : safe_reachable) {\n            int v_rank = 0;\n            for (auto const& other : E) if (V[other.i][other.j] < V[s.i][s.j]) v_rank++;\n            if (abs(v_rank - t_rank) < min_diff) { min_diff = abs(v_rank - t_rank); best_s = s; }\n            else if (abs(v_rank - t_rank) == min_diff) {\n                if (best_s.i == -1 || V[s.i][s.j] > V[best_s.i][best_s.j]) best_s = s;\n            }\n        }\n        if (best_s.i == -1) best_s = *E.begin(); // Safety fallback\n\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = t_d;\n        E.erase(best_s);\n        remaining_t.erase(find(remaining_t.begin(), remaining_t.end(), t_d));\n    }\n\n    // 2. Offline Removal Phase\n    for (int d = 0; d < M; ++d) {\n        vector<Square> reachable_containers;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<Square> q;\n        q.push({ENTRANCE_I, ENTRANCE_J});\n        visited[ENTRANCE_I][ENTRANCE_J] = true;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n        while (!q.empty()) {\n            Square curr = q.front(); q.pop();\n            for (int k = 0; k < 4; ++k) {\n                int ni = curr.i + di[k], nj = curr.j + dj[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] != -2) {\n                    if (grid[ni][nj] >= 0) {\n                        reachable_containers.push_back({ni, nj});\n                        visited[ni][nj] = true;\n                    } else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        Square best_s = {-1, -1};\n        int min_t = 1e9;\n        for (auto const& s : reachable_containers) {\n            if (grid[s.i][s.j] < min_t) { min_t = grid[s.i][s.j]; best_s = s; }\n        }\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = -1; // Mark square as empty for future retrieval paths\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Takahashi City grid size is fixed to 50x50 and number of wards is 100.\nconst int N = 50;\nconst int M = 100;\n\nint original_grid[N][N];\nint current_grid[N][N];\nint best_grid[N][N];\nint E[M + 1][M + 1];\nint ward_size[M + 1];\nbool original_adj[M + 1][M + 1];\nbool is_locked[N][N];\nint dx[] = {0, 0, 1, -1};\nint dy[] = {1, -1, 0, 0};\n\n// Static structures for BFS connectivity checks.\nint vis[N][N];\nint vis_token = 0;\npair<int, int> q_arr[N * N];\n\n/**\n * Helper to get grid color, returning 0 (outside) for out-of-bounds coordinates.\n */\ninline int get_color(int r, int c) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return 0;\n    return current_grid[r][c];\n}\n\n/**\n * Checks if a ward (color c_old) remains connected if square (r, c) is removed.\n * Ensures that all same-colored neighbors of (r, c) can still reach each other.\n */\nbool check_connectivity(int r, int c, int c_old, const vector<pair<int, int>>& neighbors) {\n    if (neighbors.size() <= 1) return true;\n    vis_token++;\n    int head = 0, tail = 0;\n    q_arr[tail++] = neighbors[0];\n    vis[neighbors[0].first][neighbors[0].second] = vis_token;\n    vis[r][c] = vis_token; // Act as a wall (as square (r, c) will be changed to 0).\n\n    int found_count = 1;\n    while (head < tail) {\n        pair<int, int> curr = q_arr[head++];\n        for (int k = 0; k < 4; k++) {\n            int ni = curr.first + dx[k], nj = curr.second + dy[k];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && current_grid[ni][nj] == c_old && vis[ni][nj] != vis_token) {\n                vis[ni][nj] = vis_token;\n                q_arr[tail++] = {ni, nj};\n                for (auto& neighbor : neighbors) {\n                    if (ni == neighbor.first && nj == neighbor.second) {\n                        found_count++;\n                        break;\n                    }\n                }\n                // Stop BFS early if all target neighbor squares are reached.\n                if (found_count == (int)neighbors.size()) return true;\n            }\n        }\n    }\n    return false;\n}\n\n/**\n * Validates if square (r, c) can be changed to color 0 without violating connectivity or adjacency rules.\n */\nbool can_remove(int r, int c) {\n    int c_old = current_grid[r][c];\n    if (ward_size[c_old] <= 1) return false;\n\n    // Constraint: Color 0 must remain connected.\n    // Ensure the new 0-tile is part of a component that touches the boundary.\n    bool next_to_0 = false;\n    if (r == 0 || r == N - 1 || c == 0 || c == N - 1) next_to_0 = true;\n    else {\n        for (int k = 0; k < 4; k++) {\n            if (current_grid[r + dx[k]][c + dy[k]] == 0) {\n                next_to_0 = true;\n                break;\n            }\n        }\n    }\n    if (!next_to_0) return false;\n\n    // Check ward-ward and ward-0 adjacency constraints.\n    vector<pair<int, int>> c_old_neighbors;\n    int neighbor_wards[4];\n    int edges_to_ward[4];\n    int num_neighbor_wards = 0;\n\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c + dy[k];\n        int d = get_color(ni, nj);\n        if (d == c_old) {\n            c_old_neighbors.push_back({ni, nj});\n        } else if (d > 0) {\n            int found_idx = -1;\n            for (int j = 0; j < num_neighbor_wards; j++) {\n                if (neighbor_wards[j] == d) { found_idx = j; break; }\n            }\n            if (found_idx == -1) {\n                neighbor_wards[num_neighbor_wards] = d;\n                edges_to_ward[num_neighbor_wards] = 1;\n                num_neighbor_wards++;\n            } else {\n                edges_to_ward[found_idx]++;\n            }\n        }\n    }\n\n    // Ensure ward-ward adjacencies are not lost.\n    for (int j = 0; j < num_neighbor_wards; j++) {\n        if (E[c_old][neighbor_wards[j]] - edges_to_ward[j] <= 0) return false;\n    }\n\n    // Ensure ward c_old remains connected.\n    return check_connectivity(r, c, c_old, c_old_neighbors);\n}\n\n/**\n * Updates the current grid and global adjacency tallies.\n */\nvoid remove_and_update(int r, int c) {\n    int c_old = current_grid[r][c];\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c + dy[k];\n        int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : current_grid[ni][nj];\n        E[c_old][d]--;\n        E[d][c_old]--;\n        E[0][d]++;\n        E[d][0]++;\n    }\n    current_grid[r][c] = 0;\n    ward_size[c_old]--;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> original_grid[i][j];\n\n    // Calculate original ward-to-ward adjacencies.\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 + dx[k], nj = j + dy[k];\n                int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : original_grid[ni][nj];\n                original_adj[c][d] = true;\n                original_adj[d][c] = true;\n            }\n        }\n    }\n\n    // Identify squares that can never be turned into 0 due to adjacency constraints.\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int c = original_grid[i][j];\n            is_locked[i][j] = false;\n            // A square is locked if its ward or any neighbor ward was not originally adjacent to 0.\n            if (!original_adj[c][0]) is_locked[i][j] = true;\n            else {\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dx[k], nj = j + dy[k];\n                    int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : original_grid[ni][nj];\n                    if (d > 0 && d != c && !original_adj[d][0]) {\n                        is_locked[i][j] = true;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> candidate_coords;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!is_locked[i][j]) candidate_coords.push_back({i, j});\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(1337);\n    int best_E_count = -1;\n\n    // Restart the greedy search from the original grid within the time limit.\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        // Initialize current state.\n        for (int i = 0; i <= M; i++) {\n            ward_size[i] = 0;\n            for (int j = 0; j <= M; j++) E[i][j] = 0;\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                current_grid[i][j] = original_grid[i][j];\n                ward_size[current_grid[i][j]]++;\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int k = 0; k < 4; k++) {\n                    int d = get_color(i + dx[k], j + dy[k]);\n                    E[current_grid[i][j]][d]++;\n                }\n            }\n        }\n\n        // Apply greedy removals until a local optimum is reached.\n        while (true) {\n            shuffle(candidate_coords.begin(), candidate_coords.end(), rng);\n            bool changed_any = false;\n            for (auto& p : candidate_coords) {\n                if (current_grid[p.first][p.second] != 0 && can_remove(p.first, p.second)) {\n                    remove_and_update(p.first, p.second);\n                    changed_any = true;\n                }\n            }\n            if (!changed_any) break;\n        }\n\n        int current_E_count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) if (current_grid[i][j] == 0) current_E_count++;\n        }\n\n        if (current_E_count > best_E_count) {\n            best_E_count = current_E_count;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) best_grid[i][j] = current_grid[i][j];\n        }\n    }\n\n    // Output the grid with the maximum number of 0 squares.\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_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 Strategy:\n * 1. Initial Sorting: Perform a partial or complete MergeSort to establish an initial item-weight order.\n * 2. Weight Estimation: Initialize weights using the expected order statistics of an exponential distribution.\n * 3. Iterative Refinement: Use remaining balance queries to compare the most unbalanced sets.\n * 4. Constraint Enforcement: If a query contradicts estimates, adjust the weights and apply Isotonic Regression\n *    to maintain the established weight order.\n * 5. Multi-way Partitioning: Use Hill Climbing to minimize the variance among the final sets.\n */\n\nint N, D, Q;\nint q_count = 0;\n\n// Standard balance query function. Increments global query counter.\nchar query(const vector<int>& L, const vector<int>& R) {\n    if (q_count >= Q) return '=';\n    q_count++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res;\n    if (!(cin >> res)) exit(0);\n    return res;\n}\n\nvector<int> sorted_items;\n\n// Isotonic Regression (Pool Adjacent Violators) variant to maintain weight ordering.\nvoid isotonic_regression(vector<double>& w) {\n    for (int it = 0; it < 100; ++it) {\n        bool changed = false;\n        for (int i = 0; i < N - 1; ++i) {\n            int u = sorted_items[i], v = sorted_items[i+1];\n            if (w[u] > w[v]) {\n                double avg = (w[u] + w[v]) / 2.0;\n                w[u] = w[v] = avg;\n                changed = true;\n            }\n        }\n        if (!changed) break;\n    }\n}\n\n// MergeSort components to sort items within a query limit.\nvoid merge_parts(vector<int>& arr, int l, int m, int r, int Q_limit) {\n    if (q_count >= Q_limit) return;\n    vector<int> left(arr.begin() + l, arr.begin() + m);\n    vector<int> right(arr.begin() + m, arr.begin() + r);\n    int i = 0, j = 0, k = l;\n    while (i < (int)left.size() && j < (int)right.size()) {\n        if (q_count < Q_limit) {\n            char res = query({left[i]}, {right[j]});\n            if (res == '<') arr[k++] = left[i++];\n            else arr[k++] = right[j++];\n        } else {\n            arr[k++] = left[i++];\n        }\n    }\n    while (i < (int)left.size()) arr[k++] = left[i++];\n    while (j < (int)right.size()) arr[k++] = right[j++];\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r, int Q_limit) {\n    if (r - l <= 1 || q_count >= Q_limit) return;\n    int m = l + (r - l) / 2;\n    merge_sort(arr, l, m, Q_limit);\n    merge_sort(arr, m, r, Q_limit);\n    merge_parts(arr, l, m, r, Q_limit);\n}\n\n// Multi-way Number Partitioning via Hill Climbing to balance set weights.\nvoid hill_climbing(vector<vector<int>>& sets, vector<double>& set_sums, const vector<double>& hat_w, int iters, chrono::steady_clock::time_point end_time) {\n    double total_w = accumulate(hat_w.begin(), hat_w.end(), 0.0);\n    double target = total_w / D;\n    mt19937 rng(42);\n\n    for (int i = 0; i < iters; ++i) {\n        if ((i & 511) == 0 && chrono::steady_clock::now() > end_time) break;\n        int a = rng() % D;\n        int b = rng() % D;\n        if (a == b) continue;\n\n        double cur_score = pow(set_sums[a] - target, 2) + pow(set_sums[b] - target, 2);\n\n        // Move Item Strategy\n        if (sets[a].size() > 1) {\n            int idx = rng() % sets[a].size();\n            int item = sets[a][idx];\n            double ns_a = set_sums[a] - hat_w[item];\n            double ns_b = set_sums[b] + hat_w[item];\n            if (pow(ns_a - target, 2) + pow(ns_b - target, 2) < cur_score) {\n                set_sums[a] = ns_a;\n                set_sums[b] = ns_b;\n                sets[b].push_back(item);\n                sets[a][idx] = sets[a].back();\n                sets[a].pop_back();\n                continue;\n            }\n        }\n\n        // Swap Items Strategy\n        if (!sets[a].empty() && !sets[b].empty()) {\n            int idx_a = rng() % sets[a].size();\n            int idx_b = rng() % sets[b].size();\n            int item_a = sets[a][idx_a];\n            int item_b = sets[b][idx_b];\n            double ns_a = set_sums[a] - hat_w[item_a] + hat_w[item_b];\n            double ns_b = set_sums[b] - hat_w[item_b] + hat_w[item_a];\n            if (pow(ns_a - target, 2) + pow(ns_b - target, 2) < cur_score) {\n                set_sums[a] = ns_a;\n                set_sums[b] = ns_b;\n                swap(sets[a][idx_a], sets[b][idx_b]);\n            }\n        }\n    }\n}\n\nint main() {\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    sorted_items.resize(N);\n    iota(sorted_items.begin(), sorted_items.end(), 0);\n\n    // Initial Sort: Reserve space for refinement queries.\n    int Q_sort = Q - 2 * D;\n    merge_sort(sorted_items, 0, N, Q_sort);\n\n    // Initial Weights: Estimated using expected exponential order statistics.\n    vector<double> hat_w(N);\n    double cumulative = 0;\n    for (int i = 0; i < N; ++i) {\n        cumulative += 1.0 / (N - i);\n        hat_w[sorted_items[i]] = 100000.0 * cumulative;\n    }\n\n    mt19937 rng(1337);\n    while (q_count < Q) {\n        // Construct a partition using the latest weight estimates.\n        vector<vector<int>> sets(D);\n        vector<double> set_sums(D, 0);\n        vector<int> current_items = sorted_items;\n        reverse(current_items.begin(), current_items.end());\n\n        for (int item : current_items) {\n            int best_s = 0;\n            for (int j = 1; j < D; ++j) if (set_sums[j] < set_sums[best_s]) best_s = j;\n            sets[best_s].push_back(item);\n            set_sums[best_s] += hat_w[item];\n        }\n        hill_climbing(sets, set_sums, hat_w, 2000, start_time + chrono::milliseconds(1800));\n\n        // Selection: Heuristic choice of sets to compare to refine weights.\n        int a, b;\n        if (rng() % 10 < 7) {\n            a = 0, b = 0;\n            for (int i = 1; i < D; ++i) {\n                if (set_sums[i] < set_sums[a]) a = i;\n                if (set_sums[i] > set_sums[b]) b = i;\n            }\n        } else {\n            a = rng() % D;\n            b = (a + 1 + rng() % (D - 1)) % D;\n        }\n\n        if (a == b || sets[a].empty() || sets[b].empty()) {\n            query({sorted_items[0]}, {sorted_items[N - 1]});\n            continue;\n        }\n\n        char res = query(sets[a], sets[b]);\n        double est_sum_a = 0, est_sum_b = 0;\n        for (int x : sets[a]) est_sum_a += hat_w[x];\n        for (int x : sets[b]) est_sum_b += hat_w[x];\n\n        // Refine weight values if the balance result contradicts current estimates.\n        if ((res == '>' && est_sum_a < est_sum_b) || (res == '<' && est_sum_a > est_sum_b)) {\n            double factor = 1.05;\n            if (res == '>') {\n                for (int x : sets[a]) hat_w[x] *= factor;\n                for (int x : sets[b]) hat_w[x] /= factor;\n            } else {\n                for (int x : sets[a]) hat_w[x] /= factor;\n                for (int x : sets[b]) hat_w[x] *= factor;\n            }\n            isotonic_regression(hat_w);\n        }\n    }\n\n    // Final Partitioning: Large-scale optimization for the best balanced output.\n    vector<vector<int>> final_sets(D);\n    vector<double> final_set_sums(D, 0);\n    vector<int> current_items = sorted_items;\n    reverse(current_items.begin(), current_items.end());\n    for (int item : current_items) {\n        int best_s = 0;\n        for (int j = 1; j < D; ++j) if (final_set_sums[j] < final_set_sums[best_s]) best_s = j;\n        final_sets[best_s].push_back(item);\n        final_set_sums[best_s] += hat_w[item];\n    }\n    hill_climbing(final_sets, final_set_sums, hat_w, 500000, start_time + chrono::milliseconds(1950));\n\n    vector<int> ans(N);\n    for (int i = 0; i < D; ++i) {\n        for (int x : final_sets[i]) ans[x] = i;\n    }\n\n    for (int i = 0; i < N; ++i) cout << ans[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * [Problem Overview]\n * n = 200 boxes in m = 10 vertical stacks.\n * Goal: Carry out boxes 1 to n in order.\n * Operation 1: Move box v and all boxes above it to another stack i. Energy: k+1 (k boxes moved).\n * Operation 2: Carry out smallest remaining box if it's on top of its stack. Energy: 0.\n * Limit: 5000 total operations.\n * Scoring: 10000 - total energy.\n * \n * [Final Refined Strategy]\n * 1. Greedy Simulation: We simulate the entire process of carrying out boxes 1..n.\n * 2. Sub-block Splitting: To move boxes above target box v, we split the block into \n *    sub-blocks that are descending (well-ordered) to facilitate future carry-outs.\n * 3. Detailed Heuristic Scoring: For each sub-block, we evaluate all possible destination \n *    stacks and pick the one with the lowest heuristic penalty. The penalty considers:\n *    - Potential Fit: Prefer stacks where the top box is larger than the incoming block.\n *    - Future Burial Cost: Penalize placing boxes on top of boxes needed soon.\n *    - Energy estimate: Explicitly approximate future energy expenditure for buried boxes.\n * 4. Randomized Search: Run thousands of simulations with randomized parameters within \n *    the 2.0s time limit and output the best operation sequence found.\n */\n\nstruct Move {\n    int v, i;\n};\n\n// State manages the physical configuration of boxes and calculates energy costs.\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<int> box_to_stack;\n    vector<Move> moves;\n    long long energy;\n\n    State(int n, int m, const vector<vector<int>>& initial_stacks) \n        : n(n), m(m), stacks(initial_stacks), energy(0) {\n        box_to_stack.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            for (int val : stacks[i]) {\n                box_to_stack[val] = i;\n            }\n        }\n    }\n\n    // Operation 1: Move block starting at box v to dest_stack_idx.\n    void move_block(int v, int dest_stack_idx) {\n        int src_stack_idx = box_to_stack[v];\n        if (src_stack_idx == dest_stack_idx) return;\n\n        auto& src_stack = stacks[src_stack_idx];\n        auto& dest_stack = stacks[dest_stack_idx];\n\n        int pos = -1;\n        for (int i = (int)src_stack.size() - 1; i >= 0; --i) {\n            if (src_stack[i] == v) {\n                pos = i;\n                break;\n            }\n        }\n\n        int k = (int)src_stack.size() - pos;\n        energy += (k + 1);\n        moves.push_back({v, dest_stack_idx + 1});\n\n        for (int i = pos; i < (int)src_stack.size(); ++i) {\n            box_to_stack[src_stack[i]] = dest_stack_idx;\n            dest_stack.push_back(src_stack[i]);\n        }\n        src_stack.resize(pos);\n    }\n\n    // Operation 2: Remove box v from its stack.\n    void carry_out(int v) {\n        int s_idx = box_to_stack[v];\n        stacks[s_idx].pop_back();\n        moves.push_back({v, 0});\n    }\n};\n\n/**\n * calculate_score: Heuristic to evaluate destination stacks for a sub-block S.\n * Penalizes burial of urgent boxes, large stack heights, and poor fitting.\n */\ninline long long calculate_score(int n, const vector<int>& stack_d, const vector<int>& S, int v, \n                                 int wf, int ws, int wu, \n                                 int la, int tdp, int tdn, \n                                 int pb, int wes) {\n    int bottom_v = S[0]; // S is a descending block; S[0] is the largest (bottom).\n    int S_size = (int)S.size();\n    long long score = 0;\n\n    if (stack_d.empty()) {\n        score = (long long)(n - bottom_v) * tdp + wes;\n    } else {\n        int top_v = stack_d.back();\n        if (top_v > bottom_v) {\n            score = (long long)(top_v - bottom_v) * tdp;\n        } else {\n            score = (long long)pb + (long long)(bottom_v - top_v) * tdn;\n        }\n\n        // Penalize burial of any boxes in the destination stack.\n        for (int j = 0; j < (int)stack_d.size(); ++j) {\n            int x = stack_d[j];\n            if (x < bottom_v) {\n                int boxes_above_x = (int)stack_d.size() - 1 - j;\n                // Estimate future cost to retrieve box x.\n                long long future_cost = (long long)(S_size + boxes_above_x + 1);\n                score += future_cost * wf;\n                if (x > v && x <= v + la) {\n                    // High penalty for boxes needed very soon.\n                    score += future_cost * wu * (la - (x - v) + 1);\n                }\n            }\n        }\n    }\n    // Maintain balance across stacks.\n    score += (long long)stack_d.size() * ws;\n    return score;\n}\n\n// Full simulation of the extraction process.\nlong long simulate(int n, int m, const vector<vector<int>>& initial_stacks, \n                   int limit, int wf, int ws, int wu, int la, int tdp, int tdn, int pb, int wes,\n                   vector<Move>& out_moves) {\n    State state(n, m, initial_stacks);\n    for (int v = 1; v <= n; ++v) {\n        int s_idx = state.box_to_stack[v];\n        if (state.stacks[s_idx].back() != v) {\n            auto& s = state.stacks[s_idx];\n            int pos = -1;\n            for (int i = (int)s.size() - 1; i >= 0; --i) {\n                if (s[i] == v) { pos = i; break; }\n            }\n            \n            // Split above-target boxes into well-ordered sub-blocks.\n            vector<vector<int>> sub_blocks;\n            vector<int> current_S = {s[pos + 1]};\n            for (int i = pos + 2; i < (int)s.size(); ++i) {\n                if (s[i-1] < s[i] || s[i-1] - s[i] > limit) {\n                    sub_blocks.push_back(current_S);\n                    current_S = {s[i]};\n                } else {\n                    current_S.push_back(s[i]);\n                }\n            }\n            sub_blocks.push_back(current_S);\n\n            // Move each sub-block (top-most first) to its best destination stack.\n            for (int i = (int)sub_blocks.size() - 1; i >= 0; --i) {\n                const auto& S = sub_blocks[i];\n                int bottom_v = S[0];\n                int best_d = -1;\n                long long min_score = LLONG_MAX;\n                \n                for (int d = 0; d < m; ++d) {\n                    if (d == s_idx) continue;\n                    long long score = calculate_score(n, state.stacks[d], S, v, wf, ws, wu, la, tdp, tdn, pb, wes);\n                    if (score < min_score) {\n                        min_score = score;\n                        best_d = d;\n                    }\n                }\n                state.move_block(bottom_v, best_d);\n            }\n        }\n        state.carry_out(v);\n        if (state.moves.size() > 5000) return LLONG_MAX;\n    }\n    out_moves = state.moves;\n    return state.energy;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> initial_stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int b; cin >> b;\n            initial_stacks[i].push_back(b);\n        }\n    }\n\n    long long min_energy = LLONG_MAX;\n    vector<Move> best_moves;\n    mt19937 rng(1337);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Ranges for randomized parameter exploration.\n    uniform_int_distribution<int> dist_limit(1, 200);\n    uniform_int_distribution<int> dist_wf(1, 100);\n    uniform_int_distribution<int> dist_ws(0, 100);\n    uniform_int_distribution<int> dist_wu(1, 2000);\n    uniform_int_distribution<int> dist_la(1, 100);\n    uniform_int_distribution<int> dist_tdp(0, 100);\n    uniform_int_distribution<int> dist_tdn(0, 100);\n    uniform_int_distribution<int> dist_pb(100, 20000);\n    uniform_int_distribution<int> dist_wes(-5000, 5000);\n\n    // Continuous parameter search until time limit.\n    int count = 0;\n    while (true) {\n        if ((count & 127) == 0) {\n            auto current_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 1900) break;\n        }\n        count++;\n        \n        int limit = dist_limit(rng);\n        int wf = dist_wf(rng);\n        int ws = dist_ws(rng);\n        int wu = dist_wu(rng);\n        int la = dist_la(rng);\n        int tdp = dist_tdp(rng);\n        int tdn = dist_tdn(rng);\n        int pb = dist_pb(rng);\n        int wes = dist_wes(rng);\n        \n        vector<Move> current_moves;\n        long long energy = simulate(n, m, initial_stacks, limit, wf, ws, wu, la, tdp, tdn, pb, wes, current_moves);\n        if (energy < min_energy) {\n            min_energy = energy;\n            best_moves = current_moves;\n        }\n    }\n\n    for (const auto& move : best_moves) {\n        cout << move.v << \" \" << move.i << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n// Maximum size of the board as per problem description\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\n\nstruct Edge {\n    int u, v;\n};\n\n// Global structures to store the adjacency list and edges of the graph\nvector<Edge> all_edges;\nbool is_in_tree[MAXN * MAXN][MAXN * MAXN];\nint parent_in_tree[MAXN * MAXN];\nint subtree_size[MAXN * MAXN];\nvector<int> tree_adj[MAXN * MAXN];\n\n// Perform DFS to compute subtree sizes for each node in the spanning tree\nvoid dfs_size(int u, int p) {\n    parent_in_tree[u] = p;\n    subtree_size[u] = 1;\n    for (int next_u : tree_adj[u]) {\n        if (next_u != p) {\n            dfs_size(next_u, u);\n            subtree_size[u] += subtree_size[next_u];\n        }\n    }\n}\n\n// Calculate the quality score of the current spanning tree based on dirtiness and subtree distribution.\n// The average dirtiness S is related to the sum of squares of the gaps between visits to each square.\n// For a DFS tour on a spanning tree, the gaps between visits to node u are twice the sizes of the \n// components formed by removing u from the tree.\nlong long compute_total_score() {\n    long long total = 0;\n    int total_nodes = N * N;\n    for (int u = 0; u < total_nodes; ++u) {\n        long long node_sum_s2 = 0;\n        for (int next_u : tree_adj[u]) {\n            if (next_u == parent_in_tree[u]) {\n                // The size of the component \"above\" node u\n                int s = total_nodes - subtree_size[u];\n                node_sum_s2 += (long long)s * s;\n            } else {\n                // The size of the subtree rooted at node u\n                int s = subtree_size[next_u];\n                node_sum_s2 += (long long)s * s;\n            }\n        }\n        total += (long long)d[u / N][u % N] * node_sum_s2;\n    }\n    return total;\n}\n\n// Helper to find the path from a given node to the root (0,0) in the tree\nvector<int> get_path_to_root(int u) {\n    vector<int> path;\n    while (u != -1) {\n        path.push_back(u);\n        u = parent_in_tree[u];\n    }\n    return path;\n}\n\nint main() {\n    // Speed up standard I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read problem input\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    for (int i = 0; i < N; ++i) cin >> v[i];\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    // Identify all possible edges between grid squares not separated by a wall\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = (i + 1) * N + j;\n                all_edges.push_back({u, vv});\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = i * N + (j + 1);\n                all_edges.push_back({u, vv});\n            }\n        }\n    }\n\n    // Generate an initial random spanning tree using Kruskal's algorithm\n    mt19937 rng(42);\n    vector<Edge> edges = all_edges;\n    shuffle(edges.begin(), edges.end(), rng);\n    vector<int> dsu(N * N);\n    for (int i = 0; i < N * N; ++i) dsu[i] = i;\n    auto dsu_find = [&](auto self, int i) -> int {\n        return dsu[i] == i ? i : dsu[i] = self(self, dsu[i]);\n    };\n    for (auto& e : edges) {\n        int root_u = dsu_find(dsu_find, e.u);\n        int root_v = dsu_find(dsu_find, e.v);\n        if (root_u != root_v) {\n            dsu[root_u] = root_v;\n            is_in_tree[e.u][e.v] = is_in_tree[e.v][e.u] = true;\n            tree_adj[e.u].push_back(e.v);\n            tree_adj[e.v].push_back(e.u);\n        }\n    }\n\n    // Initial score of the spanning tree\n    dfs_size(0, -1);\n    long long current_score = compute_total_score();\n\n    // Simulated Annealing parameters\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    const double TIME_LIMIT = 1.9; // Target time limit for SA process\n    double start_temp = 1e7;\n    double end_temp = 1e3;\n\n    // Run Simulated Annealing to optimize the spanning tree structure\n    while (true) {\n        // Occasionally check elapsed time\n        if (iterations % 256 == 0) {\n            auto current_time = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n        }\n        iterations++;\n\n        // Select a non-tree edge and add it to form a cycle\n        int e_idx = uniform_int_distribution<int>(0, all_edges.size() - 1)(rng);\n        Edge e_in = all_edges[e_idx];\n        if (is_in_tree[e_in.u][e_in.v]) continue;\n\n        // Trace paths to find the cycle formed by adding e_in\n        vector<int> path_u = get_path_to_root(e_in.u);\n        vector<int> path_v = get_path_to_root(e_in.v);\n        int iu = path_u.size() - 1, iv = path_v.size() - 1;\n        while (iu >= 0 && iv >= 0 && path_u[iu] == path_v[iv]) {\n            iu--; iv--;\n        }\n        vector<Edge> cycle;\n        for (int i = 0; i <= iu; ++i) cycle.push_back({path_u[i], parent_in_tree[path_u[i]]});\n        for (int i = 0; i <= iv; ++i) cycle.push_back({path_v[i], parent_in_tree[path_v[i]]});\n        cycle.push_back({e_in.u, e_in.v});\n\n        // Select a random edge from the cycle to remove, maintaining a spanning tree\n        int e_out_idx = uniform_int_distribution<int>(0, cycle.size() - 2)(rng);\n        Edge e_out = cycle[e_out_idx];\n\n        // Perform the edge swap (Remove e_out, Add e_in)\n        is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = false;\n        tree_adj[e_out.u].erase(remove(tree_adj[e_out.u].begin(), tree_adj[e_out.u].end(), e_out.v), tree_adj[e_out.u].end());\n        tree_adj[e_out.v].erase(remove(tree_adj[e_out.v].begin(), tree_adj[e_out.v].end(), e_out.u), tree_adj[e_out.v].end());\n        is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = true;\n        tree_adj[e_in.u].push_back(e_in.v);\n        tree_adj[e_in.v].push_back(e_in.u);\n\n        // Recompute sizes and the new tree's score\n        dfs_size(0, -1);\n        long long next_score = compute_total_score();\n\n        // SA Acceptance Criteria\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() / 1000.0;\n        double progress = min(1.0, elapsed / TIME_LIMIT);\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        if (next_score < current_score || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_score - next_score) / T)) {\n            current_score = next_score;\n        } else {\n            // Revert swap if not accepted\n            is_in_tree[e_in.u][e_in.v] = is_in_tree[e_in.v][e_in.u] = false;\n            tree_adj[e_in.u].erase(remove(tree_adj[e_in.u].begin(), tree_adj[e_in.u].end(), e_in.v), tree_adj[e_in.u].end());\n            tree_adj[e_in.v].erase(remove(tree_adj[e_in.v].begin(), tree_adj[e_in.v].end(), e_in.u), tree_adj[e_in.v].end());\n            is_in_tree[e_out.u][e_out.v] = is_in_tree[e_out.v][e_out.u] = true;\n            tree_adj[e_out.u].push_back(e_out.v);\n            tree_adj[e_out.v].push_back(e_out.u);\n            dfs_size(0, -1);\n        }\n    }\n\n    // Generate the final cleaning tour by performing a DFS on the optimized spanning tree.\n    string tour = \"\";\n    auto get_dir = [&](int u, int v) {\n        int r1 = u / N, c1 = u % N;\n        int r2 = v / N, c2 = v % N;\n        if (r1 < r2) return 'D';\n        if (r1 > r2) return 'U';\n        if (c1 < c2) return 'R';\n        return 'L';\n    };\n    auto dfs_tour_gen = [&](auto self, int u, int p) -> void {\n        for (int next_u : tree_adj[u]) {\n            if (next_u != p) {\n                tour += get_dir(u, next_u);\n                self(self, next_u, u);\n                tour += get_dir(next_u, u);\n            }\n        }\n    };\n    dfs_tour_gen(dfs_tour_gen, 0, -1);\n\n    // Output the resulting cleaning route\n    cout << tour << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\n\n// Movement cost: Manhattan distance between finger positions p1 and p2, plus 1 for the typing itself.\ninline int get_dist(int p1, int p2) {\n    return abs(p1 / N - p2 / N) + abs(p1 % N - p2 % N) + 1;\n}\n\n// Calculate the maximum prefix-suffix overlap between two lucky strings.\n// Since all words are length 5, overlap can be 0 to 4 characters.\nint get_overlap(const string& a, const string& b) {\n    for (int o = 4; o >= 1; --o) {\n        bool match = true;\n        for (int k = 0; k < o; ++k) {\n            if (a[5 - o + k] != b[k]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return o;\n    }\n    return 0;\n}\n\n// Global data tables\nint min_suffix_cost[M][6][N * N];\nint dist_matrix[M][M];\nint d_start[M];\nint overlap_table[M][M];\nvector<int> pos_of_char[26];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read initial grid dimensions, finger starting location, keyboard, and lucky words.\n    int n_in, m_in, si, sj;\n    if (!(cin >> n_in >> m_in)) return 0;\n    cin >> si >> sj;\n\n    vector<string> keyboard(N);\n    for (int i = 0; i < N; ++i) cin >> keyboard[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // Store every grid coordinate for each character A-Z.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            pos_of_char[keyboard[i][j] - 'A'].push_back(i * N + j);\n        }\n    }\n\n    // Precompute the minimum cost to type any suffix (of length 1 to 5) of each lucky word,\n    // given the finger is starting at any grid position.\n    for (int w = 0; w < M; ++w) {\n        for (int p = 0; p < N * N; ++p) min_suffix_cost[w][0][p] = 0;\n        for (int len = 1; len <= 5; ++len) {\n            int char_idx = words[w][5 - len] - 'A';\n            for (int ps = 0; ps < N * N; ++ps) {\n                int best = 1e9;\n                for (int pc : pos_of_char[char_idx]) {\n                    int c = get_dist(ps, pc) + min_suffix_cost[w][len - 1][pc];\n                    if (c < best) best = c;\n                }\n                min_suffix_cost[w][len][ps] = best;\n            }\n        }\n    }\n\n    // Build the overlap table for all pairs of lucky words.\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            overlap_table[i][j] = get_overlap(words[i], words[j]);\n        }\n    }\n\n    // Build a distance matrix for the word-order optimization (TSP).\n    // dist_matrix[i][j] is the cost to type word j given we just typed word i.\n    for (int i = 0; i < M; ++i) {\n        int last_char_i = words[i][4] - 'A';\n        for (int j = 0; j < M; ++j) {\n            int overlap = overlap_table[i][j];\n            int suffix_len = 5 - overlap;\n            int min_v = 1e9;\n            for (int p_last : pos_of_char[last_char_i]) {\n                if (min_suffix_cost[j][suffix_len][p_last] < min_v)\n                    min_v = min_suffix_cost[j][suffix_len][p_last];\n            }\n            // Use a large weight for suffix_len to prioritize maximizing string overlaps.\n            dist_matrix[i][j] = suffix_len * 1000 + min_v;\n        }\n        // Distance to type the very first word from the finger's starting position.\n        d_start[i] = min_suffix_cost[i][5][si * N + sj];\n    }\n\n    // Generate an initial path using multi-start greedy search.\n    vector<int> best_p;\n    long long best_total_cost = 2e18;\n    for (int s = 0; s < M; ++s) {\n        vector<int> cur_p; cur_p.push_back(s);\n        vector<bool> used(M, false); used[s] = true;\n        long long cur_c = d_start[s];\n        for (int i = 1; i < M; ++i) {\n            int last = cur_p.back(), next_v = -1; int min_d = 2e9;\n            for (int v = 0; v < M; ++v) {\n                if (!used[v] && dist_matrix[last][v] < min_d) {\n                    min_d = dist_matrix[last][v]; next_v = v;\n                }\n            }\n            cur_p.push_back(next_v); used[next_v] = true; cur_c += min_d;\n        }\n        if (cur_c < best_total_cost) { best_total_cost = cur_c; best_p = cur_p; }\n    }\n\n    // Refine the word sequence using Simulated Annealing (SA) with 2-opt, Swap, and Shift moves.\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(12345);\n    vector<int> p = best_p;\n    long long current_cost = best_total_cost;\n    double T_start = 100.0, T_end = 0.1, temp = T_start;\n\n    for (int iter = 0; ; ++iter) {\n        if ((iter & 511) == 0) {\n            auto now = chrono::steady_clock::now();\n            long long ms = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (ms > 1925) break;\n            temp = T_start * pow(T_end / T_start, (double)ms / 1925.0);\n        }\n\n        int move_type = uniform_int_distribution<int>(0, 2)(rng);\n        int i = uniform_int_distribution<int>(0, M - 1)(rng);\n        int j = uniform_int_distribution<int>(0, M - 1)(rng);\n        if (i == j) continue;\n\n        if (move_type == 0) { // Move 1: 2-opt\n            if (i > j) swap(i, j);\n            long long next_cost = current_cost;\n            if (i == 0) {\n                next_cost -= d_start[p[0]]; next_cost += d_start[p[j]];\n            } else {\n                next_cost -= dist_matrix[p[i - 1]][p[i]]; next_cost += dist_matrix[p[i - 1]][p[j]];\n            }\n            if (j < M - 1) {\n                next_cost -= dist_matrix[p[j]][p[j + 1]]; next_cost += dist_matrix[p[i]][p[j + 1]];\n            }\n            for (int k = i; k < j; ++k) {\n                next_cost -= dist_matrix[p[k]][p[k + 1]]; next_cost += dist_matrix[p[k + 1]][p[k]];\n            }\n            if (next_cost < current_cost || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_cost - next_cost) / temp)) {\n                current_cost = next_cost; reverse(p.begin() + i, p.begin() + j + 1);\n            }\n        } else { // Move 2 & 3: Swap or Shift\n            vector<int> next_p = p;\n            if (move_type == 1) swap(next_p[i], next_p[j]);\n            else { int val = next_p[i]; next_p.erase(next_p.begin() + i); next_p.insert(next_p.begin() + j, val); }\n            long long next_cost = d_start[next_p[0]];\n            for (int k = 0; k < M - 1; ++k) next_cost += dist_matrix[next_p[k]][next_p[k + 1]];\n            if (next_cost < current_cost || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_cost - next_cost) / temp)) {\n                current_cost = next_cost; p = next_p;\n            }\n        }\n        if (current_cost < best_total_cost) { best_total_cost = current_cost; best_p = p; }\n    }\n\n    // Build the superstring containing all lucky words using the optimized order.\n    string S = words[best_p[0]];\n    for (int i = 1; i < M; ++i) {\n        S += words[best_p[i]].substr(overlap_table[best_p[i - 1]][best_p[i]]);\n    }\n\n    // Use Dynamic Programming (DP) to determine the exact grid coordinates for each character\n    // in the superstring to minimize total Manhattan movement cost.\n    int L_str = S.size();\n    vector<vector<int>> dp_v(L_str), dp_p(L_str), cand(L_str);\n    for (int k = 0; k < L_str; ++k) {\n        cand[k] = pos_of_char[S[k] - 'A'];\n        dp_v[k].assign(cand[k].size(), 1e9); dp_p[k].assign(cand[k].size(), -1);\n    }\n    for (int i = 0; i < (int)cand[0].size(); ++i)\n        dp_v[0][i] = get_dist(si * N + sj, cand[0][i]);\n\n    for (int k = 1; k < L_str; ++k) {\n        for (int i = 0; i < (int)cand[k].size(); ++i) {\n            int cp = cand[k][i];\n            for (int j = 0; j < (int)cand[k - 1].size(); ++j) {\n                int c = dp_v[k - 1][j] + get_dist(cand[k - 1][j], cp);\n                if (c < dp_v[k][i]) { dp_v[k][i] = c; dp_p[k][i] = j; }\n            }\n        }\n    }\n\n    // Find the best ending coordinate and backtrack to get the full coordinate sequence.\n    int bi = 0, mv = 2e9;\n    for (int i = 0; i < (int)cand[L_str - 1].size(); ++i)\n        if (dp_v[L_str - 1][i] < mv) { mv = dp_v[L_str - 1][i]; bi = i; }\n\n    vector<int> res(L_str);\n    for (int k = L_str - 1; k >= 0; --k) { res[k] = cand[k][bi]; bi = dp_p[k][bi]; }\n\n    // Output the resulting finger movements.\n    for (int ps : res) cout << ps / N << \" \" << ps % N << \"\\n\";\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int r, c;\n};\n\nstruct Polyomino {\n    int id;\n    int d;\n    vector<Point> ps;\n    vector<vector<Point>> positions;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<pair<vector<int>, int>> queries;\nvector<pair<Point, int>> drills;\nvector<vector<vector<int>>> W; // W[field_idx][pos_idx][query_idx]\n\ndouble normal_cdf(double x) {\n    return 0.5 * erfc(-x * M_SQRT1_2);\n}\n\ndouble get_prob(int k, int v_sum, int v_obs) {\n    if (k == 1) return (v_sum == v_obs) ? 1.0 : 1e-18;\n    double mu = (k - v_sum) * eps + v_sum * (1.0 - eps);\n    double sigma = sqrt((double)k * eps * (1.0 - eps));\n    if (v_obs == 0) {\n        return max(1e-18, normal_cdf((0.5 - mu) / sigma));\n    } else {\n        return max(1e-18, normal_cdf((v_obs + 0.5 - mu) / sigma) - normal_cdf((v_obs - 0.5 - mu) / sigma));\n    }\n}\n\ndouble get_log_prob(int k, int v_sum, int v_obs) {\n    return log(get_prob(k, v_sum, v_obs));\n}\n\nstruct Config {\n    vector<int> pos_idx;\n    vector<int> v_sums;\n    vector<vector<int>> grid_v;\n    double log_prob;\n\n    Config() : pos_idx(M), v_sums(), grid_v(N, vector<int>(N, 0)), log_prob(0) {}\n\n    void compute_all() {\n        for (int i = 0; i < N; ++i) fill(grid_v[i].begin(), grid_v[i].end(), 0);\n        for (int i = 0; i < M; ++i) {\n            for (const auto& p : oil_fields[i].positions[pos_idx[i]]) {\n                grid_v[p.r][p.c]++;\n            }\n        }\n        v_sums.assign(queries.size(), 0);\n        log_prob = 0;\n        for (size_t q = 0; q < queries.size(); ++q) {\n            for (int k = 0; k < M; ++k) {\n                v_sums[q] += W[k][pos_idx[k]][q];\n            }\n            log_prob += get_log_prob(queries[q].first.size(), v_sums[q], queries[q].second);\n        }\n        for (const auto& d : drills) {\n            if (grid_v[d.first.r][d.first.c] != d.second) log_prob -= 1e6;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> eps)) return 0;\n    oil_fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int d; cin >> d; oil_fields[i].d = d;\n        vector<Point> ps(d);\n        int max_r = 0, max_c = 0;\n        for (int j = 0; j < d; ++j) {\n            cin >> ps[j].r >> ps[j].c;\n            max_r = max(max_r, ps[j].r);\n            max_c = max(max_c, ps[j].c);\n        }\n        oil_fields[i].ps = ps;\n        for (int r = 0; r <= N - 1 - max_r; ++r) {\n            for (int c = 0; c <= N - 1 - max_c; ++c) {\n                vector<Point> pos;\n                for (const auto& p : ps) pos.push_back({p.r + r, p.c + c});\n                oil_fields[i].positions.push_back(pos);\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    for (int i = 0; i < 2 * N; ++i) {\n        vector<int> S;\n        for (int j = 0; j < N * N; ++j) {\n            if (uniform_real_distribution<double>(0, 1)(rng) < 0.5) S.push_back(j);\n        }\n        if (S.size() < 2) { S.push_back(0); S.push_back(1); }\n        cout << \"q \" << S.size();\n        for (int idx : S) cout << \" \" << idx / N << \" \" << idx % N;\n        cout << endl;\n        int resp; cin >> resp;\n        queries.push_back({S, resp});\n    }\n\n    W.assign(M, vector<vector<int>>());\n    for (int i = 0; i < M; ++i) {\n        W[i].assign(oil_fields[i].positions.size(), vector<int>(queries.size(), 0));\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            vector<vector<bool>> is_in_pos(N, vector<bool>(N, false));\n            for (const auto& pt : oil_fields[i].positions[p]) is_in_pos[pt.r][pt.c] = true;\n            for (size_t q = 0; q < queries.size(); ++q) {\n                for (int idx : queries[q].first) {\n                    if (is_in_pos[idx / N][idx % N]) W[i][p][q]++;\n                }\n            }\n        }\n    }\n\n    const int num_samples = 400;\n    vector<Config> samples(num_samples);\n    for (int i = 0; i < num_samples; ++i) {\n        for (int j = 0; j < M; ++j) {\n            samples[i].pos_idx[j] = uniform_int_distribution<int>(0, (int)oil_fields[j].positions.size() - 1)(rng);\n        }\n        samples[i].compute_all();\n    }\n\n    for (int iter = 0; iter < 2 * N * N; ++iter) {\n        for (int i = 0; i < num_samples; ++i) {\n            for (int step = 0; step < 30; ++step) {\n                int m = uniform_int_distribution<int>(0, M - 1)(rng);\n                int old_pos = samples[i].pos_idx[m];\n                int new_pos = uniform_int_distribution<int>(0, (int)oil_fields[m].positions.size() - 1)(rng);\n                if (old_pos == new_pos) continue;\n\n                double old_lp = samples[i].log_prob;\n                for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]--;\n                for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]++;\n                \n                double new_lp = 0;\n                vector<int> old_v_sums = samples[i].v_sums;\n                for (size_t q = 0; q < queries.size(); ++q) {\n                    samples[i].v_sums[q] = samples[i].v_sums[q] - W[m][old_pos][q] + W[m][new_pos][q];\n                    new_lp += get_log_prob(queries[q].first.size(), samples[i].v_sums[q], queries[q].second);\n                }\n                for (const auto& d : drills) {\n                    if (samples[i].grid_v[d.first.r][d.first.c] != d.second) new_lp -= 1e6;\n                }\n                \n                if (new_lp > old_lp || uniform_real_distribution<double>(0, 1)(rng) < exp(new_lp - old_lp)) {\n                    samples[i].log_prob = new_lp;\n                    samples[i].pos_idx[m] = new_pos;\n                } else {\n                    for (const auto& p : oil_fields[m].positions[new_pos]) samples[i].grid_v[p.r][p.c]--;\n                    for (const auto& p : oil_fields[m].positions[old_pos]) samples[i].grid_v[p.r][p.c]++;\n                    samples[i].v_sums = old_v_sums;\n                }\n            }\n        }\n\n        vector<vector<double>> p(N, vector<double>(N, 0));\n        for (int i = 0; i < num_samples; ++i) {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) if (samples[i].grid_v[r][c] > 0) p[r][c] += 1.0;\n            }\n        }\n\n        bool confident = true;\n        vector<Point> guess_set;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p[r][c] /= num_samples;\n                if (p[r][c] > 0.5) guess_set.push_back({r, c});\n                if (p[r][c] > 0.01 && p[r][c] < 0.99) confident = false;\n            }\n        }\n\n        if (confident || iter > N * N) {\n            cout << \"a \" << guess_set.size();\n            for (const auto& pt : guess_set) cout << \" \" << pt.r << \" \" << pt.c;\n            cout << endl;\n            int resp; if (!(cin >> resp)) break;\n            if (resp == 1) break;\n        }\n\n        double max_var = -1; Point best_p = {0, 0};\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                double var = p[r][c] * (1.0 - p[r][c]);\n                if (var > max_var) { max_var = var; best_p = {r, c}; }\n            }\n        }\n\n        cout << \"q 1 \" << best_p.r << \" \" << best_p.c << endl;\n        int resp; if (!(cin >> resp)) break;\n        drills.push_back({best_p, resp});\n        for (int i = 0; i < num_samples; ++i) samples[i].compute_all();\n    }\n    return 0;\n}\n","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <deque>\n\nusing namespace std;\n\ntypedef long long ll;\nconst ll INF = 1e16;\n\n/**\n * Problem Strategy:\n * 1.  Fix the horizontal strip structure (R strips) for all D days. This makes\n *     horizontal partition movement cost zero.\n * 2.  The vertical partition positions within each strip can change each day.\n *     We use Dynamic Programming (DP) for each day and each strip to find the optimal \n *     vertical coordinates that minimize (Area Penalty + Partition Change Cost).\n * 3.  The DP state: dp[k][x] is the minimum cost for the first k reservations in \n *     the strip ending at coordinate x.\n * 4.  We use a sliding window optimization (deque) to solve the DP in O(W) per strip,\n *     total O(D * N * W) across all days, which is very efficient.\n * 5.  Candidate values for R (number of horizontal strips) are tested, and the best \n *     overall configuration is chosen.\n */\n\nstruct Rectangle {\n    int r1, c1, r2, c2;\n};\n\nint W, D, N;\nll a[55][55];\n\n// Computes the area deficit penalty for a set of rectangles on day d.\nll calculate_area_penalty(const vector<Rectangle>& rects, int d) {\n    ll penalty = 0;\n    for (int k = 0; k < N; ++k) {\n        ll area = (ll)(rects[k].r2 - rects[k].r1) * (rects[k].c2 - rects[k].c1);\n        if (a[d][k] > area) penalty += 100 * (a[d][k] - area);\n    }\n    return penalty;\n}\n\n// Computes the total combined cost: sum of area penalties and partition installation/removal costs.\nll calculate_total_cost(const vector<vector<Rectangle>>& all_rects) {\n    ll total_penalty = 0;\n    for (int d = 0; d < D; ++d) total_penalty += calculate_area_penalty(all_rects[d], d);\n\n    ll total_movement = 0;\n    for (int d = 1; d < D; ++d) {\n        // Track partition segments on the current and previous days.\n        static bool h_p[1001][1000], v_p[1000][1001];\n        static bool h_c[1001][1000], v_c[1000][1001];\n        for (int i = 0; i <= W; ++i) for (int j = 0; j < W; ++j) h_p[i][j] = h_c[i][j] = false;\n        for (int i = 0; i < W; ++i) for (int j = 0; j <= W; ++j) v_p[i][j] = v_c[i][j] = false;\n\n        auto fill = [&](const vector<Rectangle>& rects, bool h[1001][1000], bool v[1000][1001]) {\n            for (const auto& r : rects) {\n                if (r.r1 > 0 && r.r1 < W) for (int j = r.c1; j < r.c2; ++j) h[r.r1][j] = true;\n                if (r.r2 > 0 && r.r2 < W) for (int j = r.c1; j < r.c2; ++j) h[r.r2][j] = true;\n                if (r.c1 > 0 && r.c1 < W) for (int i = r.r1; i < r.r2; ++i) v[i][r.c1] = true;\n                if (r.c2 > 0 && r.c2 < W) for (int i = r.r1; i < r.r2; ++i) v[i][r.c2] = true;\n            }\n        };\n        fill(all_rects[d - 1], h_p, v_p);\n        fill(all_rects[d], h_c, v_c);\n        // Cost is the count of unit segments that are different between the two days.\n        for (int i = 1; i < W; ++i) for (int j = 0; j < W; ++j) if (h_p[i][j] != h_c[i][j]) total_movement++;\n        for (int i = 0; i < W; ++i) for (int j = 1; j < W; ++j) if (v_p[i][j] != v_c[i][j]) total_movement++;\n    }\n    return total_penalty + total_movement;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> W >> D >> N)) return 0;\n    for (int d = 0; d < D; ++d) for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    ll best_score = -1;\n    vector<vector<Rectangle>> best_all_rects;\n    vector<int> try_R = {1, 2, 5, 10, N};\n\n    for (int R : try_R) {\n        if (R > N) continue;\n        vector<vector<int>> strips(R);\n        vector<ll> avg_area(R, 0);\n        int base = N / R, rem = N % R, ck = 0;\n        // Group reservations into R strips.\n        for (int i = 0; i < R; ++i) {\n            int sz = base + (i < rem ? 1 : 0);\n            for (int j = 0; j < sz; ++j) {\n                for (int d = 0; d < D; ++d) avg_area[i] += a[d][ck];\n                strips[i].push_back(ck++);\n            }\n        }\n\n        // Determine fixed strip heights proportional to their average desired areas.\n        ll total_avg = 0;\n        for (int i = 0; i < R; ++i) total_avg += avg_area[i];\n        vector<int> H(R, 1);\n        int rem_H = W - R;\n        for (int i = 0; i < R; ++i) {\n            int add = (total_avg == 0) ? 0 : (int)((double)avg_area[i] / total_avg * (W - R));\n            H[i] += add;\n            rem_H -= add;\n        }\n        H[R - 1] += rem_H;\n\n        vector<int> y_coords(R + 1, 0);\n        for (int i = 0; i < R; ++i) y_coords[i + 1] = y_coords[i] + H[i];\n\n        vector<vector<Rectangle>> cur_all(D, vector<Rectangle>(N));\n        vector<vector<int>> prev_x(R);\n\n        for (int d = 0; d < D; ++d) {\n            for (int r = 0; r < R; ++r) {\n                int nr = strips[r].size(), h = H[r];\n                vector<vector<ll>> dp(nr + 1, vector<ll>(W + 1, INF));\n                vector<vector<int>> parent(nr + 1, vector<int>(W + 1, -1));\n                dp[0][0] = 0;\n                \n                vector<bool> is_prev(W + 1, false);\n                if (d > 0) for (int x_coord : prev_x[r]) is_prev[x_coord] = true;\n\n                for (int k = 1; k <= nr; ++k) {\n                    ll cur_a = a[d][strips[r][k - 1]];\n                    int req_w = (int)((cur_a + h - 1) / h);\n                    deque<int> dq; ll p1_best_val = INF; int p1_best_idx = -1;\n\n                    for (int x = 1; x <= W; ++x) {\n                        // Sliding window update for Case 1: Assigned width >= required width (Penalty = 0).\n                        int p_new = x - req_w;\n                        if (p_new >= k - 1 && p_new <= W && dp[k - 1][p_new] < INF) {\n                            if (dp[k - 1][p_new] < p1_best_val) {\n                                p1_best_val = dp[k - 1][p_new];\n                                p1_best_idx = p_new;\n                            }\n                        }\n                        // Sliding window update for Case 2: Assigned width < required width (Linear penalty).\n                        while (!dq.empty() && dq.front() <= x - req_w) dq.pop_front();\n                        int p2_new = x - 1;\n                        if (p2_new >= k - 1 && dp[k - 1][p2_new] < INF) {\n                            ll val_new = dp[k - 1][p2_new] + 100LL * h * p2_new;\n                            while (!dq.empty()) {\n                                ll val_back = dp[k - 1][dq.back()] + 100LL * h * dq.back();\n                                if (val_back >= val_new) dq.pop_back(); else break;\n                            }\n                            dq.push_back(p2_new);\n                        }\n\n                        if (x < k || x > W - (nr - k)) continue;\n\n                        ll best_c = INF; int best_p = -1;\n                        if (p1_best_val < INF) { best_c = p1_best_val; best_p = p1_best_idx; }\n                        if (!dq.empty()) {\n                            int p2_idx = dq.front();\n                            ll val2 = dp[k - 1][p2_idx] + 100LL * cur_a - 100LL * h * (x - p2_idx);\n                            if (val2 < best_c) { best_c = val2; best_p = p2_idx; }\n                        }\n                        // Final DP update including partition change cost.\n                        if (best_c < INF) {\n                            dp[k][x] = best_c + (k < nr ? (is_prev[x] ? -h : h) : 0);\n                            parent[k][x] = best_p;\n                        }\n                    }\n                }\n                // Backtrack and store vertical boundaries for next day's cost calculation.\n                vector<int> cur_x_list; int cx = W;\n                for (int k = nr; k >= 1; --k) {\n                    int p = parent[k][cx];\n                    cur_all[d][strips[r][k - 1]] = {y_coords[r], p, y_coords[r + 1], cx};\n                    if (k > 1) cur_x_list.push_back(p);\n                    cx = p;\n                }\n                prev_x[r] = cur_x_list;\n            }\n        }\n        // Choose the R that results in the minimum total absolute score.\n        ll current_score = calculate_total_cost(cur_all);\n        if (best_score == -1 || current_score < best_score) {\n            best_score = current_score;\n            best_all_rects = cur_all;\n        }\n    }\n\n    // Output assigned rectangular coordinates for all D days.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_all_rects[d][k].r1 << \" \" << best_all_rects[d][k].c1 << \" \"\n                 << best_all_rects[d][k].r2 << \" \" << best_all_rects[d][k].c2 << \"\\n\";\n        }\n    }\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <stdint.h>\n#include <string.h>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\nconst double W = 0.5; // Heuristic weight for board squares that are not yet \"fixed\"\n\n// Struct to store a single stamp operation\nstruct Op {\n    int m, p, q;\n};\n\n// Struct to represent a combination of 0 to 3 stamps used at the same (p, q) position\nstruct Combination {\n    int k;                   // Total number of stamps in the combination\n    vector<int> ms;          // Indices of the stamps used\n    uint32_t s[3][3];        // Sum of stamp values modulo P\n};\n\n// State representation for the beam search\nstruct State {\n    uint32_t board[N][N];    // Board square values modulo P\n    int total_k;             // Cumulative number of stamps used so far\n    int parent_idx;          // Link to parent state index in the previous beam level\n    int combi_idx;           // Index of the combination chosen at the current step\n    double eval;             // Weighted evaluation score\n};\n\n// Potential candidate for the next step of the beam search\nstruct Candidate {\n    int state_idx;           // Index of the parent state in the current beam\n    int combi_idx;           // Index of the combination to apply\n    double eval;             // Resulting evaluation score\n\n    // Descending order comparison by evaluation score\n    bool operator>(const Candidate& other) const {\n        return eval > other.eval;\n    }\n};\n\n// Global arrays for precomputed heuristic values to speed up evaluation\ndouble pre_eval_sum_sw[49][1771];\ndouble P_w_after[49][3][3];\ndouble w_after_val[49][3][3];\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    uint32_t a[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    uint32_t stamps[M][3][3];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[m][i][j];\n\n    // Precompute all stamp combinations of sizes 0, 1, 2, and 3\n    vector<Combination> all_combi;\n    all_combi.push_back({0, {}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}});\n\n    for (int m = 0; m < M; ++m) {\n        Combination c;\n        c.k = 1; c.ms = {m};\n        for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c.s[i][j] = stamps[m][i][j];\n        all_combi.push_back(c);\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            Combination c;\n            c.k = 2; c.ms = {m1, m2};\n            for (int i = 0; i < 3; ++i)\n                for (int j = 0; j < 3; ++j)\n                    c.s[i][j] = (stamps[m1][i][j] + stamps[m2][i][j]) % P;\n            all_combi.push_back(c);\n        }\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            for (int m3 = m2; m3 < M; ++m3) {\n                Combination c;\n                c.k = 3; c.ms = {m1, m2, m3};\n                for (int i = 0; i < 3; ++i)\n                    for (int j = 0; j < 3; ++j)\n                        c.s[i][j] = ((long long)stamps[m1][i][j] + stamps[m2][i][j] + stamps[m3][i][j]) % P;\n                all_combi.push_back(c);\n            }\n        }\n    }\n\n    // List all potential stamp placement corners (p, q) in row-major order\n    vector<pair<int, int>> positions;\n    for (int p = 0; p <= 6; ++p)\n        for (int q = 0; q <= 6; ++q)\n            positions.push_back({p, q});\n\n    // Identify for each grid cell when it will no longer be affected by future stamps\n    int last_p[N][N], last_q[N][N];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            last_p[r][c] = -1; last_q[r][c] = -1;\n            for (const auto& pos : positions) {\n                if (r >= pos.first && r < pos.first + 3 && c >= pos.second && c < pos.second + 3) {\n                    last_p[r][c] = pos.first;\n                    last_q[r][c] = pos.second;\n                }\n            }\n        }\n    }\n\n    // Track which squares become \"fixed\" at each step in the beam search\n    vector<pair<int, int>> fixed_squares[7][7];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            fixed_squares[last_p[r][c]][last_q[r][c]].push_back({r, c});\n        }\n    }\n\n    // Precompute heuristic values for stamp weights at each position\n    for (int step = 0; step < 49; ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                double w = (last_p[r][c] == p && last_q[r][c] == q) ? 1.0 : W;\n                w_after_val[step][i][j] = w;\n                P_w_after[step][i][j] = (double)P * w;\n            }\n        }\n        for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n            double sum_sw = 0;\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    sum_sw += (double)all_combi[c_idx].s[i][j] * w_after_val[step][i][j];\n                }\n            }\n            pre_eval_sum_sw[step][c_idx] = sum_sw;\n        }\n    }\n\n    // Beam search initialization\n    State initial_state;\n    memcpy(initial_state.board, a, sizeof(a));\n    initial_state.total_k = 0;\n    initial_state.parent_idx = -1;\n    initial_state.combi_idx = -1;\n    initial_state.eval = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.eval += (double)a[i][j] * W;\n\n    vector<vector<State>> all_beams;\n    all_beams.push_back({initial_state});\n\n    int B = 900; // Beam size (adjusted for speed)\n    vector<Candidate> candidates;\n    candidates.reserve(B * all_combi.size());\n\n    // Iterative beam search through each stamp position\n    for (int step = 0; step < (int)positions.size(); ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        const vector<State>& current_beam = all_beams.back();\n        candidates.clear();\n\n        for (int s_idx = 0; s_idx < (int)current_beam.size(); ++s_idx) {\n            const State& st = current_beam[s_idx];\n            double base_eval_increase = 0;\n            for (const auto& sq : fixed_squares[p][q]) {\n                base_eval_increase += (double)st.board[sq.first][sq.second] * (1.0 - W);\n            }\n            double base_eval = st.eval + base_eval_increase;\n\n            // Tight inner loop for evaluation of each combination\n            for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n                const Combination& combi = all_combi[c_idx];\n                if (st.total_k + combi.k > K) continue;\n\n                double cur_eval = base_eval + pre_eval_sum_sw[step][c_idx];\n                if (st.board[p][q] + combi.s[0][0] >= P) cur_eval -= P_w_after[step][0][0];\n                if (st.board[p][q+1] + combi.s[0][1] >= P) cur_eval -= P_w_after[step][0][1];\n                if (st.board[p][q+2] + combi.s[0][2] >= P) cur_eval -= P_w_after[step][0][2];\n                if (st.board[p+1][q] + combi.s[1][0] >= P) cur_eval -= P_w_after[step][1][0];\n                if (st.board[p+1][q+1] + combi.s[1][1] >= P) cur_eval -= P_w_after[step][1][1];\n                if (st.board[p+1][q+2] + combi.s[1][2] >= P) cur_eval -= P_w_after[step][1][2];\n                if (st.board[p+2][q] + combi.s[2][0] >= P) cur_eval -= P_w_after[step][2][0];\n                if (st.board[p+2][q+1] + combi.s[2][1] >= P) cur_eval -= P_w_after[step][2][1];\n                if (st.board[p+2][q+2] + combi.s[2][2] >= P) cur_eval -= P_w_after[step][2][2];\n                \n                candidates.push_back({s_idx, c_idx, cur_eval});\n            }\n        }\n\n        // Selection of top B candidates for the next beam level\n        int next_B = min((int)candidates.size(), B);\n        nth_element(candidates.begin(), candidates.begin() + next_B, candidates.end(), greater<Candidate>());\n        candidates.resize(next_B);\n\n        vector<State> next_beam;\n        next_beam.reserve(next_B);\n        for (const auto& cand : candidates) {\n            const State& parent = current_beam[cand.state_idx];\n            const Combination& combi = all_combi[cand.combi_idx];\n            State ns;\n            memcpy(ns.board, parent.board, sizeof(parent.board));\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    uint32_t v = ns.board[p + i][q + j] + combi.s[i][j];\n                    if (v >= P) v -= P;\n                    ns.board[p + i][q + j] = v;\n                }\n            }\n            ns.total_k = parent.total_k + combi.k;\n            ns.parent_idx = cand.state_idx;\n            ns.combi_idx = cand.combi_idx;\n            ns.eval = cand.eval;\n            next_beam.push_back(std::move(ns));\n        }\n        all_beams.push_back(std::move(next_beam));\n    }\n\n    // Retrieve best overall final state and output the sequence of operations\n    const vector<State>& final_beam = all_beams.back();\n    int best_state_idx = 0;\n    double best_eval = -1e18;\n    for (int i = 0; i < (int)final_beam.size(); ++i) {\n        if (final_beam[i].eval > best_eval) {\n            best_eval = final_beam[i].eval;\n            best_state_idx = i;\n        }\n    }\n\n    vector<Op> final_ops;\n    int cur_idx = best_state_idx;\n    for (int step = (int)positions.size() - 1; step >= 0; --step) {\n        const State& st = all_beams[step + 1][cur_idx];\n        const Combination& combi = all_combi[st.combi_idx];\n        for (int m_idx : combi.ms) {\n            final_ops.push_back({m_idx, positions[step].first, positions[step].second});\n        }\n        cur_idx = st.parent_idx;\n    }\n\n    cout << final_ops.size() << \"\\n\";\n    for (int i = (int)final_ops.size() - 1; i >= 0; --i) {\n        cout << final_ops[i].m << \" \" << final_ops[i].p << \" \" << final_ops[i].q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer's solution for the container terminal problem.\n *\n * Strategy:\n * 1. Bomb all small cranes (cranes 1-4) in Turn 0 to clear the grid.\n * 2. Use the large crane (crane 0) to handle all containers one by one.\n * 3. Crane 0 strategy:\n *    - Priority 1: If a container that is next in order for its dispatch gate is already on the grid,\n *                  pick it up and move it to its dispatch gate.\n *    - Priority 2: If no such container is on the grid, find the most urgent container (smallest index\n *                  that hasn't been dispatched) still in a receiving queue. Move the top container of\n *                  that queue to a buffer square to clear the way.\n * 4. This strategy ensures M1=0 (no inversions), M2=0 (all to correct gates), and M3=0 (all dispatched).\n *    The turns count M0 will be minimized by only moving what's necessary and using shortest paths.\n */\n\nvoid add_move_to_queue(vector<char>& q, int tr, int tc, int& r, int& c) {\n    while (r < tr) { q.push_back('D'); r++; }\n    while (r > tr) { q.push_back('U'); r--; }\n    while (c < tc) { q.push_back('R'); c++; }\n    while (c > tc) { q.push_back('L'); c--; }\n}\n\nint main() {\n    int N_in;\n    if (!(cin >> N_in)) return 0;\n    int N = 5;\n    vector<vector<int>> arrival_queue(5, vector<int>(5));\n    vector<int> gate_of(25);\n    for (int i = 0; i < 5; ++i) {\n        for (int j = 0; j < 5; ++j) {\n            cin >> arrival_queue[i][j];\n            gate_of[arrival_queue[i][j]] = i;\n        }\n    }\n\n    vector<int> current_gate_idx(5, 0);\n    vector<vector<int>> grid(5, vector<int>(5, -1));\n    vector<int> next_needed(5);\n    for (int i = 0; i < 5; i++) next_needed[i] = 5 * i;\n    vector<bool> is_dispatched(25, false);\n    int dispatched_count = 0;\n\n    int crane_r = 0, crane_c = 0;\n    int held = -1;\n    vector<string> actions(5, \"\");\n    vector<char> action_queue;\n\n    for (int t = 0; t < 10000; ++t) {\n        // Step 1: Arrival of containers\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][0] == -1 && current_gate_idx[i] < 5) {\n                // Containers arrive only if square is empty and no crane is holding there\n                if (!(crane_r == i && crane_c == 0 && held != -1)) {\n                    grid[i][0] = arrival_queue[i][current_gate_idx[i]];\n                    current_gate_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        char act0 = '.';\n        if (t == 0) {\n            // Initial moves: move Crane 0 out of (0,0) and bomb others\n            act0 = 'R';\n            for (int i = 1; i < 5; i++) actions[i] += 'B';\n        } else {\n            if (action_queue.empty()) {\n                // Determine next task for Crane 0\n                if (held == -1) {\n                    int target_r = -1, target_c = -1;\n                    // Check if a needed container is already on the grid (arrival gates or buffer)\n                    for (int r = 0; r < 5; ++r) {\n                        for (int c = 0; c < 4; ++c) {\n                            if (grid[r][c] != -1) {\n                                int val = grid[r][c];\n                                if (val == next_needed[val / 5]) {\n                                    target_r = r; target_c = c; break;\n                                }\n                            }\n                        }\n                        if (target_r != -1) break;\n                    }\n\n                    if (target_r != -1) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, target_r, target_c, r, c);\n                        action_queue.push_back('P');\n                    } else {\n                        // Find most urgent container still in a queue and clear its path\n                        int urgent_v = 100;\n                        int clear_gate = -1;\n                        for (int i = 0; i < 5; ++i) {\n                            if (next_needed[i] < 5 * (i + 1)) {\n                                int v = next_needed[i];\n                                bool is_av = !is_dispatched[v];\n                                if (is_av) {\n                                    for (int r1 = 0; r1 < 5; r1++)\n                                        for (int c1 = 0; c1 < 4; c1++)\n                                            if (grid[r1][c1] == v) is_av = false;\n                                }\n                                if (is_av && v < urgent_v) {\n                                    urgent_v = v;\n                                    clear_gate = gate_of[v];\n                                }\n                            }\n                        }\n                        if (clear_gate != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, clear_gate, 0, r, c);\n                            if (grid[clear_gate][0] != -1) action_queue.push_back('P');\n                            else action_queue.push_back('.'); // Wait for container arrival\n                        }\n                    }\n                } else {\n                    // Holding a container: either dispatch it or move it to a buffer\n                    if (held == next_needed[held / 5]) {\n                        int r = crane_r, c = crane_c;\n                        add_move_to_queue(action_queue, held / 5, 4, r, c);\n                        action_queue.push_back('Q');\n                    } else {\n                        int br = -1, bc = -1;\n                        for (int c = 1; c <= 3; ++c) {\n                            for (int r = 0; r < 5; ++r) {\n                                if (grid[r][c] == -1) { br = r; bc = c; break; }\n                            }\n                            if (br != -1) break;\n                        }\n                        if (br != -1) {\n                            int r = crane_r, c = crane_c;\n                            add_move_to_queue(action_queue, br, bc, r, c);\n                            action_queue.push_back('Q');\n                        } else {\n                            action_queue.push_back('.');\n                        }\n                    }\n                }\n            }\n\n            if (!action_queue.empty()) {\n                act0 = action_queue.front();\n                action_queue.erase(action_queue.begin());\n            }\n            for (int i = 1; i < 5; i++) actions[i] += '.';\n        }\n\n        actions[0] += act0;\n        if (act0 == 'P') { held = grid[crane_r][crane_c]; grid[crane_r][crane_c] = -1; }\n        else if (act0 == 'Q') {\n            int val = held;\n            grid[crane_r][crane_c] = val;\n            if (crane_c == 4) next_needed[val / 5]++;\n            held = -1;\n        } else if (act0 == 'U') crane_r--;\n        else if (act0 == 'D') crane_r++;\n        else if (act0 == 'L') crane_c--;\n        else if (act0 == 'R') crane_c++;\n\n        // Step 3: Container dispatch\n        for (int i = 0; i < 5; i++) {\n            if (grid[i][4] != -1) {\n                is_dispatched[grid[i][4]] = true;\n                grid[i][4] = -1;\n                dispatched_count++;\n            }\n        }\n\n        if (dispatched_count == 25) break;\n    }\n\n    // Output all actions, padding with '.' as necessary\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) max_len = max(max_len, (int)actions[i].length());\n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) actions[i] += '.';\n        cout << actions[i] << endl;\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n// The construction site is an N x N grid with N fixed at 20.\nconst int N = 20;\n\n/**\n * State struct maintains the simulation of ground leveling.\n * It tracks current heights, the truck's location, the soil load,\n * and the sequence of operations with their total cost.\n */\nstruct State {\n    int h[N][N];\n    int r, c;\n    long long L;\n    long long cost;\n    vector<string> ops;\n\n    State(const int initial_h[N][N]) {\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                h[i][j] = initial_h[i][j];\n            }\n        }\n        r = 0; c = 0; L = 0; cost = 0;\n        ops.reserve(40000); // Pre-allocate memory for speed.\n    }\n\n    // Load soil: current height decreases, truck load increases.\n    void load(int d) {\n        if (d <= 0) return;\n        h[r][c] -= d;\n        L += d;\n        cost += d;\n        ops.push_back(\"+\" + to_string(d));\n    }\n\n    // Unload soil: current height increases, truck load decreases.\n    void unload(int d) {\n        if (d <= 0) return;\n        h[r][c] += d;\n        L -= d;\n        cost += d;\n        ops.push_back(\"-\" + to_string(d));\n    }\n\n    // Move truck: cost depends on movement (100) and current load (d).\n    void move(char dir) {\n        if (dir == 'U') r--;\n        else if (dir == 'D') r++;\n        else if (dir == 'L') c--;\n        else if (dir == 'R') c++;\n        cost += (100 + L);\n        ops.push_back(string(1, dir));\n    }\n};\n\n// Precomputed tables for performance in heuristic calculations.\ndouble dist_pow_table[41];\ndouble soil_pow_table[101];\n\n/**\n * Solve function implements a multi-start randomized greedy algorithm.\n * It selects the next target square to work on based on distance and soil volume,\n * using heuristic weights that are randomized across trials.\n */\nvoid solve(const int initial_h[N][N], double dp, double sp, double lp, double sw, vector<string>& best_ops, long long &best_total_cost, mt19937& rng) {\n    State s(initial_h);\n    \n    // Identify squares that need initial leveling.\n    vector<pair<int, int>> targets;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (initial_h[i][j] != 0) targets.push_back({i, j});\n        }\n    }\n\n    // Precompute power tables for the current heuristic parameters.\n    for (int i = 0; i <= 40; ++i) dist_pow_table[i] = pow((double)i, dp);\n    for (int i = 1; i <= 100; ++i) soil_pow_table[i] = pow((double)i, sp);\n\n    // Limit operations to avoid exceeding turn constraints (100,000).\n    while (!targets.empty() && s.ops.size() < 99900) {\n        // Step 1: Handle work at the current cell.\n        if (s.h[s.r][s.c] > 0) {\n            s.load(s.h[s.r][s.c]);\n        } else if (s.h[s.r][s.c] < 0 && s.L > 0) {\n            int amount = (int)min((long long)abs(s.h[s.r][s.c]), s.L);\n            s.unload(amount);\n        }\n\n        // Clean up the work list.\n        for (int k = 0; k < (int)targets.size(); ++k) {\n            if (s.h[targets[k].first][targets[k].second] == 0) {\n                targets[k] = targets.back();\n                targets.pop_back();\n                k--;\n            }\n        }\n        if (targets.empty()) break;\n\n        // Step 2: Select the next work target using a heuristic score.\n        int tr = -1, tc = -1;\n        double min_score = 1e30;\n        for (const auto& t : targets) {\n            int dist = abs(s.r - t.first) + abs(s.c - t.second);\n            if (dist == 0) continue; \n            \n            // Cannot visit a sink if the truck is empty.\n            if (s.h[t.first][t.second] < 0 && s.L == 0) continue;\n\n            int val = (s.h[t.first][t.second] > 0) ? s.h[t.first][t.second] : (int)min((long long)abs(s.h[t.first][t.second]), s.L);\n            double score = (dist_pow_table[dist] * (100.0 + (double)s.L) / soil_pow_table[val]);\n            \n            if (s.h[t.first][t.second] > 0) {\n                // If target is a source, apply the load penalty (impact of carrying extra weight later).\n                score *= (1.0 + (double)s.L * lp);\n            } else {\n                // If target is a sink, apply the sink weight.\n                score *= sw;\n            }\n\n            if (score < min_score) {\n                min_score = score;\n                tr = t.first; tc = t.second;\n            }\n        }\n\n        if (tr == -1) break;\n\n        // Step 3: Pathfinding. Move one step toward the target. \n        // If multiple steps reduce Manhattan distance, pick the one passing through more work squares.\n        int dr = tr - s.r;\n        int dc = tc - s.c;\n        vector<char> moves;\n        if (dr > 0) moves.push_back('D'); else if (dr < 0) moves.push_back('U');\n        if (dc > 0) moves.push_back('R'); else if (dc < 0) moves.push_back('L');\n\n        char best_move = moves[0];\n        if (moves.size() > 1) {\n            double best_m_score = -1.0;\n            vector<char> best_moves;\n            for (char m : moves) {\n                double m_score = 0;\n                if (m == 'D') {\n                    for (int r = s.r + 1; r <= tr; ++r) if (s.h[r][s.c] != 0 && (s.h[r][s.c] > 0 || s.L > 0)) m_score += 1.0;\n                } else if (m == 'U') {\n                    for (int r = s.r - 1; r >= tr; --r) if (s.h[r][s.c] != 0 && (s.h[r][s.c] > 0 || s.L > 0)) m_score += 1.0;\n                } else if (m == 'R') {\n                    for (int c = s.c + 1; c <= tc; ++c) if (s.h[s.r][c] != 0 && (s.h[s.r][c] > 0 || s.L > 0)) m_score += 1.0;\n                } else if (m == 'L') {\n                    for (int c = s.c - 1; c >= tc; --c) if (s.h[s.r][c] != 0 && (s.h[s.r][c] > 0 || s.L > 0)) m_score += 1.0;\n                }\n                if (m_score > best_m_score) {\n                    best_m_score = m_score;\n                    best_moves = {m};\n                } else if (m_score == best_m_score) {\n                    best_moves.push_back(m);\n                }\n            }\n            best_move = best_moves[rng() % best_moves.size()];\n        }\n        s.move(best_move);\n    }\n\n    // Step 4: Final Evaluation. Calculate total cost and the penalty for unfinished squares.\n    long long diff = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s.h[i][j] != 0) diff += 100LL * abs(s.h[i][j]) + 10000LL;\n        }\n    }\n    if (s.L > 0) diff += 10000LL;\n\n    // Track the best global sequence found.\n    if (s.cost + diff < best_total_cost) {\n        best_total_cost = s.cost + diff;\n        best_ops = s.ops;\n    }\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    int h[N][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    auto start_time = chrono::steady_clock::now();\n    long long best_total_cost = 8e18;\n    vector<string> best_ops;\n    mt19937 rng(1337);\n\n    // Initial heuristic parameter sets to kick off search.\n    vector<vector<double>> params = {\n        {1.5, 1.0, 0.005, 0.5},\n        {1.8, 1.2, 0.001, 0.3},\n        {1.2, 0.8, 0.010, 0.8},\n        {2.0, 0.5, 0.001, 0.6},\n        {1.4, 1.4, 0.0001, 0.9}\n    };\n    for (const auto& p : params) {\n        solve(h, p[0], p[1], p[2], p[3], best_ops, best_total_cost, rng);\n    }\n\n    // Randomized search within the execution time limit (2.0s).\n    uniform_real_distribution<double> dist_dist(1.0, 2.4);\n    uniform_real_distribution<double> soil_dist(0.3, 1.8);\n    uniform_real_distribution<double> load_dist(0.0001, 0.018);\n    uniform_real_distribution<double> sink_dist(0.1, 1.2);\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1850) {\n        solve(h, dist_dist(rng), soil_dist(rng), load_dist(rng), sink_dist(rng), best_ops, best_total_cost, rng);\n    }\n\n    // Output the results.\n    for (const string& op : best_ops) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Strategy:\n * 1. Each turn, we manage 60 seeds and must plant 36 in an N x N (6x6) grid.\n * 2. 60 edges in this grid (vertical and horizontal neighbors) will produce 60 new seeds.\n * 3. We use a potential function P(i, j) = (sum of max(seed_i.x[l], seed_j.x[l]))^2 to estimate\n *    the quality of the offspring produced by breeding seeds i and j.\n * 4. Diversity is maintained by ensuring the best seed for each criterion (dimension) is \n *    always considered for planting.\n * 5. Simulated Annealing is used to optimize the grid arrangement and seed selection from\n *    the available pool, maximizing the total potential sum of all edges.\n * 6. The SA neighborhood includes swapping two seeds on the grid and swapping a grid seed \n *    with an unused pool seed.\n */\n\nconst int N = 6;\nconst int M = 15;\nconst int T_MAX = 10;\nconst int SEED_COUNT = 60;\nconst int PLANT_COUNT = 36;\nconst int UNUSED_COUNT = 24;\n\nstruct Seed {\n    int x[M];\n    int v;\n};\n\n// P2[i][j] precomputes the potential value of offspring from seed i and seed j.\nlong long P2[SEED_COUNT][SEED_COUNT];\n\nvoid precompute_potentials(const vector<Seed>& seeds) {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = i + 1; j < SEED_COUNT; ++j) {\n            long long s_max = 0;\n            for (int l = 0; l < M; ++l) {\n                s_max += max(seeds[i].x[l], seeds[j].x[l]);\n            }\n            // Using a squared sum targets both high mean and variance in offspring.\n            P2[i][j] = P2[j][i] = s_max * s_max;\n        }\n        P2[i][i] = 0;\n    }\n}\n\nint main() {\n    // Fast Standard IO optimization.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, m_in, t_in;\n    if (!(cin >> n_in >> m_in >> t_in)) return 0;\n\n    vector<Seed> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            if (!(cin >> seeds[i].x[j])) return 0;\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    mt19937 rng(1337);\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    for (int t = 0; t < T_MAX; ++t) {\n        precompute_potentials(seeds);\n\n        // Initial Selection: Diversity (best per dimension) + top total sums.\n        vector<int> selection;\n        vector<bool> is_selected(SEED_COUNT, false);\n        for (int l = 0; l < M; ++l) {\n            int best_idx = -1, max_val = -1;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (seeds[i].x[l] > max_val) {\n                    max_val = seeds[i].x[l];\n                    best_idx = i;\n                }\n            }\n            if (best_idx != -1 && !is_selected[best_idx]) {\n                is_selected[best_idx] = true;\n                selection.push_back(best_idx);\n            }\n        }\n        vector<int> sorted_indices(SEED_COUNT);\n        iota(sorted_indices.begin(), sorted_indices.end(), 0);\n        sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n        for (int idx : sorted_indices) {\n            if (selection.size() < PLANT_COUNT && !is_selected[idx]) {\n                is_selected[idx] = true;\n                selection.push_back(idx);\n            }\n        }\n\n        // Setup the initial planting grid and the off-grid pool.\n        int grid[N][N];\n        int off_grid[UNUSED_COUNT];\n        int sel_idx = 0;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                grid[r][c] = selection[sel_idx++];\n            }\n        }\n        int off_idx = 0;\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            if (!is_selected[i]) off_grid[off_idx++] = i;\n        }\n\n        // Helper to calculate the sum of edge potentials connected to a square.\n        auto get_local_score = [&](int r, int c) {\n            long long res = 0;\n            if (r > 0) res += P2[grid[r][c]][grid[r - 1][c]];\n            if (r < N - 1) res += P2[grid[r][c]][grid[r + 1][c]];\n            if (c > 0) res += P2[grid[r][c]][grid[r][c - 1]];\n            if (c < N - 1) res += P2[grid[r][c]][grid[r][c + 1]];\n            return res;\n        };\n\n        // Current total potential of the grid.\n        long long current_total_score = 0;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r + 1 < N) current_total_score += P2[grid[r][c]][grid[r + 1][c]];\n                if (c + 1 < N) current_total_score += P2[grid[r][c]][grid[r][c + 1]];\n            }\n        }\n\n        long long best_total_score = current_total_score;\n        int best_grid[N][N];\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n\n        // Simulated Annealing Parameters.\n        auto turn_start = chrono::steady_clock::now();\n        const double TIME_LIMIT = 0.19;\n        const double start_temp = 50000.0;\n        const double end_temp = 100.0;\n        int iterations = 0;\n\n        while (true) {\n            // Check time limit periodically.\n            if ((iterations & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - turn_start).count();\n                if (elapsed > TIME_LIMIT) break;\n                double temp = start_temp * pow(end_temp / start_temp, elapsed / TIME_LIMIT);\n\n                for (int step = 0; step < 1024; ++step) {\n                    int move_type = rng() % 2;\n                    if (move_type == 0) {\n                        // Neighborhood move: Swap two grid seeds.\n                        int r1 = rng() % N, c1 = rng() % N;\n                        int r2 = rng() % N, c2 = rng() % N;\n                        if (r1 == r2 && c1 == c2) continue;\n\n                        long long old_l = get_local_score(r1, c1) + get_local_score(r2, c2);\n                        swap(grid[r1][c1], grid[r2][c2]);\n                        long long new_l = get_local_score(r1, c1) + get_local_score(r2, c2);\n                        long long diff = new_l - old_l;\n\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_score) {\n                                best_total_score = current_total_score;\n                                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid[r][c] = grid[r][c];\n                            }\n                        } else {\n                            swap(grid[r1][c1], grid[r2][c2]); // Revert move.\n                        }\n                    } else {\n                        // Neighborhood move: Swap a grid seed with a pool seed.\n                        int r = rng() % N, c = rng() % N;\n                        int idx = rng() % UNUSED_COUNT;\n\n                        long long old_l = get_local_score(r, c);\n                        swap(grid[r][c], off_grid[idx]);\n                        long long new_l = get_local_score(r, c);\n                        long long diff = new_l - old_l;\n\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_score) {\n                                best_total_score = current_total_score;\n                                for (int rr = 0; rr < N; ++rr) for (int cc = 0; cc < N; ++cc) best_grid[rr][cc] = grid[rr][cc];\n                            }\n                        } else {\n                            swap(grid[r][c], off_grid[idx]); // Revert move.\n                        }\n                    }\n                }\n            }\n            iterations++;\n        }\n\n        // Turn output.\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                cout << best_grid[r][c] << (c == N - 1 ? \"\" : \" \");\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read resulting generation for the next turn.\n        if (t < T_MAX - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                seeds[i].v = 0;\n                for (int j = 0; j < M; ++j) {\n                    if (!(cin >> seeds[i].x[j])) return 0;\n                    seeds[i].v += seeds[i].x[j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n\nusing namespace std;\n\n// Structure to track the status and destination of each takoyaki.\nstruct Takoyaki {\n    int sx, sy, tx, ty;\n    int state; // 0: at start, 1: held by a finger, 2: delivered to target\n    int finger_id;\n};\n\nint main() {\n    // Fast standard I/O for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    vector<pair<int, int>> S_pos, T_pos;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (s_grid[i][j] == '1') S_pos.push_back({i, j});\n            if (t_grid[i][j] == '1') T_pos.push_back({i, j});\n        }\n    }\n\n    // Match each takoyaki starting position to a target position greedily based on Manhattan distance.\n    vector<Takoyaki> takos(M);\n    vector<bool> target_used(M, false);\n    for (int i = 0; i < M; ++i) {\n        int best_j = -1, best_dist = 1e9;\n        for (int j = 0; j < M; ++j) {\n            if (!target_used[j]) {\n                int d = abs(S_pos[i].first - T_pos[j].first) + abs(S_pos[i].second - T_pos[j].second);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_j = j;\n                }\n            }\n        }\n        takos[i] = {S_pos[i].first, S_pos[i].second, T_pos[best_j].first, T_pos[best_j].second, 0, -1};\n        target_used[best_j] = true;\n    }\n\n    // grid_tako tracks the ID of the takoyaki currently sitting at its start square (state 0).\n    // grid_delivered tracks target squares where a takoyaki has reached its final destination.\n    vector<vector<int>> grid_tako(N, vector<int>(N, -1));\n    vector<vector<bool>> grid_delivered(N, vector<bool>(N, false));\n    int delivered_count = 0;\n    for (int i = 0; i < M; ++i) {\n        if (takos[i].sx == takos[i].tx && takos[i].sy == takos[i].ty) {\n            takos[i].state = 2;\n            delivered_count++;\n            grid_delivered[takos[i].sx][takos[i].sy] = true;\n        } else {\n            grid_tako[takos[i].sx][takos[i].sy] = i;\n        }\n    }\n\n    // Design the robotic arm as a star tree structure.\n    // Vertex 0 is the root. Fingers 1 through V-1 are leaf vertices connected to the root.\n    cout << V << \"\\n\";\n    vector<int> L(V, 0);\n    for (int i = 1; i < V; ++i) {\n        L[i] = min(i, N - 1); // Varied edge lengths: 1, 2, ..., V-1.\n        cout << 0 << \" \" << L[i] << \"\\n\";\n    }\n\n    int rx = 0, ry = 0; // Current root grid coordinates.\n    cout << rx << \" \" << ry << \"\\n\";\n\n    int dr[] = {0, 1, 0, -1}, dc[] = {1, 0, -1, 0}; // Directions: 0:Right, 1:Down, 2:Left, 3:Up.\n    vector<int> f_dir(V, 0), f_hold(V, -1);\n    int turns = 0;\n\n    // Simulation loop: continue until all takoyaki reach targets or the limit is hit.\n    while (delivered_count < M && turns < 100000) {\n        int focus_j = -1, focus_f = -1, focus_d = -1, target_rx = -1, target_ry = -1;\n        int best_cost = 1e9;\n\n        int busy_count = 0;\n        for (int i = 1; i < V; ++i) if (f_hold[i] != -1) busy_count++;\n\n        // 1. Task Selection Strategy: Prioritize delivering takoyakis already in hand.\n        for (int f = 1; f < V; f++) {\n            if (f_hold[f] != -1) {\n                int i = f_hold[f];\n                // Delivery is possible only if the target square isn't blocked by another takoyaki.\n                if (grid_tako[takos[i].tx][takos[i].ty] == -1) {\n                    for (int d = 0; d < 4; d++) {\n                        int trx = takos[i].tx - dr[d] * L[f], try_ = takos[i].ty - dc[d] * L[f];\n                        if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                            int cost = max(abs(rx - trx) + abs(ry - try_), (f_dir[f] == d ? 0 : (abs(f_dir[f] - d) == 2 ? 2 : 1)));\n                            if (cost < best_cost) {\n                                best_cost = cost; focus_j = i; focus_f = f; focus_d = d; target_rx = trx; target_ry = try_;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // 2. Pickup Logic: If hand capacity allows, look for takoyakis to pick up from the cooker.\n        // We prioritize picking up 'blockers'\u2014takoyakis sitting on the target square of something we hold.\n        if (best_cost > 30 || best_cost == 1e9) {\n            for (int i = 0; i < M; i++) {\n                if (takos[i].state == 0 && busy_count < V - 1) {\n                    bool is_blocker = false;\n                    for (int f = 1; f < V; f++) {\n                        if (f_hold[f] != -1) {\n                            int held_i = f_hold[f];\n                            if (takos[held_i].tx == takos[i].sx && takos[held_i].ty == takos[i].sy) {\n                                is_blocker = true; break;\n                            }\n                        }\n                    }\n\n                    // Always keep one finger free (if V allows) to handle potential future blockers.\n                    if (is_blocker || busy_count < max(1, V - 2)) {\n                        for (int f = 1; f < V; f++) {\n                            if (f_hold[f] == -1) {\n                                for (int d = 0; d < 4; d++) {\n                                    int trx = takos[i].sx - dr[d] * L[f], try_ = takos[i].sy - dc[d] * L[f];\n                                    if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                                        int cost = max(abs(rx - trx) + abs(ry - try_), (f_dir[f] == d ? 0 : (abs(f_dir[f] - d) == 2 ? 2 : 1)));\n                                        if (is_blocker) cost -= 2000; // Bonus to prioritize removing blocking takoyakis.\n                                        if (cost < best_cost) {\n                                            best_cost = cost; focus_j = i; focus_f = f; focus_d = d; target_rx = trx; target_ry = try_;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (focus_j == -1) break;\n\n        int initial_state = takos[focus_j].state;\n        // Inner execution loop: progress the root and fingers until the focus task goal is reached.\n        while (turns < 100000) {\n            string op_move = \"\";\n            // Move root grid position.\n            if (rx < target_rx) { rx++; op_move += 'D'; }\n            else if (rx > target_rx) { rx--; op_move += 'U'; }\n            else if (ry < target_ry) { ry++; op_move += 'R'; }\n            else if (ry > target_ry) { ry--; op_move += 'L'; }\n            else op_move += '.';\n\n            // Rotate the focus finger towards its target orientation.\n            for (int f = 1; f < V; f++) {\n                if (f == focus_f && f_dir[f] != focus_d) {\n                    if ((f_dir[f] + 1) % 4 == focus_d) { f_dir[f] = (f_dir[f] + 1) % 4; op_move += 'R'; }\n                    else { f_dir[f] = (f_dir[f] + 3) % 4; op_move += 'L'; }\n                } else op_move += '.';\n            }\n\n            // Finger actions: check if any fingertip can perform a valid P (pick or release) operation.\n            string op_act = \".\"; // Root vertex 0 doesn't pick or release.\n            for (int f = 1; f < V; f++) {\n                int fr = rx + dr[f_dir[f]] * L[f], fc = ry + dc[f_dir[f]] * L[f];\n                bool acted = false;\n                if (fr >= 0 && fr < N && fc >= 0 && fc < N) {\n                    if (f_hold[f] == -1) {\n                        int id = grid_tako[fr][fc];\n                        if (id != -1 && takos[id].state == 0) {\n                            takos[id].state = 1; takos[id].finger_id = f; f_hold[f] = id;\n                            grid_tako[fr][fc] = -1; op_act += 'P'; acted = true;\n                        }\n                    } else {\n                        int id = f_hold[f];\n                        if (fr == takos[id].tx && fc == takos[id].ty && grid_tako[fr][fc] == -1 && !grid_delivered[fr][fc]) {\n                            takos[id].state = 2; f_hold[f] = -1;\n                            grid_delivered[fr][fc] = true; delivered_count++;\n                            op_act += 'P'; acted = true;\n                        }\n                    }\n                }\n                if (!acted) op_act += '.';\n            }\n\n            cout << op_move << op_act << \"\\n\";\n            turns++;\n            if (delivered_count == M) break;\n            // Stop if the focus task state changes (e.g., reached target or picked up blocker).\n            if (takos[focus_j].state != initial_state) break;\n            // Stop if the arm is in the desired focus position.\n            if (rx == target_rx && ry == target_ry && f_dir[focus_f] == focus_d) break;\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n// Maximum grid size for DP. A larger grid improves precision but increases computation time.\nconst int G_MAX = 101;\nconst long long INF = 1e16;\nconst long long SCALE = 10000000LL; // Multiplier to prioritize fish count over perimeter.\n\nstruct Point {\n    int x, y;\n};\n\nstruct Result {\n    long long score; \n    int i_start, i_end;\n    vector<pair<int, int>> path;\n    bool swapped;\n    vector<int> xs, ys;\n};\n\n// Reusable memory for DP and grid calculations.\nstatic int cell_score[G_MAX][G_MAX];\nstatic int row_sum[G_MAX][G_MAX + 1];\nstatic long long dp[G_MAX][G_MAX][G_MAX];\nstatic pair<short, short> p_table[G_MAX][G_MAX][G_MAX];\n\n/**\n * Solves the problem by constructing an optimal x-monotone rectilinear polygon on a grid.\n */\nResult solve_with_grid(int N, const vector<Point>& macks, const vector<Point>& sards, bool swap_xy, int grid_size, int d_limit) {\n    vector<Point> m = macks, s = sards;\n    if (swap_xy) {\n        for (int i = 0; i < N; ++i) {\n            swap(m[i].x, m[i].y);\n            swap(s[i].x, s[i].y);\n        }\n    }\n\n    // Coordinate compression to create a grid focused on fish locations.\n    vector<int> X, Y;\n    for (int i = 0; i < N; ++i) {\n        X.push_back(m[i].x); Y.push_back(m[i].y);\n        X.push_back(s[i].x); Y.push_back(s[i].y);\n    }\n    X.push_back(0); X.push_back(100000);\n    Y.push_back(0); Y.push_back(100000);\n    sort(X.begin(), X.end()); X.erase(unique(X.begin(), X.end()), X.end());\n    sort(Y.begin(), Y.end()); Y.erase(unique(Y.begin(), Y.end()), Y.end());\n\n    int gx_count = min((int)X.size() - 1, grid_size);\n    int gy_count = min((int)Y.size() - 1, grid_size);\n    vector<int> xs, ys;\n    for (int i = 0; i <= gx_count; ++i) xs.push_back(X[i * (X.size() - 1) / gx_count]);\n    for (int i = 0; i <= gy_count; ++i) ys.push_back(Y[i * (Y.size() - 1) / gy_count]);\n\n    // Calculate mackerel - sardine counts per grid cell.\n    for (int i = 0; i < gx_count; ++i) for (int j = 0; j < gy_count; ++j) cell_score[i][j] = 0;\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), m[i].x) - xs.begin(); if (gx > 0 && (gx == gx_count || xs[gx] > m[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), m[i].y) - ys.begin(); if (gy > 0 && (gy == gy_count || ys[gy] > m[i].y)) gy--;\n        if (gx < gx_count && gy < gy_count) cell_score[gx][gy]++;\n    }\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), s[i].x) - xs.begin(); if (gx > 0 && (gx == gx_count || xs[gx] > s[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), s[i].y) - ys.begin(); if (gy > 0 && (gy == gy_count || ys[gy] > s[i].y)) gy--;\n        if (gx < gx_count && gy < gy_count) cell_score[gx][gy]--;\n    }\n\n    for (int i = 0; i < gx_count; ++i) {\n        row_sum[i][0] = 0;\n        for (int j = 0; j < gy_count; ++j) row_sum[i][j + 1] = row_sum[i][j] + cell_score[i][j];\n    }\n\n    // DP initialization: find best connected sequence of vertical intervals.\n    for (int i = 0; i < gx_count; ++i) \n        for (int L = 0; L < gy_count; ++L) \n            for (int R = L; R < gy_count; ++R) \n                dp[i][L][R] = -INF;\n\n    for (int i = 0; i < gx_count; ++i) {\n        long long h_cost = 2LL * (xs[i + 1] - xs[i]);\n        for (int L = 0; L < gy_count; ++L) {\n            int L1_min = max(0, L - d_limit);\n            int L1_max = min(gy_count - 1, L + d_limit);\n            for (int R = L; R < gy_count; ++R) {\n                long long cur_f = row_sum[i][R + 1] - row_sum[i][L];\n                dp[i][L][R] = cur_f * SCALE - (ys[R + 1] - ys[L]) - h_cost;\n                p_table[i][L][R] = { -1, -1 };\n                if (i > 0) {\n                    int R1_min = max({0, R - d_limit, L}); \n                    int R1_max = min(gy_count - 1, R + d_limit);\n                    for (int L1 = L1_min; L1 <= L1_max; ++L1) {\n                        for (int R1 = max(L1, R1_min); R1 <= R1_max; ++R1) {\n                            if (dp[i-1][L1][R1] == -INF || max(L, L1) > min(R, R1)) continue;\n                            long long v_cost = (long long)abs(ys[L] - ys[L1]) + abs(ys[R + 1] - ys[R1 + 1]);\n                            long long val = dp[i-1][L1][R1] + cur_f * SCALE - v_cost - h_cost;\n                            if (val > dp[i][L][R]) {\n                                dp[i][L][R] = val;\n                                p_table[i][L][R] = { (short)L1, (short)R1 };\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    long long best_a_minus_b = -1;\n    int bi = -1, bl = -1, br = -1;\n    for (int i = 0; i < gx_count; ++i) {\n        for (int L = 0; L < gy_count; ++L) {\n            for (int R = L; R < gy_count; ++R) {\n                if (dp[i][L][R] == -INF) continue;\n                long long final_fv = dp[i][L][R] - (ys[R + 1] - ys[L]);\n                long long a_minus_b = (final_fv + 5000000LL) / SCALE; \n                long long total_perim = a_minus_b * SCALE - final_fv;\n                if (total_perim <= 400000 && a_minus_b > best_a_minus_b) {\n                    best_a_minus_b = a_minus_b; bi = i; bl = L; br = R;\n                }\n            }\n        }\n    }\n\n    if (bi == -1) return { -1, -1, -1, {}, swap_xy, xs, ys };\n    vector<pair<int, int>> path;\n    int ci = bi, cl = bl, cr = br;\n    while (ci >= 0 && cl != -1) {\n        path.push_back({ cl, cr });\n        auto p = p_table[ci][cl][cr];\n        cl = p.first; cr = p.second; ci--;\n    }\n    reverse(path.begin(), path.end());\n    return { best_a_minus_b, bi - (int)path.size() + 1, bi, path, swap_xy, xs, ys };\n}\n\nvoid output(const Result& res) {\n    if (res.score <= 0) {\n        cout << \"4\\n0 0\\n0 1\\n1 1\\n1 0\" << endl;\n        return;\n    }\n    vector<pair<int, int>> v;\n    int n = res.path.size();\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].first] });\n    v.push_back({ res.xs[res.i_start], res.ys[res.path[0].second + 1] });\n    for (int i = 0; i < n - 1; ++i) {\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i].second + 1] });\n        v.push_back({ res.xs[res.i_start + i + 1], res.ys[res.path[i + 1].second + 1] });\n    }\n    v.push_back({ res.xs[res.i_end + 1], res.ys[res.path.back().second + 1] });\n    v.push_back({ res.xs[res.i_end + 1], res.ys[res.path.back().first] });\n    for (int i = n - 1; i > 0; --i) {\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i].first] });\n        v.push_back({ res.xs[res.i_start + i], res.ys[res.path[i - 1].first] });\n    }\n    if (res.swapped) for (auto& p : v) swap(p.first, p.second);\n    vector<pair<int, int>> uv;\n    for (auto p : v) if (uv.empty() || p != uv.back()) uv.push_back(p);\n    if (uv.size() > 1 && uv.front() == uv.back()) uv.pop_back();\n    cout << uv.size() << endl;\n    for (auto p : uv) cout << p.first << \" \" << p.second << endl;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    int N; if (!(cin >> N)) return 0;\n    vector<Point> macks(N), sards(N);\n    for (int i = 0; i < N; ++i) cin >> macks[i].x >> macks[i].y;\n    for (int i = 0; i < N; ++i) cin >> sards[i].x >> sards[i].y;\n\n    Result best_res = { -1, -1, -1, {}, false, {}, {} };\n    for (bool s_xy : {false, true}) {\n        Result res = solve_with_grid(N, macks, sards, s_xy, 90, 7);\n        if (res.score > best_res.score) best_res = res;\n    }\n    output(best_res);\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Representation of a rectangle's placement on a 2D grid\nstruct Rect {\n    long long x, y, xw, yh;\n};\n\n// Arrangement configuration for N rectangles\nstruct Config {\n    int r[100]; // 0: no rotation, 1: 90-degree rotation\n    int d[100]; // 0: 'U' (fixed x, moves toward y=0), 1: 'L' (fixed y, moves toward x=0)\n    int b[100]; // Reference rectangle index, -1 for coordinate axes\n};\n\n// Global arrays for tracking overlap dependencies to allow path tracing\nint parentX[100], parentY[100];\n\n/**\n * Calculates the bounding box and placement of N rectangles.\n * Returns the {Width, Height} of the bounding box.\n */\npair<long long, long long> evaluate(int N, const Config& conf, Rect* p, const vector<long long>& w, const vector<long long>& h, int start_idx = 0) {\n    for (int i = start_idx; i < N; ++i) {\n        long long cur_w = conf.r[i] ? h[i] : w[i];\n        long long cur_h = conf.r[i] ? w[i] : h[i];\n        long long x = 0, y = 0;\n        parentX[i] = -1;\n        parentY[i] = -1;\n        \n        if (conf.d[i] == 0) { // Upward placement ('U')\n            x = (conf.b[i] == -1) ? 0 : p[conf.b[i]].xw;\n            for (int j = 0; j < i; ++j) {\n                if (x < p[j].xw && p[j].x < x + cur_w) {\n                    if (p[j].yh > y) {\n                        y = p[j].yh;\n                        parentY[i] = j;\n                    }\n                }\n            }\n        } else { // Leftward placement ('L')\n            y = (conf.b[i] == -1) ? 0 : p[conf.b[i]].yh;\n            for (int j = 0; j < i; ++j) {\n                if (y < p[j].yh && p[j].y < y + cur_h) {\n                    if (p[j].xw > x) {\n                        x = p[j].xw;\n                        parentX[i] = j;\n                    }\n                }\n            }\n        }\n        p[i] = {x, y, x + cur_w, y + cur_h};\n    }\n    \n    long long max_w = 0, max_h = 0;\n    for (int i = 0; i < N; ++i) {\n        max_w = max(max_w, p[i].xw);\n        max_h = max(max_h, p[i].yh);\n    }\n    return {max_w, max_h};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T_turns;\n    double sigma_val;\n    if (!(cin >> N >> T_turns >> sigma_val)) return 0;\n\n    // Initial width and height observations\n    vector<double> w_est(N), h_est(N);\n    vector<double> current_sigma(N, sigma_val);\n    vector<int> count_measurements(N, 1);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_time = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    mt19937 rng(1337);\n    Config best_ever_conf;\n    for (int i = 0; i < N; ++i) {\n        best_ever_conf.r[i] = (w_est[i] < h_est[i] ? 1 : 0);\n        best_ever_conf.d[i] = rng() % 2;\n        best_ever_conf.b[i] = (int)(rng() % (i + 1)) - 1;\n    }\n    long long best_ever_score = -1;\n\n    // Phase 1: Direct Measurement turns\n    int M = min(N, T_turns / 2);\n    for (int t = 0; t < M; ++t) {\n        cout << 1 << \"\\n\" << t << \" 0 U -1\\n\" << flush;\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) return 0;\n        w_est[t] = (w_est[t] * count_measurements[t] + W_p) / (count_measurements[t] + 1.0);\n        h_est[t] = (h_est[t] * count_measurements[t] + H_p) / (count_measurements[t] + 1.0);\n        count_measurements[t]++;\n        current_sigma[t] = sigma_val / sqrt(count_measurements[t]);\n    }\n\n    Rect placed[100];\n    \n    // Phase 2: Packing and refinement using Simulated Annealing\n    for (int t = M; t < T_turns; ++t) {\n        double turn_start_time = elapsed_time();\n        double turn_time_limit = (2.90 - turn_start_time) / (T_turns - t);\n\n        // Thompson Sampling: sample true dimensions from our current posterior\n        vector<long long> w_sample(N), h_sample(N);\n        for (int i = 0; i < N; ++i) {\n            normal_distribution<double> dist_w(w_est[i], current_sigma[i]);\n            normal_distribution<double> dist_h(h_est[i], current_sigma[i]);\n            w_sample[i] = max(1LL, (long long)round(dist_w(rng)));\n            h_sample[i] = max(1LL, (long long)round(dist_h(rng)));\n        }\n\n        Config current_conf = best_ever_conf;\n        auto initial_eval = evaluate(N, current_conf, placed, w_sample, h_sample);\n        long long current_score = initial_eval.first + initial_eval.second;\n        Config best_in_turn = current_conf;\n        long long best_score_in_turn = current_score;\n\n        // SA Parameters\n        double t_start = sigma_val;\n        double t_end = 1.0;\n        uniform_real_distribution<double> dist01(0, 1);\n\n        // Run SA for the turn's time slice\n        while (elapsed_time() - turn_start_time < turn_time_limit) {\n            int k = rng() % N;\n            int old_r = current_conf.r[k], old_d = current_conf.d[k], old_b = current_conf.b[k];\n            Rect backup_p[100];\n            for (int i = k; i < N; ++i) backup_p[i] = placed[i];\n\n            int type = rng() % 3;\n            if (type == 0) current_conf.r[k] = 1 - current_conf.r[k];\n            else if (type == 1) current_conf.d[k] = 1 - current_conf.d[k];\n            else current_conf.b[k] = (int)(rng() % (k + 1)) - 1;\n\n            auto n_res = evaluate(N, current_conf, placed, w_sample, h_sample, k);\n            long long n_score = n_res.first + n_res.second;\n\n            double ratio = (elapsed_time() - turn_start_time) / turn_time_limit;\n            double temp = t_start * pow(t_end / t_start, ratio);\n\n            if (n_score < current_score || dist01(rng) < exp((double)(current_score - n_score) / temp)) {\n                current_score = n_score;\n                if (n_score < best_score_in_turn) {\n                    best_score_in_turn = n_score;\n                    best_in_turn = current_conf;\n                }\n            } else {\n                current_conf.r[k] = old_r; current_conf.d[k] = old_d; current_conf.b[k] = old_b;\n                for (int i = k; i < N; ++i) placed[i] = backup_p[i];\n            }\n        }\n\n        // Send current best configuration to the judge\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; ++i) cout << i << \" \" << best_in_turn.r[i] << \" \" << (best_in_turn.d[i] == 0 ? 'U' : 'L') << \" \" << best_in_turn.b[i] << \"\\n\";\n        cout << flush;\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n\n        // Trace the width and height critical paths to slightly nudge estimates\n        vector<long long> w_ll(N), h_ll(N);\n        for(int i=0; i<N; ++i) { w_ll[i] = (long long)round(w_est[i]); h_ll[i] = (long long)round(h_est[i]); }\n        auto final_res = evaluate(N, best_in_turn, placed, w_ll, h_ll);\n\n        auto trace = [&](bool isW, long long target) {\n            vector<int> path;\n            int cur = -1;\n            for (int i = 0; i < N; ++i) { if ((isW ? placed[i].xw : placed[i].yh) == target) { cur = i; break; } }\n            while (cur != -1) {\n                path.push_back(cur);\n                if (isW) cur = (best_in_turn.d[cur] == 0 ? best_in_turn.b[cur] : parentX[cur]);\n                else cur = (best_in_turn.d[cur] == 1 ? best_in_turn.b[cur] : parentY[cur]);\n            }\n            return path;\n        };\n\n        vector<int> pW = trace(true, final_res.first);\n        vector<int> pH = trace(false, final_res.second);\n        double errW = (double)(W_p - final_res.first);\n        double errH = (double)(H_p - final_res.second);\n        for (int i : pW) { if (best_in_turn.r[i] == 0) w_est[i] += errW / pW.size() * 0.1; else h_est[i] += errW / pW.size() * 0.1; }\n        for (int i : pH) { if (best_in_turn.r[i] == 0) h_est[i] += errH / pH.size() * 0.1; else w_est[i] += errH / pH.size() * 0.1; }\n\n        if (best_ever_score == -1 || W_p + H_p < best_ever_score) {\n            best_ever_score = W_p + H_p;\n            best_ever_conf = best_in_turn;\n        }\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#include <numeric>\n\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int H_LIMIT = 10;\n\nint N, M, H_input;\nlong long A[MAXN];\nvector<int> adj[MAXN];\nint parent_v[MAXN];\nvector<int> children_v[MAXN];\nint depth_v[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_depth_rel[MAXN];\n\n// Fast check for ancestor within height limit to prevent cycles\nbool is_ancestor(int u, int v) {\n    if (u == -1) return false;\n    int curr = v;\n    int count = 0;\n    while (curr != -1 && count <= H_LIMIT + 2) {\n        if (curr == u) return true;\n        curr = parent_v[curr];\n        count++;\n    }\n    return false;\n}\n\n// Recompute beauty sum and relative max depth for node u\nvoid recompute_node_metrics(int u) {\n    long long sum = A[u];\n    int mx = 0;\n    for (int child : children_v[u]) {\n        sum += subtree_sum_A[child];\n        mx = max(mx, max_depth_rel[child] + 1);\n    }\n    subtree_sum_A[u] = sum;\n    max_depth_rel[u] = mx;\n}\n\n// Update a node and its ancestors after a change in its subtree\nvoid update_ancestors(int u) {\n    int count = 0;\n    while (u != -1 && count <= H_LIMIT + 2) {\n        long long old_sum = subtree_sum_A[u];\n        int old_mx = max_depth_rel[u];\n        recompute_node_metrics(u);\n        if (subtree_sum_A[u] == old_sum && max_depth_rel[u] == old_mx) break;\n        u = parent_v[u];\n        count++;\n    }\n}\n\n// Propagate depth changes down the subtree\nvoid update_subtree_depth(int u, int d) {\n    depth_v[u] = d;\n    for (int child : children_v[u]) {\n        update_subtree_depth(child, d + 1);\n    }\n}\n\n// Move a node and its entire subtree to a new parent\nvoid move_v(int v, int new_p) {\n    int old_p = parent_v[v];\n    if (old_p != -1) {\n        auto& cv = children_v[old_p];\n        for (size_t i = 0; i < cv.size(); ++i) {\n            if (cv[i] == v) {\n                cv[i] = cv.back();\n                cv.pop_back();\n                break;\n            }\n        }\n        update_ancestors(old_p);\n    }\n    parent_v[v] = new_p;\n    if (new_p != -1) {\n        children_v[new_p].push_back(v);\n        update_subtree_depth(v, depth_v[new_p] + 1);\n        update_ancestors(new_p);\n    } else {\n        update_subtree_depth(v, 0);\n        update_ancestors(-1); \n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> H_input)) 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; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    for (int i = 0; i < N; ++i) {\n        parent_v[i] = -1; depth_v[i] = 0; children_v[i].clear();\n        subtree_sum_A[i] = A[i]; max_depth_rel[i] = 0;\n    }\n\n    mt19937 mt(42);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    sort(nodes.begin(), nodes.end(), [&](int i, int j) { return A[i] > A[j]; });\n\n    // Greedy start\n    for (int v : nodes) {\n        int best_p = -1, max_h = -1;\n        for (int p : adj[v]) {\n            if (!is_ancestor(v, p) && depth_v[p] + 1 + max_depth_rel[v] <= H_LIMIT) {\n                if (depth_v[p] > max_h) { max_h = depth_v[p]; best_p = p; }\n            }\n        }\n        if (best_p != -1) move_v(v, best_p);\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    double T_start = 2000.0, T_end = 0.1, log_T_ratio = log(T_end / T_start);\n    long long iter = 0; \n    double T = T_start;\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Simulated Annealing\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 1.92) break;\n            T = T_start * exp(log_T_ratio * (elapsed / 1.92));\n        }\n        iter++;\n        int v = mt() % N;\n        int deg = (int)adj[v].size();\n        int r = mt() % (deg + 1);\n        int new_p = (r == deg) ? -1 : adj[v][r];\n\n        if (new_p == parent_v[v]) continue;\n\n        bool ok = (new_p == -1) || (depth_v[new_p] + 1 + max_depth_rel[v] <= H_LIMIT && !is_ancestor(v, new_p));\n        if (ok) {\n            int old_d = depth_v[v];\n            int new_d = (new_p == -1 ? 0 : depth_v[new_p] + 1);\n            long long delta = (long long)(new_d - old_d) * subtree_sum_A[v];\n            if (delta >= 0 || (T > 0 && dist(mt) < exp((double)delta / T))) {\n                move_v(v, new_p);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << parent_v[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#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Optimized Solver for \"Oni wa Soto, Fuku wa Uchi\"\n * \n * Strategy:\n * 1. Pre-calculate safe directions (L, R, U, D) for each Oni where no Fukunokami \n *    is in the path to the edge.\n * 2. Simulated Annealing is used to assign each Oni to one of its safe directions.\n * 3. The movement strategy consists of two phases: \n *    - Phase 1 (First Dimension): Shift rows/columns to remove Oni and return \n *      the row/column to its original state.\n *    - Phase 2 (Last Dimension): Shift rows/columns to remove Oni and omit the \n *      final return shift to minimize moves.\n * 4. The SA minimizes total move count T and optimizes whether to process rows or columns last.\n */\n\nconst int N = 20;\n\nstruct Oni {\n    int r, c;\n    vector<int> safe_dirs; // 0:L, 1:R, 2:U, 3:D\n};\n\ninline int cost_last_dim(int m1, int m2) {\n    if (m1 > 0 && m2 > 0) return min(2 * m1 + m2, 2 * m2 + m1);\n    return max(m1, m2);\n}\n\ninline int cost_first_dim(int m1, int m2) {\n    return 2 * (m1 + m2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_val;\n    if (!(cin >> n_val)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    vector<Oni> onis;\n    vector<int> row_onis[N], col_onis[N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                Oni oni; oni.r = i; oni.c = j;\n                bool l_s = true; for (int k = 0; k <= j; ++k) if (board[i][k] == 'o') l_s = false;\n                if (l_s) oni.safe_dirs.push_back(0);\n                bool r_s = true; for (int k = j; k < N; ++k) if (board[i][k] == 'o') r_s = false;\n                if (r_s) oni.safe_dirs.push_back(1);\n                bool u_s = true; for (int k = 0; k <= i; ++k) if (board[k][j] == 'o') u_s = false;\n                if (u_s) oni.safe_dirs.push_back(2);\n                bool d_s = true; for (int k = i; k < N; ++k) if (board[k][j] == 'o') d_s = false;\n                if (d_s) oni.safe_dirs.push_back(3);\n                row_onis[i].push_back((int)onis.size());\n                col_onis[j].push_back((int)onis.size());\n                onis.push_back(oni);\n            }\n        }\n    }\n\n    if (onis.empty()) return 0;\n\n    mt19937 rng(42);\n    vector<int> current_dirs(onis.size());\n    int L[N] = {0}, R[N] = {0}, U[N] = {0}, D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); ++i) {\n        current_dirs[i] = onis[i].safe_dirs[rng() % onis[i].safe_dirs.size()];\n        if (current_dirs[i] == 0) L[onis[i].r] = max(L[onis[i].r], onis[i].c + 1);\n        else if (current_dirs[i] == 1) R[onis[i].r] = max(R[onis[i].r], N - onis[i].c);\n        else if (current_dirs[i] == 2) U[onis[i].c] = max(U[onis[i].c], onis[i].r + 1);\n        else if (current_dirs[i] == 3) D[onis[i].c] = max(D[onis[i].c], N - onis[i].r);\n    }\n\n    int total_L_R_first = 0, total_L_R_last = 0;\n    int total_U_D_first = 0, total_U_D_last = 0;\n    for (int i = 0; i < N; i++) {\n        total_L_R_first += cost_first_dim(L[i], R[i]);\n        total_L_R_last += cost_last_dim(L[i], R[i]);\n        total_U_D_first += cost_first_dim(U[i], D[i]);\n        total_U_D_last += cost_last_dim(U[i], D[i]);\n    }\n\n    int current_cost = min(total_L_R_last + total_U_D_first, total_L_R_first + total_U_D_last);\n    auto start_time = chrono::steady_clock::now();\n    double start_temp = 2.0, end_temp = 0.0;\n    long long iter = 0;\n\n    while (true) {\n        if ((iter & 511) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (elapsed > 1950) break;\n            double progress = elapsed / 1950.0;\n            double temp = start_temp + (end_temp - start_temp) * progress;\n\n            for (int sub = 0; sub < 512; sub++) {\n                int k = rng() % onis.size();\n                if (onis[k].safe_dirs.size() <= 1) continue;\n                int old_d = current_dirs[k];\n                int next_d = onis[k].safe_dirs[rng() % onis[k].safe_dirs.size()];\n                if (next_d == old_d) continue;\n\n                int row = onis[k].r, col = onis[k].c;\n                int old_L = L[row], old_R = R[row], old_U = U[col], old_D = D[col];\n\n                current_dirs[k] = next_d;\n                if (old_d == 0) {\n                    L[row] = 0;\n                    for (int idx : row_onis[row]) if (current_dirs[idx] == 0) L[row] = max(L[row], onis[idx].c + 1);\n                } else if (old_d == 1) {\n                    R[row] = 0;\n                    for (int idx : row_onis[row]) if (current_dirs[idx] == 1) R[row] = max(R[row], N - onis[idx].c);\n                } else if (old_d == 2) {\n                    U[col] = 0;\n                    for (int idx : col_onis[col]) if (current_dirs[idx] == 2) U[col] = max(U[col], onis[idx].r + 1);\n                } else if (old_d == 3) {\n                    D[col] = 0;\n                    for (int idx : col_onis[col]) if (current_dirs[idx] == 3) D[col] = max(D[col], N - onis[idx].r);\n                }\n\n                if (next_d == 0) L[row] = max(L[row], onis[k].c + 1);\n                else if (next_d == 1) R[row] = max(R[row], N - onis[k].c);\n                else if (next_d == 2) U[col] = max(U[col], onis[k].r + 1);\n                else if (next_d == 3) D[col] = max(D[col], N - onis[k].r);\n\n                int next_L_R_first = total_L_R_first - cost_first_dim(old_L, old_R) + cost_first_dim(L[row], R[row]);\n                int next_L_R_last = total_L_R_last - cost_last_dim(old_L, old_R) + cost_last_dim(L[row], R[row]);\n                int next_U_D_first = total_U_D_first - cost_first_dim(old_U, old_D) + cost_first_dim(U[col], D[col]);\n                int next_U_D_last = total_U_D_last - cost_last_dim(old_U, old_D) + cost_last_dim(U[col], D[col]);\n                int next_cost = min(next_L_R_last + next_U_D_first, next_L_R_first + next_U_D_last);\n\n                int diff = next_cost - current_cost;\n                if (diff <= 0 || (temp > 0 && exp(-diff / temp) > (double)rng() / rng.max())) {\n                    current_cost = next_cost;\n                    total_L_R_first = next_L_R_first; total_L_R_last = next_L_R_last;\n                    total_U_D_first = next_U_D_first; total_U_D_last = next_U_D_last;\n                } else {\n                    current_dirs[k] = old_d;\n                    L[row] = old_L; R[row] = old_R; U[col] = old_U; D[col] = old_D;\n                }\n            }\n        }\n        iter++;\n    }\n\n    int final_L[N] = {0}, final_R[N] = {0}, final_U[N] = {0}, final_D[N] = {0};\n    for (int i = 0; i < (int)onis.size(); i++) {\n        if (current_dirs[i] == 0) final_L[onis[i].r] = max(final_L[onis[i].r], onis[i].c + 1);\n        else if (current_dirs[i] == 1) final_R[onis[i].r] = max(final_R[onis[i].r], N - onis[i].c);\n        else if (current_dirs[i] == 2) final_U[onis[i].c] = max(final_U[onis[i].c], onis[i].r + 1);\n        else if (current_dirs[i] == 3) final_D[onis[i].c] = max(final_D[onis[i].c], N - onis[i].r);\n    }\n\n    auto exec_ph1 = [&](char d1, char d2, int id, int m1, int m2) {\n        if (m1 > 0 && m2 > 0) {\n            for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\";\n            for (int k = 0; k < m1 + m2; k++) cout << d2 << \" \" << id << \"\\n\";\n            for (int k = 0; k < m2; k++) cout << d1 << \" \" << id << \"\\n\";\n        } else if (m1 > 0) {\n            for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\";\n            for (int k = 0; k < m1; k++) cout << d2 << \" \" << id << \"\\n\";\n        } else if (m2 > 0) {\n            for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\";\n            for (int k = 0; k < m2; k++) cout << d1 << \" \" << id << \"\\n\";\n        }\n    };\n\n    auto exec_ph2 = [&](char d1, char d2, int id, int m1, int m2) {\n        if (m1 > 0 && m2 > 0) {\n            if (2 * m1 + m2 < 2 * m2 + m1) {\n                for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\";\n                for (int k = 0; k < m1 + m2; k++) cout << d2 << \" \" << id << \"\\n\";\n            } else {\n                for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\";\n                for (int k = 0; k < m2 + m1; k++) cout << d1 << \" \" << id << \"\\n\";\n            }\n        } else if (m1 > 0) for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\";\n        else if (m2 > 0) for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\";\n    };\n\n    if (total_L_R_last + total_U_D_first <= total_L_R_first + total_U_D_last) {\n        for (int j = 0; j < N; j++) exec_ph1('U', 'D', j, final_U[j], final_D[j]);\n        for (int i = 0; i < N; i++) exec_ph2('L', 'R', i, final_L[i], final_R[i]);\n    } else {\n        for (int i = 0; i < N; i++) exec_ph1('L', 'R', i, final_L[i], final_R[i]);\n        for (int j = 0; j < N; j++) exec_ph2('U', 'D', j, final_U[j], final_D[j]);\n    }\n\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We need to determine two integers a_i and b_i for each employee i (0 to N-1).\n * Weekly cleaners are decided by the previous cleaner's visit parity.\n * Objective: Minimize sum |actual_visit_count_i - target_T_i| over L weeks.\n *\n * Strategy:\n * 1. Proxy Cost Optimization:\n *    Use the flow balance equations based on parity:\n *    t_j \u2248 delta_{j,0} + sum_{i} (ceil(T_i/2) * [a_i=j] + floor(T_i/2) * [b_i=j])\n *    Minimize sum |t_j - target_T_j| using Simulated Annealing.\n *    This ensures the overall network structure supports the target counts.\n * 2. Fine-Tuning:\n *    Use Hill Climbing based on actual 500,000-week simulations to account for\n *    transient behavior and the exact L-week limit.\n */\n\nconst int N = 100;\nlong long target_T[N];\nint best_final_a[N], best_final_b[N];\nlong long min_actual_err = -1;\n\nlong long U_calls[N], V_calls[N];\n\n// Buffers for proxy cost calculation\nbool reachable[N];\nlong long cur_t_arr[N];\nint bfs_q[N];\nint sim_counts[N];\n\n/**\n * Calculates a proxy error based on target transitions.\n * If target_T[i] visits to node i occur, it sends ceil(target_T[i]/2) to a_i\n * and floor(target_T[i]/2) to b_i.\n */\nlong long get_proxy_cost(const int* a, const int* b) {\n    fill(reachable, reachable + N, false);\n    fill(cur_t_arr, cur_t_arr + N, 0);\n    \n    // Check reachability from starting node 0\n    int head = 0, tail = 0;\n    bfs_q[tail++] = 0;\n    reachable[0] = true;\n    while (head < tail) {\n        int u = bfs_q[head++];\n        int na = a[u];\n        if (!reachable[na]) {\n            reachable[na] = true;\n            bfs_q[tail++] = na;\n        }\n        int nb = b[u];\n        if (!reachable[nb]) {\n            reachable[nb] = true;\n            bfs_q[tail++] = nb;\n        }\n    }\n    \n    // Start count for week 1\n    cur_t_arr[0] = 1;\n    // Calculate expected inflows from reachable nodes\n    for (int i = 0; i < N; ++i) {\n        if (reachable[i]) {\n            cur_t_arr[a[i]] += U_calls[i];\n            cur_t_arr[b[i]] += V_calls[i];\n        }\n    }\n    \n    long long err = 0;\n    for (int i = 0; i < N; ++i) {\n        // Heavy penalty for unreachable nodes that should have cleanings\n        if (!reachable[i] && target_T[i] > 0) {\n            err += 1000000LL + target_T[i];\n        }\n        err += abs(cur_t_arr[i] - target_T[i]);\n    }\n    return err;\n}\n\n/**\n * Performs a full L-week simulation to calculate exact visit counts.\n * Complexity: O(L), where L = 500,000.\n */\nlong long get_actual_err(const int* a, const int* b, int L) {\n    fill(sim_counts, sim_counts + N, 0);\n    int curr = 0;\n    for (int w = 0; w < L; ++w) {\n        sim_counts[curr]++;\n        if (sim_counts[curr] & 1) curr = a[curr];\n        else curr = b[curr];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; ++i) err += abs((long long)sim_counts[i] - target_T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, l_in;\n    if (!(cin >> n_in >> l_in)) return 0;\n    for (int i = 0; i < N; ++i) cin >> target_T[i];\n\n    // Precompute call distributions for each node's target visit count\n    for (int i = 0; i < N; ++i) {\n        U_calls[i] = (target_T[i] + 1) / 2;\n        V_calls[i] = target_T[i] / 2;\n    }\n\n    mt19937 mt(1337);\n    int cur_a[N], cur_b[N];\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = mt() % N;\n        cur_b[i] = mt() % N;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Step 1: Simulated Annealing for proxy error optimization\n    long long cur_proxy_err = get_proxy_cost(cur_a, cur_b);\n    long long best_step1_err = cur_proxy_err;\n    int best_step1_a[N], best_step1_b[N];\n    for(int i=0; i<N; ++i) { best_step1_a[i] = cur_a[i]; best_step1_b[i] = cur_b[i]; }\n\n    const double duration_step1 = 1.0;\n    const double t_start = 2500.0, t_end = 0.1;\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > duration_step1) break;\n        }\n        iters++;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long next_proxy_err = get_proxy_cost(cur_a, cur_b);\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double temp = t_start * pow(t_end / t_start, elapsed / duration_step1);\n        \n        if (next_proxy_err <= cur_proxy_err || \n            (double)mt() / mt.max() < exp((double)(cur_proxy_err - next_proxy_err) / temp)) {\n            cur_proxy_err = next_proxy_err;\n            if (cur_proxy_err < best_step1_err) {\n                best_step1_err = cur_proxy_err;\n                for(int k=0; k<N; ++k) { best_step1_a[k] = cur_a[k]; best_step1_b[k] = cur_b[k]; }\n            }\n        } else {\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Initialize current state with the best found in Step 1\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = best_step1_a[i];\n        cur_b[i] = best_step1_b[i];\n        best_final_a[i] = cur_a[i];\n        best_final_b[i] = cur_b[i];\n    }\n    min_actual_err = get_actual_err(cur_a, cur_b, l_in);\n    \n    // Step 2: Hill Climbing with Actual Simulation for fine-tuning\n    const double duration_total = 1.95;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > duration_total) break;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long actual_err = get_actual_err(cur_a, cur_b, l_in);\n        if (actual_err <= min_actual_err) {\n            min_actual_err = actual_err;\n            for (int i = 0; i < N; ++i) {\n                best_final_a[i] = cur_a[i];\n                best_final_b[i] = cur_b[i];\n            }\n        } else {\n            // Revert on worse score\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Output the final optimal cleaning plan transitions\n    for (int i = 0; i < N; ++i) {\n        cout << best_final_a[i] << \" \" << best_final_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct DSU {\n    vector<int> p;\n    int comps;\n    DSU(int n) : p(n), comps(n) {\n        for (int i = 0; i < n; i++) p[i] = i;\n    }\n    int find(int i) {\n        if (p[i] == i) return i;\n        return p[i] = find(p[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            p[root_i] = root_j;\n            comps--;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v;\n    long long w;\n    bool operator<(const Edge& other) const {\n        if (w != other.w) return w < other.w;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\ndouble hat_x[800], hat_y[800];\nlong long center_dist[800][800];\nvector<int> groups[400];\nint group_id[800];\nint index_in_group[800];\ndouble sum_x[400], sum_y[400], sum_x2[400], sum_y2[400];\nbool is_query_tested[800][800];\nbool is_query_selected[800][800];\n\nvoid update_group_stats(int k, int city, bool adding) {\n    if (adding) {\n        sum_x[k] += hat_x[city];\n        sum_x2[k] += hat_x[city] * hat_x[city];\n        sum_y[k] += hat_y[city];\n        sum_y2[k] += hat_y[city] * hat_y[city];\n    } else {\n        sum_x[k] -= hat_x[city];\n        sum_x2[k] -= hat_x[city] * hat_x[city];\n        sum_y[k] -= hat_y[city];\n        sum_y2[k] -= hat_y[city] * hat_y[city];\n    }\n}\n\ndouble get_group_cost(int k) {\n    int n = G[k];\n    if (n == 0) return 0;\n    double cx2 = sum_x2[k] - (sum_x[k] * sum_x[k] / n);\n    double cy2 = sum_y2[k] - (sum_y[k] * sum_y[k] / n);\n    return max(0.0, cx2 + cy2);\n}\n\nvoid bisect(vector<int> cities, int g_start, int g_end, int depth) {\n    if (g_start + 1 == g_end) {\n        groups[g_start] = cities;\n        return;\n    }\n    int mid = (g_start + g_end) / 2;\n    int left_n = 0;\n    for (int i = g_start; i < mid; i++) left_n += G[i];\n    if (depth % 2 == 0) sort(cities.begin(), cities.end(), [&](int a, int b) { return hat_x[a] < hat_x[b]; });\n    else sort(cities.begin(), cities.end(), [&](int a, int b) { return hat_y[a] < hat_y[b]; });\n    vector<int> left_cities(cities.begin(), cities.begin() + left_n);\n    vector<int> right_cities(cities.begin() + left_n, cities.end());\n    bisect(left_cities, g_start, mid, depth + 1);\n    bisect(right_cities, mid, g_end, depth + 1);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(NULL);\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    for (int i = 0; i < N; i++) {\n        double lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        hat_x[i] = (lx + rx) / 2.0; hat_y[i] = (ly + ry) / 2.0;\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) center_dist[i][j] = 0;\n            else {\n                double dx = hat_x[i] - hat_x[j], dy = hat_y[i] - hat_y[j];\n                center_dist[i][j] = (long long)floor(sqrt(dx * dx + dy * dy) + 1e-9);\n            }\n        }\n    }\n    vector<int> all_cities(N);\n    for (int i = 0; i < N; i++) all_cities[i] = i;\n    bisect(all_cities, 0, M, 0);\n    for (int k = 0; k < M; k++) {\n        sum_x[k] = sum_y[k] = sum_x2[k] = sum_y2[k] = 0;\n        for (int i = 0; i < (int)groups[k].size(); i++) {\n            int c = groups[k][i]; group_id[c] = k; index_in_group[c] = i;\n            update_group_stats(k, c, true);\n        }\n    }\n    mt19937 rng(42);\n    auto sa_start = chrono::steady_clock::now();\n    double T_start = 1000000.0, T_end = 1.0;\n    int iterations = 0;\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - sa_start).count();\n            if (elapsed > 0.6) break;\n            double T = T_start * pow(T_end / T_start, elapsed / 0.6);\n            for (int step = 0; step < 1024; step++) {\n                int u = rng() % N, v = rng() % N;\n                int gU = group_id[u], gV = group_id[v];\n                if (gU == gV) continue;\n                double old_c = get_group_cost(gU) + get_group_cost(gV);\n                update_group_stats(gU, u, false); update_group_stats(gU, v, true);\n                update_group_stats(gV, v, false); update_group_stats(gV, u, true);\n                double new_c = get_group_cost(gU) + get_group_cost(gV);\n                if (new_c < old_c || uniform_real_distribution<double>(0, 1)(rng) < exp((old_c - new_c) / T)) {\n                    int idx_u = index_in_group[u], idx_v = index_in_group[v];\n                    groups[gU][idx_u] = v; groups[gV][idx_v] = u;\n                    group_id[u] = gV; group_id[v] = gU;\n                    index_in_group[u] = idx_v; index_in_group[v] = idx_u;\n                } else {\n                    update_group_stats(gU, v, false); update_group_stats(gU, u, true);\n                    update_group_stats(gV, u, false); update_group_stats(gV, v, true);\n                }\n            }\n            iterations += 1024;\n        }\n    }\n    vector<int> local_idx(N);\n    vector<DSU> dsus;\n    for (int k = 0; k < M; k++) {\n        dsus.emplace_back(G[k]);\n        for (int i = 0; i < (int)groups[k].size(); i++) local_idx[groups[k][i]] = i;\n    }\n    int q_made = 0;\n    bool changed = true;\n    while (q_made < Q && changed) {\n        changed = false;\n        for (int k = 0; k < M; k++) {\n            if (q_made >= Q) break;\n            if (G[k] < 2 || dsus[k].comps == 1) continue;\n            int u_b = -1, v_b = -1; long long d_m = 2e18;\n            for (int i = 0; i < G[k]; i++) {\n                for (int j = i + 1; j < G[k]; j++) {\n                    if (dsus[k].find(i) != dsus[k].find(j)) {\n                        if (center_dist[groups[k][i]][groups[k][j]] < d_m) {\n                            d_m = center_dist[groups[k][i]][groups[k][j]]; u_b = i; v_b = j;\n                        }\n                    }\n                }\n            }\n            if (u_b != -1) {\n                vector<int> C = {groups[k][u_b], groups[k][v_b]};\n                vector<bool> in_C(N, false); in_C[C[0]] = true; in_C[C[1]] = true;\n                while ((int)C.size() < min(L, G[k])) {\n                    int w_b = -1; long long d_w = 2e18;\n                    for (int city : groups[k]) if (!in_C[city]) {\n                        for (int cc : C) if (center_dist[city][cc] < d_w) { d_w = center_dist[city][cc]; w_b = city; }\n                    }\n                    if (w_b != -1) { C.push_back(w_b); in_C[w_b] = true; } else break;\n                }\n                sort(C.begin(), C.end()); cout << \"? \" << C.size();\n                for (int c : C) cout << \" \" << c; cout << endl;\n                q_made++;\n                for (int i = 0; i < (int)C.size(); i++) for (int j = i + 1; j < (int)C.size(); j++) \n                    is_query_tested[C[i]][C[j]] = is_query_tested[C[j]][C[i]] = true;\n                for (int i = 0; i < (int)C.size() - 1; i++) {\n                    int a, b; cin >> a >> b;\n                    is_query_selected[a][b] = is_query_selected[b][a] = true;\n                    dsus[k].unite(local_idx[a], local_idx[b]);\n                }\n                changed = true;\n            }\n        }\n    }\n    while (q_made < Q) {\n        int k = rng() % M; if (G[k] < 2) continue;\n        vector<int> C = groups[k]; shuffle(C.begin(), C.end(), rng);\n        if ((int)C.size() > L) C.resize(L); sort(C.begin(), C.end());\n        cout << \"? \" << C.size(); for (int c : C) cout << \" \" << c; cout << endl;\n        q_made++;\n        for (int i = 0; i < (int)C.size(); i++) for (int j = i + 1; j < (int)C.size(); j++) \n            is_query_tested[C[i]][C[j]] = is_query_tested[C[j]][C[i]] = true;\n        for (int i = 0; i < (int)C.size() - 1; i++) { int a, b; cin >> a >> b; is_query_selected[a][b] = is_query_selected[b][a] = true; }\n    }\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < G[k]; i++) cout << groups[k][i] << (i == G[k] - 1 ? \"\" : \" \"); cout << endl;\n        if (G[k] > 1) {\n            vector<Edge> c_e;\n            for (int i = 0; i < G[k]; i++) for (int j = i + 1; j < G[k]; j++) {\n                int u = min(groups[k][i], groups[k][j]), v = max(groups[k][i], groups[k][j]);\n                long long wc = is_query_selected[u][v] ? 0 : (!is_query_tested[u][v] ? 20000 : 40000);\n                c_e.push_back({u, v, (wc + center_dist[u][v]) * 1000000LL + (long long)u * 1000LL + v});\n            }\n            sort(c_e.begin(), c_e.end()); DSU final_dsu(G[k]);\n            int ed_c = 0;\n            for (auto& e : c_e) if (final_dsu.unite(local_idx[e.u], local_idx[e.v])) {\n                cout << e.u << \" \" << e.v << endl; if (++ed_c == G[k] - 1) break;\n            }\n        }\n    }\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n// Skating rink constants\nconst int N = 20;\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dchar[] = {'U', 'D', 'L', 'R'};\nconst int INF = 1e8;\n\n// To store parent information for path reconstruction\nstruct Parent {\n    int r, c;\n    char type, dir;\n};\n\n/**\n * Fast Dijkstra using a 3-bucket queue (Dial's algorithm for edge weights 1 and 2).\n * Finds shortest path from (start_r, start_c) to all other squares.\n */\nvoid fast_dijkstra(int start_r, int start_c, const vector<vector<bool>>& grid, int dists[N][N], Parent parents[N][N] = nullptr) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dists[i][j] = INF;\n    if (start_r < 0 || start_r >= N || start_c < 0 || start_c >= N) return;\n    dists[start_r][start_c] = 0;\n\n    int q[3][400];\n    int head[3] = {0, 0, 0}, tail[3] = {0, 0, 0};\n    q[0][tail[0]++] = start_r * N + start_c;\n\n    int d = 0, remaining = 1;\n    while (remaining > 0) {\n        int b = d % 3;\n        while (head[b] < tail[b]) {\n            int curr_val = q[b][head[b]++];\n            remaining--;\n            int cr = curr_val / N, cc = curr_val % N;\n            if (dists[cr][cc] < d) continue;\n\n            // Try Move action\n            for (int i = 0; i < 4; i++) {\n                int nr = cr + dr[i], nc = cc + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int cost = 1 + (grid[nr][nc] ? 1 : 0);\n                    if (dists[nr][nc] > d + cost) {\n                        dists[nr][nc] = d + cost;\n                        if (parents) parents[nr][nc] = {cr, cc, 'M', dchar[i]};\n                        q[(d + cost) % 3][tail[(d + cost) % 3]++] = nr * N + nc;\n                        remaining++;\n                    }\n                }\n            }\n            // Try Slide action\n            for (int i = 0; i < 4; i++) {\n                int sr = cr, sc = cc;\n                while (true) {\n                    int nr = sr + dr[i], nc = sc + dc[i];\n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N || grid[nr][nc]) break;\n                    sr = nr; sc = nc;\n                }\n                if (sr != cr || sc != cc) {\n                    if (dists[sr][sc] > d + 1) {\n                        dists[sr][sc] = d + 1;\n                        if (parents) parents[sr][sc] = {cr, cc, 'S', dchar[i]};\n                        q[(d + 1) % 3][tail[(d + 1) % 3]++] = sr * N + sc;\n                        remaining++;\n                    }\n                }\n            }\n        }\n        head[b] = tail[b] = 0;\n        d++;\n    }\n}\n\n/**\n * Backward Dijkstra to find shortest distances to target (tr, tc).\n * Accurately handles the asymmetry of Slides.\n */\nvoid fast_backward_dijkstra(int tr, int tc, const vector<vector<bool>>& grid, int dists[N][N]) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dists[i][j] = INF;\n    if (tr < 0 || tr >= N || tc < 0 || tc >= N) return;\n    dists[tr][tc] = 0;\n\n    int q[3][400];\n    int head[3] = {0, 0, 0}, tail[3] = {0, 0, 0};\n    q[0][tail[0]++] = tr * N + tc;\n\n    int d = 0, remaining = 1;\n    while (remaining > 0) {\n        int b = d % 3;\n        while (head[b] < tail[b]) {\n            int curr_val = q[b][head[b]++];\n            remaining--;\n            int cr = curr_val / N, cc = curr_val % N;\n            if (dists[cr][cc] < d) continue;\n\n            // Backward Move\n            for (int i = 0; i < 4; i++) {\n                int nr = cr - dr[i], nc = cc - dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int cost = 1 + (grid[cr][cc] ? 1 : 0);\n                    if (dists[nr][nc] > d + cost) {\n                        dists[nr][nc] = d + cost;\n                        q[(d + cost) % 3][tail[(d + cost) % 3]++] = nr * N + nc;\n                        remaining++;\n                    }\n                }\n            }\n            // Backward Slide\n            for (int i = 0; i < 4; i++) {\n                int br = cr + dr[i], bc = cc + dc[i];\n                if (br < 0 || br >= N || bc < 0 || bc >= N || grid[br][bc]) {\n                    int nr = cr - dr[i], nc = cc - dc[i];\n                    while (nr >= 0 && nr < N && nc >= 0 && nc < N && !grid[nr][nc]) {\n                        if (dists[nr][nc] > d + 1) {\n                            dists[nr][nc] = d + 1;\n                            q[(d + 1) % 3][tail[(d + 1) % 3]++] = nr * N + nc;\n                            remaining++;\n                        }\n                        nr -= dr[i]; nc -= dc[i];\n                    }\n                }\n            }\n        }\n        head[b] = tail[b] = 0;\n        d++;\n    }\n}\n\n/**\n * Reconstructs path from start to end and updates global state.\n */\nvoid reconstruct(int start_r, int start_c, int end_r, int end_c, Parent parents[N][N], vector<vector<bool>>& grid, int& curr_r, int& curr_c) {\n    if (start_r == end_r && start_c == end_c) return;\n    vector<pair<char, char>> path;\n    int cr = end_r, cc = end_c;\n    while (cr != start_r || cc != start_c) {\n        Parent p = parents[cr][cc];\n        path.push_back({p.type, p.dir});\n        cr = p.r; cc = p.c;\n    }\n    reverse(path.begin(), path.end());\n    for (auto& p : path) {\n        int di = (p.second == 'U' ? 0 : p.second == 'D' ? 1 : p.second == 'L' ? 2 : 3);\n        if (p.first == 'M') {\n            if (grid[curr_r + dr[di]][curr_c + dc[di]]) {\n                cout << \"A \" << p.second << \"\\n\";\n                grid[curr_r + dr[di]][curr_c + dc[di]] = false;\n            }\n            cout << \"M \" << p.second << \"\\n\";\n            curr_r += dr[di]; curr_c += dc[di];\n        } else if (p.first == 'S') {\n            cout << \"S \" << p.second << \"\\n\";\n            while (true) {\n                int nr = curr_r + dr[di], nc = curr_c + dc[di];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N || grid[nr][nc]) break;\n                curr_r = nr; curr_c = nc;\n            }\n        }\n    }\n}\n\n// Memory buffers for multiple Dijkstra calls\nint d0[N][N], d1[N][N], d2[N][N], bd_mod[N][N], d_mod1[N][N], d_mod2[N][N], d_fin[N][N];\nParent p0[N][N], p_fin[N][N];\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int n_in, m_in; cin >> n_in >> m_in;\n    vector<pair<int, int>> targets(m_in);\n    for (int i = 0; i < m_in; i++) cin >> targets[i].first >> targets[i].second;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    int curr_r = targets[0].first, curr_c = targets[0].second;\n\n    for (int k = 1; k < m_in; k++) {\n        int tr = targets[k].first, tc = targets[k].second;\n        fast_dijkstra(curr_r, curr_c, grid, d0, p0);\n        fast_dijkstra(tr, tc, grid, d1);\n        \n        long long best_eval = d0[tr][tc];\n        if (k + 1 < m_in) {\n            best_eval += d1[targets[k+1].first][targets[k+1].second];\n            if (k + 2 < m_in) {\n                fast_dijkstra(targets[k+1].first, targets[k+1].second, grid, d2);\n                best_eval += d2[targets[k+2].first][targets[k+2].second];\n            }\n        }\n\n        int best_br = -1, best_bc = -1, best_ar = -1, best_ac = -1;\n        char best_adir = ' ';\n\n        // Search for a single block flip to minimize the cost sequence (Look-ahead of up to 2 targets)\n        for (int br = 0; br < N; br++) {\n            for (int bc = 0; bc < N; bc++) {\n                if ((br == tr && bc == tc) || (br == curr_r && bc == curr_c)) continue;\n\n                grid[br][bc] = !grid[br][bc];\n                fast_backward_dijkstra(tr, tc, grid, bd_mod);\n                fast_dijkstra(tr, tc, grid, d_mod1);\n                \n                int cost_k_p1 = (k + 1 < m_in) ? d_mod1[targets[k+1].first][targets[k+1].second] : 0;\n                int cost_k_p2 = 0;\n                if (k + 2 < m_in) {\n                    fast_dijkstra(targets[k+1].first, targets[k+1].second, grid, d_mod2);\n                    cost_k_p2 = d_mod2[targets[k+2].first][targets[k+2].second];\n                }\n\n                for (int d = 0; d < 4; d++) {\n                    int ar = br + dr[d], ac = bc + dc[d];\n                    if (ar >= 0 && ar < N && ac >= 0 && ac < N && d0[ar][ac] < INF && bd_mod[ar][ac] < INF) {\n                        int cost_k = d0[ar][ac] + 1 + bd_mod[ar][ac];\n                        if ((long long)cost_k + cost_k_p1 + cost_k_p2 < best_eval) {\n                            best_eval = (long long)cost_k + cost_k_p1 + cost_k_p2;\n                            best_br = br; best_bc = bc; best_ar = ar; best_ac = ac;\n                            best_adir = dchar[d ^ 1];\n                        }\n                    }\n                }\n                grid[br][bc] = !grid[br][bc]; // Reset flip\n            }\n        }\n\n        if (best_br == -1) {\n            reconstruct(curr_r, curr_c, tr, tc, p0, grid, curr_r, curr_c);\n        } else {\n            reconstruct(curr_r, curr_c, best_ar, best_ac, p0, grid, curr_r, curr_c);\n            cout << \"A \" << best_adir << \"\\n\";\n            grid[best_br][best_bc] = !grid[best_br][best_bc];\n            fast_dijkstra(best_ar, best_ac, grid, d_fin, p_fin);\n            reconstruct(best_ar, best_ac, tr, tc, p_fin, grid, curr_r, curr_c);\n        }\n    }\n    return 0;\n}\n"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <numeric>\n\nusing namespace std;\n\n// Structure for axis-parallel rectangles (integer coordinates)\nstruct Rect {\n    int a, b, c, d; // (a, b) is bottom-left, (c, d) is top-right\n};\n\n// Structure for each company's data and current assigned rectangle\nstruct Company {\n    int x, y, r;\n    Rect rect;\n    double p;\n};\n\n// Function to calculate satisfaction p_i based on the formula ratio(2 - ratio)\ninline double get_p(int a, int b, int c, int d, int r) {\n    long long s = (long long)(c - a) * (d - b);\n    if (s <= 0) return 0.0;\n    double ratio = (s < (long long)r) ? (double)s / r : (double)r / s;\n    return ratio * (2.0 - ratio);\n}\n\n// Optimized overlap check for rectangles with positive common area\ninline bool overlaps(const Rect& r1, const Rect& r2) {\n    return max(r1.a, r2.a) < min(r1.c, r2.c) &&\n           max(r1.b, r2.b) < min(r1.d, r2.d);\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    // Load company data and initialize each with a minimal 1x1 rectangle\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        companies[i].rect = {companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1};\n        companies[i].p = get_p(companies[i].rect.a, companies[i].rect.b, companies[i].rect.c, companies[i].rect.d, companies[i].r);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n\n    // Phase 1: Simple Greedy Initial Growth\n    // Helps establish a solid base by growing towards desired area without overlaps\n    for (int iter = 0; iter < 200; ++iter) {\n        shuffle(idx.begin(), idx.end(), rng);\n        bool changed = false;\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3}; // 0:L, 1:B, 2:R, 3:T\n            shuffle(dirs, dirs + 4, rng);\n            for (int dir : dirs) {\n                if ((long long)(companies[i].rect.c - companies[i].rect.a) * (companies[i].rect.d - companies[i].rect.b) >= companies[i].r)\n                    continue;\n\n                Rect next = companies[i].rect;\n                if (dir == 0 && next.a > 0) next.a--;\n                else if (dir == 1 && next.b > 0) next.b--;\n                else if (dir == 2 && next.c < 10000) next.c++;\n                else if (dir == 3 && next.d < 10000) next.d++;\n                else continue;\n\n                if (next.a > companies[i].x || next.c <= companies[i].x ||\n                    next.b > companies[i].y || next.d <= companies[i].y) continue;\n\n                bool ok = true;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(next, companies[j].rect)) { ok = false; break; }\n                }\n                if (ok) {\n                    companies[i].rect = next;\n                    companies[i].p = get_p(next.a, next.b, next.c, next.d, companies[i].r);\n                    changed = true;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    // Phase 2: Simulated Annealing with Recursive Overlap Resolution (Pushing)\n    double current_total_p = 0;\n    for (int i = 0; i < n; ++i) current_total_p += companies[i].p;\n\n    const double SA_TIME_LIMIT = 4.65;\n    double T_start = 0.01;\n    double T_end = 0.0001;\n    \n    vector<pair<int, Rect>> changes;\n    changes.reserve(n);\n\n    long long iter_sa = 0;\n    while (true) {\n        if ((iter_sa & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > SA_TIME_LIMIT) break;\n            double progress = elapsed / SA_TIME_LIMIT;\n            // Linear/Exponential hybrid cooling\n            double T = T_start * pow(T_end / T_start, progress);\n\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            int side = uniform_int_distribution<int>(0, 3)(rng);\n\n            int old_val = (side == 0) ? companies[i].rect.a : (side == 1) ? companies[i].rect.b : (side == 2) ? companies[i].rect.c : companies[i].rect.d;\n            int new_val;\n            double move_type = uniform_real_distribution<double>(0, 1)(rng);\n            \n            if (move_type < 0.50) new_val = old_val + uniform_int_distribution<int>(-20, 20)(rng);\n            else if (move_type < 0.85) new_val = old_val + uniform_int_distribution<int>(-300, 300)(rng);\n            else if (move_type < 0.98) { // Strategic adjustment towards requested area r_i\n                int w = companies[i].rect.c - companies[i].rect.a;\n                int h = companies[i].rect.d - companies[i].rect.b;\n                if (side == 0)      new_val = companies[i].rect.c - max(1, companies[i].r / h);\n                else if (side == 1) new_val = companies[i].rect.d - max(1, companies[i].r / w);\n                else if (side == 2) new_val = companies[i].rect.a + max(1, companies[i].r / h);\n                else                new_val = companies[i].rect.b + max(1, companies[i].r / w);\n                \n                if (side == 0)      new_val = min(companies[i].x, max(0, new_val));\n                else if (side == 1) new_val = min(companies[i].y, max(0, new_val));\n                else if (side == 2) new_val = max(companies[i].x + 1, min(10000, new_val));\n                else                new_val = max(companies[i].y + 1, min(10000, new_val));\n            } else new_val = uniform_int_distribution<int>(0, 10000)(rng);\n\n            new_val = max(0, min(10000, new_val));\n            if (new_val == old_val) continue;\n\n            Rect next_i = companies[i].rect;\n            if (side == 0) next_i.a = new_val;\n            else if (side == 1) next_i.b = new_val;\n            else if (side == 2) next_i.c = new_val;\n            else next_i.d = new_val;\n\n            // Basic point containment and area validation\n            if (next_i.a >= next_i.c || next_i.b >= next_i.d ||\n                next_i.a > companies[i].x || next_i.c <= companies[i].x ||\n                next_i.b > companies[i].y || next_i.d <= companies[i].y) continue;\n\n            changes.clear();\n            changes.push_back({i, next_i});\n            bool possible = true;\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (overlaps(next_i, companies[j].rect)) {\n                    Rect next_j = companies[j].rect;\n                    // Shrink boundary to allow expansion of i\n                    if (side == 0)      next_j.c = next_i.a;\n                    else if (side == 1) next_j.d = next_i.b;\n                    else if (side == 2) next_j.a = next_i.c;\n                    else if (side == 3) next_j.b = next_i.d;\n\n                    // Neighbors must remain valid\n                    if (next_j.a >= next_j.c || next_j.b >= next_j.d ||\n                        next_j.a > companies[j].x || next_j.c <= companies[j].x ||\n                        next_j.b > companies[j].y || next_j.d <= companies[j].y) {\n                        possible = false;\n                        break;\n                    }\n                    changes.push_back({j, next_j});\n                }\n            }\n\n            if (possible) {\n                double delta = 0;\n                for (auto& ch : changes) delta += get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r) - companies[ch.first].p;\n                \n                if (delta >= 0 || uniform_real_distribution<double>(0, 1)(rng) < exp(delta / T)) {\n                    current_total_p += delta;\n                    for (auto& ch : changes) {\n                        companies[ch.first].rect = ch.second;\n                        companies[ch.first].p = get_p(ch.second.a, ch.second.b, ch.second.c, ch.second.d, companies[ch.first].r);\n                    }\n                }\n            }\n        }\n        iter_sa++;\n    }\n\n    // Phase 3: Final Greedy Cleanup\n    // Refine all rectangles locally to fill remaining gaps and maximize total score\n    for (int iter = 0; iter < 200; ++iter) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 4.9) break;\n        bool changed_any = false;\n        shuffle(idx.begin(), idx.end(), rng);\n        for (int i : idx) {\n            int dirs[4] = {0, 1, 2, 3};\n            shuffle(dirs, dirs + 4, rng);\n            for (int d : dirs) {\n                while (true) {\n                    Rect next = companies[i].rect;\n                    if (d == 0 && next.a > 0) next.a--;\n                    else if (d == 1 && next.b > 0) next.b--;\n                    else if (d == 2 && next.c < 10000) next.c++;\n                    else if (d == 3 && next.d < 10000) next.d++;\n                    else break;\n\n                    if (next.a > companies[i].x || next.c <= companies[i].x ||\n                        next.b > companies[i].y || next.d <= companies[i].y) break;\n\n                    bool safe = true;\n                    for (int j = 0; j < n; j++) {\n                        if (i == j) continue;\n                        if (overlaps(next, companies[j].rect)) { safe = false; break; }\n                    }\n                    if (!safe) break;\n\n                    double p_old = get_p(companies[i].rect.a, companies[i].rect.b, companies[i].rect.c, companies[i].rect.d, companies[i].r);\n                    double p_new = get_p(next.a, next.b, next.c, next.d, companies[i].r);\n                    if (p_new > p_old) {\n                        companies[i].rect = next;\n                        changed_any = true;\n                    } else break;\n                }\n            }\n        }\n        if (!changed_any) break;\n    }\n\n    // Output all calculated rectangles\n    for (int i = 0; i < n; ++i) {\n        cout << companies[i].rect.a << \" \" << companies[i].rect.b << \" \"\n             << companies[i].rect.c << \" \" << companies[i].rect.d << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <bitset>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We need to find a path on a 50x50 grid with tile constraints.\n * - Each square belongs to a tile (1x1, 1x2, or 2x1).\n * - Each tile can be visited at most once.\n * - The goal is to maximize the sum of values p[i][j] of visited squares.\n * \n * Algorithm Improvement:\n * - Use Beam Search with a larger beam width (K=10000).\n * - Diversity constraint: keep at most B=10 paths per square at each step.\n * - Optimize bitset operations and state memory management.\n * - Use a history pointer system to reconstruct the path after the search.\n */\n\n// Grid and maximum tile constants\nconst int GRID_SIZE = 50;\nconst int MAX_TILES = 2500;\n\n// PathNode for reconstructing the final path from the search history\nstruct PathNode {\n    int parent_idx;\n    short r, c;\n    char move;\n};\n\n// State representing a partial path in the beam search\nstruct State {\n    int score;\n    int history_idx;\n    short r, c;\n    bitset<MAX_TILES> visited;\n};\n\n// Candidate for the next step of the path\nstruct Candidate {\n    int score;\n    int parent_beam_idx;\n    short ni, nj;\n    char move;\n\n    // Comparator for sorting candidates by total score in descending order.\n    // Ties are broken using coordinate values to ensure deterministic results.\n    bool operator>(const Candidate& other) const {\n        if (score != other.score) return score > other.score;\n        if (ni != other.ni) return ni > other.ni;\n        return nj > other.nj;\n    }\n};\n\nint main() {\n    // Fast I/O for better performance\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    auto start_time = chrono::high_resolution_clock::now();\n\n    // Read initial position\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    // Read tile configurations\n    int t[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> t[i][j];\n\n    // Read square scores\n    int p[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j) cin >> p[i][j];\n\n    // Beam search configuration\n    const int K = 10000; // Maximum number of states to maintain in the beam\n    const int B = 10;    // Diversity: max number of paths allowed to end at the same grid square\n\n    // Store the history of path expansions to reconstruct the final path\n    // Using a flat vector for history to optimize memory allocation and access speed\n    vector<PathNode> history;\n    history.reserve(15000000);\n\n    // Current beam of states representing paths of the current length\n    vector<State> current_beam;\n    current_beam.reserve(K);\n\n    // Initial state: Takahashi starts at (si, sj)\n    bitset<MAX_TILES> initial_visited;\n    initial_visited.set(t[si][sj]);\n    current_beam.push_back({p[si][sj], 0, (short)si, (short)sj, initial_visited});\n    history.push_back({-1, (short)si, (short)sj, ' '});\n\n    int best_score = p[si][sj];\n    int best_history_idx = 0;\n\n    // Movement directions\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    // Candidate list for the next beam expansion\n    vector<Candidate> candidates;\n    candidates.reserve(K * 4);\n\n    // Array to track diversity per cell\n    int counts[GRID_SIZE * GRID_SIZE];\n\n    // Main Beam Search loop\n    while (true) {\n        // Exit search if time limit (2s) is nearing (leaving some margin)\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n\n        candidates.clear();\n        // For each state in the current beam, explore all 4 adjacent moves\n        for (int i = 0; i < (int)current_beam.size(); ++i) {\n            const auto& s = current_beam[i];\n            for (int d = 0; d < 4; ++d) {\n                int ni = s.r + dr[d];\n                int nj = s.c + dc[d];\n                // Check grid boundaries\n                if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE) {\n                    // Check if the tile at the destination has already been visited\n                    if (!s.visited.test(t[ni][nj])) {\n                        candidates.push_back({s.score + p[ni][nj], i, (short)ni, (short)nj, move_chars[d]});\n                    }\n                }\n            }\n        }\n\n        // If no more valid expansions are found, stop the search\n        if (candidates.empty()) break;\n\n        // Sort all possible next moves by score to select the best states for the next beam\n        sort(candidates.begin(), candidates.end(), greater<Candidate>());\n\n        vector<State> next_beam;\n        next_beam.reserve(K);\n        memset(counts, 0, sizeof(counts));\n\n        // Fill the next beam with the top K candidates, respecting the diversity constraint B\n        for (const auto& cand : candidates) {\n            int pos = cand.ni * GRID_SIZE + cand.nj;\n            if (counts[pos] < B) {\n                if (next_beam.size() >= K) break;\n\n                State next_s;\n                next_s.score = cand.score;\n                next_s.r = cand.ni;\n                next_s.c = cand.nj;\n                // Inherit visited bitset from parent and mark the new tile\n                next_s.visited = current_beam[cand.parent_beam_idx].visited;\n                next_s.visited.set(t[cand.ni][cand.nj]);\n                next_s.history_idx = (int)history.size();\n                \n                // Track expansion history\n                history.push_back({current_beam[cand.parent_beam_idx].history_idx, cand.ni, cand.nj, cand.move});\n                \n                // Update overall best path found\n                if (next_s.score > best_score) {\n                    best_score = next_s.score;\n                    best_history_idx = next_s.history_idx;\n                }\n\n                next_beam.push_back(std::move(next_s));\n                counts[pos]++;\n            }\n        }\n\n        // Move to the next step\n        if (next_beam.empty()) break;\n        current_beam = std::move(next_beam);\n    }\n\n    // Trace back through history to reconstruct the sequence of moves for the best path\n    string result_path = \"\";\n    int curr_node_idx = best_history_idx;\n    while (history[curr_node_idx].parent_idx != -1) {\n        result_path += history[curr_node_idx].move;\n        curr_node_idx = history[curr_node_idx].parent_idx;\n    }\n    // Reverse moves as we traced from finish to start\n    reverse(result_path.begin(), result_path.end());\n    \n    // Output the resulting path string\n    cout << result_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 * Strategy Summary:\n * 1. Road Network: 30x30 undirected grid graph with unknown edge lengths.\n * 2. Edge structure: Either M=1 (constant base length per row/column) or M=2 (two base lengths).\n * 3. Learning: Use feedback from noisy measurements (~10% error) to estimate edge lengths.\n * 4. Algorithm: Dijkstra's for shortest path queries, updated with kernel-smoothing to exploit \n *    the grid's structure.\n * 5. Weights: Exponentially weight later queries more (0.998^(1000-k)).\n */\n\n// Grid dimensions\nconst int N = 30;\n// Known possible range for edge lengths\nconst double MIN_WEIGHT = 1000.0;\nconst double MAX_WEIGHT = 9000.0;\nconst double INIT_WEIGHT = 5000.0;\n\n// Struct to track edges used in a path for subsequent weight updates\nstruct EdgeInfo {\n    int type; // 0 for horizontal (h_weights), 1 for vertical (v_weights)\n    int i, j;\n};\n\n// Global weight estimates and visit statistics\ndouble h_weights[N][N - 1];\ndouble v_weights[N - 1][N];\nint h_counts[N][N - 1];\nint v_counts[N - 1][N];\ndouble gamma_pow[N + 1];\n\n/**\n * Initializes the grid with expected average weights and precomputes \n * kernel smoothing factors.\n */\nvoid init() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            h_weights[i][j] = INIT_WEIGHT;\n            h_counts[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = INIT_WEIGHT;\n            v_counts[i][j] = 0;\n        }\n    }\n    // gamma determines the spatial influence of a weight update along a row or column.\n    double gamma = 0.94;\n    gamma_pow[0] = 1.0;\n    for (int i = 1; i <= N; ++i) {\n        gamma_pow[i] = gamma_pow[i - 1] * gamma;\n    }\n}\n\n/**\n * Adjusts the estimated weight for the shortest path search.\n * Early on (first 200 queries), we reduce weights of less-visited edges to encourage exploration.\n */\ndouble get_dijkstra_weight(int type, int i, int j, int k) {\n    double w = (type == 0) ? h_weights[i][j] : v_weights[i][j];\n    if (k < 200) {\n        int count = (type == 0) ? h_counts[i][j] : v_counts[i][j];\n        double bias = 0.20 * (1.0 - (double)k / 200.0) / (1.0 + (double)count);\n        return w * (1.0 - bias);\n    }\n    return w;\n}\n\n/**\n * Uses Dijkstra's algorithm to find the best path based on current knowledge.\n */\nstring find_path(int si, int sj, int ti, int tj, int k, vector<EdgeInfo>& path_edges) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<pair<int, int>, char>>> parent(N, vector<pair<pair<int, int>, char>>(N, {{-1, -1}, ' '}));\n    using P = pair<double, pair<int, int>>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int i = pq.top().second.first;\n        int j = pq.top().second.second;\n        pq.pop();\n\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        // Neighbor check: Up, Down, Left, Right\n        // Vertical edges connect (i, j) and (i+1, j)\n        // Horizontal edges connect (i, j) and (i, j+1)\n        if (i > 0) { // Up\n            double w = get_dijkstra_weight(1, i - 1, j, k);\n            if (dist[i - 1][j] > d + w) {\n                dist[i - 1][j] = d + w;\n                parent[i - 1][j] = {{i, j}, 'U'};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (i < N - 1) { // Down\n            double w = get_dijkstra_weight(1, i, j, k);\n            if (dist[i + 1][j] > d + w) {\n                dist[i + 1][j] = d + w;\n                parent[i + 1][j] = {{i, j}, 'D'};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (j > 0) { // Left\n            double w = get_dijkstra_weight(0, i, j - 1, k);\n            if (dist[i][j - 1] > d + w) {\n                dist[i][j - 1] = d + w;\n                parent[i][j - 1] = {{i, j}, 'L'};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        if (j < N - 1) { // Right\n            double w = get_dijkstra_weight(0, i, j, k);\n            if (dist[i][j + 1] > d + w) {\n                dist[i][j + 1] = d + w;\n                parent[i][j + 1] = {{i, j}, 'R'};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    // Reconstruction of the optimal path found.\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char dir = parent[ci][cj].second;\n        path += dir;\n        int pi = parent[ci][cj].first.first;\n        int pj = parent[ci][cj].first.second;\n        if (dir == 'U') {\n            path_edges.push_back({1, ci, cj});\n            v_counts[ci][cj]++;\n        } else if (dir == 'D') {\n            path_edges.push_back({1, pi, pj});\n            v_counts[pi][pj]++;\n        } else if (dir == 'L') {\n            path_edges.push_back({0, ci, cj});\n            h_counts[ci][cj]++;\n        } else if (dir == 'R') {\n            path_edges.push_back({0, pi, pj});\n            h_counts[pi][pj]++;\n        }\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/**\n * Updates estimated edge weights by comparing predicted path length with judge feedback.\n * Kernel smoothing distributes the error correction along rows/columns.\n */\nvoid update_weights(const vector<EdgeInfo>& path_edges, int result, int k) {\n    double predicted = 0;\n    for (const auto& e : path_edges) {\n        predicted += (e.type == 0) ? h_weights[e.i][e.j] : v_weights[e.i][e.j];\n    }\n\n    double error = (double)result - predicted;\n    // Decaying learning rate for long-term stability.\n    double lr = 0.48 * pow(0.9995, (double)k);\n\n    vector<vector<double>> coeff_h(N, vector<double>(N - 1, 0.0));\n    vector<vector<double>> coeff_v(N - 1, vector<double>(N, 0.0));\n\n    // Calculate update coefficients based on proximity to used edges in the grid.\n    for (const auto& e : path_edges) {\n        if (e.type == 0) {\n            for (int jp = 0; jp < N - 1; ++jp) coeff_h[e.i][jp] += gamma_pow[abs(e.j - jp)];\n        } else {\n            for (int ip = 0; ip < N - 1; ++ip) coeff_v[ip][e.j] += gamma_pow[abs(e.i - ip)];\n        }\n    }\n\n    // Normalize the step size based on total contribution to the measured path.\n    double total_coeff = 0;\n    for (const auto& e : path_edges) {\n        total_coeff += (e.type == 0) ? coeff_h[e.i][e.j] : coeff_v[e.i][e.j];\n    }\n\n    if (total_coeff > 0) {\n        double step = (error * lr) / total_coeff;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N - 1; ++j) {\n                if (coeff_h[i][j] > 0) {\n                    h_weights[i][j] += step * coeff_h[i][j];\n                    h_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, h_weights[i][j]));\n                }\n            }\n        }\n        for (int i = 0; i < N - 1; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (coeff_v[i][j] > 0) {\n                    v_weights[i][j] += step * coeff_v[i][j];\n                    v_weights[i][j] = max(MIN_WEIGHT, min(MAX_WEIGHT, v_weights[i][j]));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    init();\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        vector<EdgeInfo> path_edges;\n        string path = find_path(si, sj, ti, tj, k, path_edges);\n        cout << path << endl; // Endl flushes the output.\n\n        int result;\n        if (!(cin >> result)) break;\n        update_weights(path_edges, result, k);\n    }\n\n    return 0;\n}\n","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <cmath>\n#include <cstring>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Fast xorshift random number generator for better performance in Simulated Annealing\nuint32_t xorshift() {\n    static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t t = x ^ (x << 11);\n    x = y; y = z; z = w;\n    return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n}\n\nconst int N = 20;\nint M;\nint A[N][N];\nint best_A[N][N];\nint current_c = 0;\nint current_d = 0;\nint count_in_matrix[805]; // Max unique strings M (up to 800)\nint weights[805];\nbool length_exists[15];\nint modN[60];\n\n// Fast Hash Table for mapping packed strings to internal IDs\nstruct HashTable {\n    static const int SIZE = 1 << 16;\n    long long keys[SIZE];\n    int values[SIZE];\n    HashTable() { memset(keys, -1, sizeof(keys)); }\n    inline void insert(long long key, int val) {\n        uint32_t h = ((uint64_t)key * 11400714819323198485ULL) >> (64 - 16);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return;\n            h = (h + 1) & (SIZE - 1);\n        }\n        keys[h] = key;\n        values[h] = val;\n    }\n    inline int query(long long key) {\n        uint32_t h = ((uint64_t)key * 11400714819323198485ULL) >> (64 - 16);\n        while (keys[h] != -1) {\n            if (keys[h] == key) return values[h];\n            h = (h + 1) & (SIZE - 1);\n        }\n        return -1;\n    }\n} id_map;\n\n// Pack string to a 64-bit long long: 3 bits per char (up to 12 chars) + 4 bits for length\ninline long long pack_str_func(uint64_t val, int len) {\n    return (long long)((val << 4) | (uint64_t)len);\n}\n\n// Update covered strings count efficiently when cell A[r][c] changes\nvoid update_stats(int r, int c, int delta) {\n    for (int k = 0; k < 12; k++) {\n        // Horizontal check for strings of length L covering cell (r, c)\n        int sc = modN[c - k + 20];\n        uint64_t val_h = 0;\n        for (int L = 1; L <= 12; L++) {\n            int j = modN[sc + L - 1 + 20];\n            int v = A[r][j];\n            if (v == 0) break;\n            val_h = (val_h << 3) | (uint64_t)(v - 1);\n            if (L > k && length_exists[L]) {\n                int id = id_map.query(pack_str_func(val_h, L));\n                if (id != -1) {\n                    if (delta == 1) {\n                        if (count_in_matrix[id]++ == 0) current_c += weights[id];\n                    } else {\n                        if (--count_in_matrix[id] == 0) current_c -= weights[id];\n                    }\n                }\n            }\n        }\n        // Vertical check for strings of length L covering cell (r, c)\n        int sr = modN[r - k + 20];\n        uint64_t val_v = 0;\n        for (int L = 1; L <= 12; L++) {\n            int i = modN[sr + L - 1 + 20];\n            int v = A[i][c];\n            if (v == 0) break;\n            val_v = (val_v << 3) | (uint64_t)(v - 1);\n            if (L > k && length_exists[L]) {\n                int id = id_map.query(pack_str_func(val_v, L));\n                if (id != -1) {\n                    if (delta == 1) {\n                        if (count_in_matrix[id]++ == 0) current_c += weights[id];\n                    } else {\n                        if (--count_in_matrix[id] == 0) current_c -= weights[id];\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalized score for Simulated Annealing\ninline double get_sa_score(int c, int d) {\n    if (c < M) return (double)c;\n    return (double)M * 800.0 / (800.0 - (double)d);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n_input; if (!(cin >> n_input >> M)) return 0;\n    \n    for (int i = 0; i < 60; i++) modN[i] = (i - 20 + 20) % 20;\n\n    vector<string> s_list(M);\n    map<string, int> string_counts;\n    memset(length_exists, false, sizeof(length_exists));\n    for (int i = 0; i < M; i++) {\n        cin >> s_list[i];\n        string_counts[s_list[i]]++;\n        length_exists[s_list[i].length()] = true;\n    }\n\n    int k_unique = 0;\n    for (auto const& [str, weight] : string_counts) {\n        weights[k_unique] = weight;\n        uint64_t val = 0;\n        for (char ch : str) val = (val << 3) | (uint64_t)(ch - 'A');\n        id_map.insert(pack_str_func(val, (int)str.length()), k_unique);\n        k_unique++;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    memset(A, 0, sizeof(A));\n    vector<string> sorted_s = s_list;\n    sort(sorted_s.begin(), sorted_s.end(), [](const string& a, const string& b) {\n        return a.length() > b.length();\n    });\n\n    // Greedy initialization to satisfy as many strings as possible\n    for (const string& str : sorted_s) {\n        int best_r = -1, best_c = -1, best_dir = -1;\n        long long best_val = -1;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int dir = 0; dir < 2; dir++) {\n                    long long score = 0;\n                    for (int k = 0; k < (int)str.length(); k++) {\n                        int rr = (dir == 0 ? r : modN[r + k + 20]), cc = (dir == 0 ? modN[c + k + 20] : c);\n                        if (A[rr][cc] == 0) score += 2;\n                        else if (A[rr][cc] == str[k] - 'A' + 1) score += 10;\n                        else { score = -2000; break; }\n                    }\n                    if (score > best_val) { best_val = score; best_r = r; best_c = c; best_dir = dir; }\n                }\n            }\n        }\n        if (best_val > 0) {\n            for (int k = 0; k < (int)str.length(); k++) {\n                int rr = (best_dir == 0 ? best_r : modN[best_r + k + 20]), cc = (best_dir == 0 ? modN[best_c + k + 20] : best_c);\n                A[rr][cc] = str[k] - 'A' + 1;\n            }\n        }\n    }\n    // Fill remaining empty cells with random letters\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (A[i][j] == 0) A[i][j] = (xorshift() % 8) + 1;\n\n    // Initial evaluation of coverage\n    memset(count_in_matrix, 0, sizeof(count_in_matrix));\n    current_c = 0; current_d = 0;\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (A[r][c] == 0) current_d++;\n            for (int L = 2; L <= 12; L++) {\n                if (!length_exists[L]) continue;\n                uint64_t v_h = 0; bool ok_h = true;\n                for (int i = 0; i < L; i++) {\n                    int v = A[r][modN[c + i + 20]]; if (v == 0) { ok_h = false; break; }\n                    v_h = (v_h << 3) | (uint64_t)(v - 1);\n                }\n                if (ok_h) {\n                    int id = id_map.query(pack_str_func(v_h, L));\n                    if (id != -1) { if (count_in_matrix[id]++ == 0) current_c += weights[id]; }\n                }\n                uint64_t v_v = 0; bool ok_v = true;\n                for (int i = 0; i < L; i++) {\n                    int v = A[modN[r + i + 20]][c]; if (v == 0) { ok_v = false; break; }\n                    v_v = (v_v << 3) | (uint64_t)(v - 1);\n                }\n                if (ok_v) {\n                    int id = id_map.query(pack_str_func(v_v, L));\n                    if (id != -1) { if (count_in_matrix[id]++ == 0) current_c += weights[id]; }\n                }\n            }\n        }\n    }\n\n    double old_s = get_sa_score(current_c, current_d);\n    double best_s = old_s; memcpy(best_A, A, sizeof(A));\n    double T_start = 2.0, T_end = 0.01;\n\n    // Simulated Annealing Loop\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.94) break;\n        double T = T_start * pow(T_end / T_start, elapsed / 2.94);\n\n        for (int sub = 0; sub < 100; sub++) {\n            int r = xorshift() % N, c = xorshift() % N;\n            int old_v = A[r][c], new_v;\n            // Bias sampling for letters when c < M, and dots when c = M\n            if (current_c < M) {\n                if (xorshift() % 100 < 98) new_v = (xorshift() % 8) + 1;\n                else new_v = 0;\n            } else {\n                if (xorshift() % 100 < 15) new_v = (xorshift() % 8) + 1;\n                else new_v = 0;\n            }\n            if (new_v == old_v) continue;\n\n            int pre_c = current_c, pre_d = current_d;\n            update_stats(r, c, -1);\n            A[r][c] = new_v;\n            update_stats(r, c, 1);\n            current_d += (new_v == 0) - (old_v == 0);\n\n            double cur_s = get_sa_score(current_c, current_d);\n            if (cur_s >= old_s || exp((cur_s - old_s) / T) > (double)xorshift() / 4294967295.0) {\n                old_s = cur_s;\n                if (cur_s > best_s) { best_s = cur_s; memcpy(best_A, A, sizeof(A)); }\n            } else {\n                update_stats(r, c, -1);\n                A[r][c] = old_v;\n                update_stats(r, c, 1);\n                current_c = pre_c; current_d = pre_d;\n            }\n        }\n    }\n\n    // Output final results\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) cout << (best_A[i][j] == 0 ? '.' : (char)('A' + best_A[i][j] - 1));\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXR = 5000;\nconst int MAX_SEG = 10000;\n\nint N, SI, SJ;\nvector<string> grid;\n\nstruct Road {\n    int r, c, cost;\n};\n\nvector<Road> roads;\nint road_idx_map[70][70];\nvector<pair<int, int>> adj[MAXR];\nint dists[MAXR][MAXR];\nshort parents[MAXR][MAXR];\n\n// Dial's algorithm for APSP on a grid with weights 5-9\nvoid dial(int start, int* d, short* p, int R) {\n    for (int i = 0; i < R; ++i) d[i] = INF;\n    d[start] = 0;\n    p[start] = -1;\n    static vector<int> buckets[10];\n    for (int i = 0; i < 10; ++i) buckets[i].clear();\n    buckets[0].push_back(start);\n    int cur_dist = 0, num_visited = 0;\n    while (num_visited < R) {\n        int b_idx = cur_dist % 10;\n        while (!buckets[b_idx].empty()) {\n            int u = buckets[b_idx].back();\n            buckets[b_idx].pop_back();\n            if (d[u] < cur_dist) continue;\n            num_visited++;\n            for (auto& edge : adj[u]) {\n                int v = edge.first, w = edge.second;\n                if (d[v] > cur_dist + w) {\n                    d[v] = cur_dist + w;\n                    p[v] = (short)u;\n                    buckets[d[v] % 10].push_back(v);\n                }\n            }\n        }\n        cur_dist++;\n        if (cur_dist > 100000) break;\n    }\n}\n\nint n_h = 0, n_v = 0;\nvector<int> h_segs[MAX_SEG], v_segs[MAX_SEG];\nint h_seg_of[MAXR], v_seg_of[MAXR];\nint visitor_count_h[MAX_SEG], visitor_count_v[MAX_SEG];\nint is_visible_count[MAXR];\nint num_visible = 0;\n\nvoid update_sq_visibility(int sq, int delta) {\n    int h = h_seg_of[sq];\n    int v = v_seg_of[sq];\n    if (delta == 1) {\n        if (++visitor_count_h[h] == 1) {\n            for (int r : h_segs[h]) if (is_visible_count[r]++ == 0) num_visible++;\n        }\n        if (++visitor_count_v[v] == 1) {\n            for (int r : v_segs[v]) if (is_visible_count[r]++ == 0) num_visible++;\n        }\n    } else {\n        if (--visitor_count_h[h] == 0) {\n            for (int r : h_segs[h]) if (--is_visible_count[r] == 0) num_visible--;\n        }\n        if (--visitor_count_v[v] == 0) {\n            for (int r : v_segs[v]) if (--is_visible_count[r] == 0) num_visible--;\n        }\n    }\n}\n\nint calculate_tour_dist(const vector<int>& tour) {\n    if (tour.empty()) return 0;\n    int d = 0;\n    int K = (int)tour.size();\n    for (int i = 0; i < K; i++) {\n        d += dists[tour[i]][tour[(i + 1) % K]];\n    }\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> SI >> SJ)) return 0;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_idx_map[i][j] = (int)roads.size();\n                roads.push_back({i, j, grid[i][j] - '0'});\n            } else road_idx_map[i][j] = -1;\n        }\n    }\n    int R = (int)roads.size();\n    for (int i = 0; i < R; ++i) {\n        int r = roads[i].r, c = roads[i].c;\n        int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && grid[nr][nc] != '#')\n                adj[i].push_back({road_idx_map[nr][nc], grid[nr][nc] - '0'});\n        }\n    }\n\n    for (int i = 0; i < R; ++i) dial(i, dists[i], parents[i], R);\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                if (j == 0 || grid[i][j - 1] == '#') {\n                    int sid = n_h++;\n                    for (int k = j; k < N && grid[i][k] != '#'; ++k) {\n                        int idx = road_idx_map[i][k];\n                        h_segs[sid].push_back(idx); h_seg_of[idx] = sid;\n                    }\n                }\n                if (i == 0 || grid[i - 1][j] == '#') {\n                    int sid = n_v++;\n                    for (int k = i; k < N && grid[k][j] != '#'; ++k) {\n                        int idx = road_idx_map[k][j];\n                        v_segs[sid].push_back(idx); v_seg_of[idx] = sid;\n                    }\n                }\n            }\n        }\n    }\n\n    int start_node = road_idx_map[SI][SJ];\n    vector<int> tour = {start_node};\n    update_sq_visibility(start_node, 1);\n\n    mt19937 rng(42);\n    while (num_visible < R) {\n        int best_sq = -1; double best_score = -1e18;\n        for (int i = 0; i < min(R, 300); i++) {\n            int sq = uniform_int_distribution<>(0, R - 1)(rng);\n            int prev_v = num_visible;\n            update_sq_visibility(sq, 1);\n            int inc = num_visible - prev_v;\n            update_sq_visibility(sq, -1);\n            if (inc == 0) continue;\n            double score = (double)inc / (dists[tour.back()][sq] + 1);\n            if (score > best_score) { best_score = score; best_sq = sq; }\n        }\n        if (best_sq == -1) break;\n        tour.push_back(best_sq); update_sq_visibility(best_sq, 1);\n    }\n\n    for (int i = 1; i < (int)tour.size(); i++) {\n        int u = tour[i];\n        update_sq_visibility(u, -1);\n        if (num_visible == R) { tour.erase(tour.begin() + i); i--; }\n        else { update_sq_visibility(u, 1); }\n    }\n\n    int current_dist = calculate_tour_dist(tour);\n    double current_cost = current_dist + (double)(R - num_visible) * 1e7;\n    vector<int> best_tour = tour;\n    int best_dist = (num_visible == R) ? current_dist : INF;\n\n    auto start_time = chrono::high_resolution_clock::now();\n    double duration_limit = 2.85;\n    long long iter = 0;\n\n    while (true) {\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n            if (elapsed > duration_limit) break;\n        }\n        iter++;\n        double t_norm = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count() / duration_limit;\n        double temp = max(0.1, 50.0 * (1.0 - t_norm));\n\n        int K = (int)tour.size();\n        int move_type = uniform_int_distribution<>(0, 99)(rng);\n        \n        if (move_type < 25 && K > 2) { // 2-opt\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i >= j) continue;\n            int p_i = tour[i - 1], n_j = tour[(j + 1) % K];\n            int d_old = dists[p_i][tour[i]] + dists[tour[j]][n_j];\n            int d_new = dists[p_i][tour[j]] + dists[tour[i]][n_j];\n            // Since it's asymmetric, must recalculate the reversed sub-path\n            for (int k = i; k < j; k++) {\n                d_old += dists[tour[k]][tour[k + 1]];\n                d_new += dists[tour[k + 1]][tour[k]];\n            }\n            if (d_new < d_old || uniform_real_distribution<>(0, 1)(rng) < exp((double)(d_old - d_new) / temp)) {\n                reverse(tour.begin() + i, tour.begin() + j + 1);\n                current_dist += (d_new - d_old);\n                current_cost = current_dist + (double)(R - num_visible) * 1e7;\n            }\n        } else if (move_type < 45 && K > 2) { // Relocate\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i == j) continue;\n            int u = tour[i];\n            int p_i = tour[i - 1], n_i = tour[(i + 1) % K];\n            int d_diff = - dists[p_i][u] - dists[u][n_i] + dists[p_i][n_i];\n            vector<int> next_tour = tour;\n            next_tour.erase(next_tour.begin() + i);\n            int nK = (int)next_tour.size();\n            int p_j = next_tour[j - 1], n_j = next_tour[j % nK];\n            d_diff += - dists[p_j][n_j] + dists[p_j][u] + dists[u][n_j];\n            if (d_diff < 0 || uniform_real_distribution<>(0, 1)(rng) < exp((double)(-d_diff) / temp)) {\n                tour = next_tour;\n                tour.insert(tour.begin() + j, u);\n                current_dist += d_diff;\n                current_cost = current_dist + (double)(R - num_visible) * 1e7;\n            }\n        } else if (move_type < 65 && K > 1) { // Replace / Shift within segment\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int old_sq = tour[i];\n            int choice = uniform_int_distribution<>(0, 2)(rng);\n            int new_sq;\n            if (choice == 0) new_sq = h_segs[h_seg_of[old_sq]][uniform_int_distribution<>(0, (int)h_segs[h_seg_of[old_sq]].size() - 1)(rng)];\n            else if (choice == 1) new_sq = v_segs[v_seg_of[old_sq]][uniform_int_distribution<>(0, (int)v_segs[v_seg_of[old_sq]].size() - 1)(rng)];\n            else new_sq = uniform_int_distribution<>(0, R - 1)(rng);\n            int d_diff = - dists[tour[i - 1]][old_sq] - dists[old_sq][tour[(i + 1) % K]]\n                         + dists[tour[i - 1]][new_sq] + dists[new_sq][tour[(i + 1) % K]];\n            update_sq_visibility(old_sq, -1); update_sq_visibility(new_sq, 1);\n            double next_cost = (current_dist + d_diff) + (double)(R - num_visible) * 1e7;\n            if (next_cost < current_cost || uniform_real_distribution<>(0, 1)(rng) < exp((current_cost - next_cost) / temp)) {\n                tour[i] = new_sq; current_dist += d_diff; current_cost = next_cost;\n            } else { update_sq_visibility(new_sq, -1); update_sq_visibility(old_sq, 1); }\n        } else if (move_type < 80 && K > 2) { // Remove\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int u = tour[i];\n            int d_diff = - dists[tour[i - 1]][u] - dists[u][tour[(i + 1) % K]] + dists[tour[i - 1]][tour[(i + 1) % K]];\n            update_sq_visibility(u, -1);\n            double next_cost = (current_dist + d_diff) + (double)(R - num_visible) * 1e7;\n            if (next_cost < current_cost || uniform_real_distribution<>(0, 1)(rng) < exp((current_cost - next_cost) / temp)) {\n                tour.erase(tour.begin() + i); current_dist += d_diff; current_cost = next_cost;\n            } else { update_sq_visibility(u, 1); }\n        } else if (move_type < 95) { // Add\n            int new_sq = uniform_int_distribution<>(0, R - 1)(rng);\n            int i = uniform_int_distribution<>(1, K)(rng);\n            int p = tour[i - 1], n = tour[i % K];\n            int d_diff = - dists[p][n] + dists[p][new_sq] + dists[new_sq][n];\n            update_sq_visibility(new_sq, 1);\n            double next_cost = (current_dist + d_diff) + (double)(R - num_visible) * 1e7;\n            if (next_cost < current_cost || uniform_real_distribution<>(0, 1)(rng) < exp((current_cost - next_cost) / temp)) {\n                if (i == K) tour.push_back(new_sq); else tour.insert(tour.begin() + i, new_sq);\n                current_dist += d_diff; current_cost = next_cost;\n            } else { update_sq_visibility(new_sq, -1); }\n        } else if (K > 2) { // Swap\n            int i = uniform_int_distribution<>(1, K - 1)(rng);\n            int j = uniform_int_distribution<>(1, K - 1)(rng);\n            if (i == j) continue;\n            if (i > j) swap(i, j);\n            int u = tour[i], v = tour[j];\n            int p_i = tour[i - 1], n_i = tour[(i + 1) % K], p_j = tour[j - 1], n_j = tour[(j + 1) % K];\n            int d_diff;\n            if (j == i + 1) d_diff = - dists[p_i][u] - dists[u][v] - dists[v][n_j] + dists[p_i][v] + dists[v][u] + dists[u][n_j];\n            else d_diff = - dists[p_i][u] - dists[u][n_i] - dists[p_j][v] - dists[v][n_j] + dists[p_i][v] + dists[v][n_i] + dists[p_j][u] + dists[u][n_j];\n            if (d_diff < 0 || uniform_real_distribution<>(0, 1)(rng) < exp((double)(-d_diff) / temp)) {\n                swap(tour[i], tour[j]); current_dist += d_diff;\n                current_cost = current_dist + (double)(R - num_visible) * 1e7;\n            }\n        }\n        if (num_visible == R && current_dist < best_dist) { best_dist = current_dist; best_tour = tour; }\n    }\n\n    string final_path = \"\";\n    int finalK = (int)best_tour.size();\n    for (int i = 0; i < finalK; i++) {\n        int u = best_tour[i], v = best_tour[(i + 1) % finalK], pre = u;\n        vector<int> path;\n        for (int curr = v; curr != u; curr = (int)parents[u][curr]) path.push_back(curr);\n        reverse(path.begin(), path.end());\n        for (int node : path) {\n            if (roads[node].r < roads[pre].r) final_path += 'U';\n            else if (roads[node].r > roads[pre].r) final_path += 'D';\n            else if (roads[node].c < roads[pre].c) final_path += 'L';\n            else final_path += 'R';\n            pre = node;\n        }\n    }\n    cout << final_path << endl;\n\n    return 0;\n}\n","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\n// Configuration based on problem statement\nconst int MAX_DAYS = 2000;\nconst int N_TASKS = 1000;\nconst int M_MEMBERS = 20;\n\nstruct History {\n    vector<int> d;\n    int t;\n};\n\nstruct Task {\n    int id;\n    vector<int> d;\n    vector<int> deps;\n    vector<int> rev_deps;\n    double height;\n    int descendants;\n    int status; // -1: not ready, 0: ready, 1: ongoing, 2: completed\n};\n\nstruct Member {\n    int id;\n    vector<double> s;\n    int current_task;\n    int start_day;\n    vector<History> history;\n};\n\nint N, M, K, R;\nvector<Task> tasks;\nvector<Member> members;\n\n// Calculate the difficulty term w_i,j = sum(max(0, d_i,k - s_j,k))\ndouble get_w(const vector<double>& s, const vector<int>& d) {\n    double w = 0;\n    for (int k = 0; k < K; ++k) {\n        if ((double)d[k] > s[k]) w += (double)d[k] - s[k];\n    }\n    return w;\n}\n\n// Calculate the expected number of days for completion based on w_i,j and the random integer r\ndouble expected_duration(double w) {\n    if (w <= 0.0) return 1.0;\n    double sum = 0;\n    for (int r = -3; r <= 3; ++r) {\n        sum += max(1.0, w + (double)r);\n    }\n    return sum / 7.0;\n}\n\n// Re-calculate task heights for critical path prioritization\nvoid calculate_heights() {\n    double avg_s_val = 32.0 / sqrt((double)K);\n    vector<double> avg_s(K, avg_s_val);\n    \n    vector<double> duration_ests(N);\n    for (int i = 0; i < N; ++i) {\n        duration_ests[i] = expected_duration(get_w(avg_s, tasks[i].d));\n    }\n\n    for (int i = 0; i < N; ++i) tasks[i].height = 0;\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; ++i) out_degree[i] = (int)tasks[i].rev_deps.size();\n    \n    vector<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (out_degree[i] == 0) {\n            q.push_back(i);\n            tasks[i].height = duration_ests[i];\n        }\n    }\n    \n    int head = 0;\n    while(head < (int)q.size()){\n        int v = q[head++];\n        for(int u : tasks[v].deps){\n            tasks[u].height = max(tasks[u].height, tasks[v].height + duration_ests[u]);\n            if(--out_degree[u] == 0) q.push_back(u);\n        }\n    }\n}\n\n// Calculate total task descendants for secondary prioritization\nvoid calculate_descendants() {\n    for (int i = 0; i < N; ++i) {\n        vector<bool> visited(N, false);\n        vector<int> q_d;\n        q_d.push_back(i);\n        visited[i] = true;\n        int count = 0;\n        int head = 0;\n        while(head < (int)q_d.size()){\n            int v = q_d[head++];\n            for(int next_v : tasks[v].rev_deps){\n                if(!visited[next_v]){\n                    visited[next_v] = true;\n                    q_d.push_back(next_v);\n                    count++;\n                }\n            }\n        }\n        tasks[i].descendants = count;\n    }\n}\n\n// Update skill estimates using gradient descent based on task completion history\nvoid update_skills(int m_idx) {\n    auto& m = members[m_idx];\n    if (m.history.empty()) return;\n    \n    for (int iter = 0; iter < 400; ++iter) {\n        double eta = 0.1 / (1.0 + iter * 0.01);\n        vector<double> grad(K, 0.0);\n        for (const auto& h : m.history) {\n            double w = get_w(m.s, h.d);\n            double target_w = (h.t == 1) ? 0.0 : (double)h.t;\n            double diff = w - target_w;\n            // For t=1, we only know w is small, so we don't penalize if w is already 0\n            if (h.t == 1 && diff < 0) diff = 0;\n            for (int k = 0; k < K; ++k) {\n                if ((double)h.d[k] > m.s[k]) grad[k] -= diff;\n            }\n        }\n        for (int k = 0; k < K; ++k) {\n            m.s[k] -= eta * grad[k] / (double)m.history.size();\n            m.s[k] = max(0.0, m.s[k]);\n        }\n        // Project onto norm constraints [20, 60]\n        double norm2 = 0;\n        for (int k = 0; k < K; ++k) norm2 += m.s[k] * m.s[k];\n        double norm = sqrt(norm2);\n        if (norm < 20.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 20.0 / (norm + 1e-9);\n        } else if (norm > 60.0) {\n            for (int k = 0; k < K; ++k) m.s[k] *= 60.0 / norm;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    tasks.resize(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].id = i;\n        tasks[i].d.resize(K);\n        for (int k = 0; k < K; ++k) cin >> tasks[i].d[k];\n        tasks[i].status = -1;\n    }\n    \n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        tasks[v].deps.push_back(u);\n        tasks[u].rev_deps.push_back(v);\n    }\n    \n    calculate_heights();\n    calculate_descendants();\n    \n    members.resize(M);\n    for (int j = 0; j < M; ++j) {\n        members[j].id = j;\n        members[j].s.assign(K, 32.0 / sqrt((double)K));\n        members[j].current_task = -1;\n    }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        \n        for (int i = 0; i < N; ++i) {\n            if (tasks[i].status == -1) {\n                bool ok = true;\n                for (int dep : tasks[i].deps) {\n                    if (tasks[dep].status != 2) { ok = false; break; }\n                }\n                if (ok) tasks[i].status = 0;\n            }\n        }\n        \n        vector<int> idle_members, ready_tasks;\n        for (int j = 0; j < M; ++j) if (members[j].current_task == -1) idle_members.push_back(j);\n        for (int i = 0; i < N; ++i) if (tasks[i].status == 0) ready_tasks.push_back(i);\n        \n        vector<pair<int, int>> assignments;\n        while (!idle_members.empty() && !ready_tasks.empty()) {\n            double best_score = -1e18;\n            int best_m_idx = -1, best_t_idx = -1, best_mi = -1, best_ti = -1;\n\n            for (int mi = 0; mi < (int)idle_members.size(); ++mi) {\n                int j = idle_members[mi];\n                for (int ti = 0; ti < (int)ready_tasks.size(); ++ti) {\n                    int i = ready_tasks[ti];\n                    double w_est = get_w(members[j].s, tasks[i].d);\n                    double dur = expected_duration(w_est);\n                    // Standard scheduling priority: (critical_path_importance) * (efficiency)\n                    double score = (tasks[i].height * 100.0 + (double)tasks[i].descendants) / dur;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m_idx = j;\n                        best_t_idx = i;\n                        best_mi = mi;\n                        best_ti = ti;\n                    }\n                }\n            }\n            \n            if (best_m_idx != -1) {\n                assignments.push_back({best_m_idx, best_t_idx});\n                tasks[best_t_idx].status = 1;\n                members[best_m_idx].current_task = best_t_idx;\n                members[best_m_idx].start_day = current_day;\n                idle_members.erase(idle_members.begin() + best_mi);\n                ready_tasks.erase(ready_tasks.begin() + best_ti);\n            } else break;\n        }\n        \n        cout << (int)assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        cout << endl;\n        \n        int n_completed;\n        if (!(cin >> n_completed) || n_completed == -1) break;\n        for (int i = 0; i < n_completed; ++i) {\n            int m_id; cin >> m_id; --m_id;\n            int t_idx = members[m_id].current_task;\n            int duration = current_day - members[m_id].start_day + 1;\n            members[m_id].history.push_back({tasks[t_idx].d, duration});\n            tasks[t_idx].status = 2;\n            members[m_id].current_task = -1;\n            update_skills(m_id);\n        }\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// Order information and state arrays\nint orders_a[1000], orders_b[1000], orders_c[1000], orders_d[1000];\nint order_in_s[50];\nbool in_s[1000];\nint route[102];\nint pos[101]; // position of point index 0-99 in route\nint cur_x[101], cur_y[101]; // coords of point 0-99, and point 100 is the office (400, 400)\n\n// Calculate Manhattan distance between two points by their index in cur_x/cur_y\ninline int dist_points(int p1, int p2) {\n    return abs(cur_x[p1] - cur_x[p2]) + abs(cur_y[p1] - cur_y[p2]);\n}\n\n// Calculate Manhattan distance between a route index and specific coordinates\ninline int dist_to_coord(int r_idx, int x, int y) {\n    return abs(cur_x[route[r_idx]] - x) + abs(cur_y[route[r_idx]] - y);\n}\n\nint main() {\n    // Optimize standard I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read 1000 orders\n    for (int i = 0; i < 1000; i++) {\n        if (!(cin >> orders_a[i] >> orders_b[i] >> orders_c[i] >> orders_d[i])) break;\n    }\n\n    // Heuristic: Pick a pool of candidates closest to the office center (400, 400)\n    vector<pair<int, int>> pool_candidates;\n    for (int i = 0; i < 1000; i++) {\n        int d = abs(orders_a[i] - 400) + abs(orders_b[i] - 400) + abs(orders_c[i] - 400) + abs(orders_d[i] - 400);\n        pool_candidates.push_back({d, i});\n    }\n    sort(pool_candidates.begin(), pool_candidates.end());\n\n    // Use a subset of size 400 for selection\n    int pool_size = 400;\n    vector<int> pool;\n    for (int i = 0; i < pool_size; i++) {\n        pool.push_back(pool_candidates[i].second);\n    }\n\n    // Initialize chosen orders S with the first 50 closest orders\n    for (int i = 0; i < 50; i++) {\n        int order_idx = pool[i];\n        order_in_s[i] = order_idx;\n        in_s[order_idx] = true;\n        cur_x[i] = orders_a[order_idx];      // Pickup coordinate x\n        cur_y[i] = orders_b[order_idx];      // Pickup coordinate y\n        cur_x[i + 50] = orders_c[order_idx]; // Delivery coordinate x\n        cur_y[i + 50] = orders_d[order_idx]; // Delivery coordinate y\n    }\n    cur_x[100] = 400; cur_y[100] = 400; // Office coordinate\n\n    // Build an initial route using a Greedy Pickup-Delivery heuristic\n    int current_x = 400, current_y = 400;\n    vector<bool> visited_p(100, false);\n    route[0] = 100; route[101] = 100;\n    for (int step = 1; step <= 100; step++) {\n        int best_dist = 1e9, best_p = -1;\n        for (int p = 0; p < 100; p++) {\n            if (visited_p[p]) continue;\n            if (p >= 50 && !visited_p[p - 50]) continue; // Cannot deliver before pickup\n            int d = abs(current_x - cur_x[p]) + abs(current_y - cur_y[p]);\n            if (d < best_dist) { best_dist = d; best_p = p; }\n        }\n        route[step] = best_p;\n        pos[best_p] = step;\n        visited_p[best_p] = true;\n        current_x = cur_x[best_p]; current_y = cur_y[best_p];\n    }\n\n    // Initial total travel time\n    int current_t = 0;\n    for (int i = 0; i <= 100; i++) {\n        current_t += dist_points(route[i], route[i+1]);\n    }\n\n    // Simulated Annealing setup\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double t_start = 30.0, t_end = 0.1;\n    long long total_iter = 0;\n\n    while (true) {\n        // Limit total execution time to 1.96 seconds\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.96) break;\n\n        double progress = elapsed / 1.96;\n        double temp = t_start * pow(t_end / t_start, progress);\n\n        // Perform chunks of iterations\n        for (int j = 0; j < 2000; j++) {\n            int move_type = rng() % 100;\n\n            if (move_type < 45) { // Relocate point Move\n                int i = 1 + rng() % 100;\n                int k_pos = 1 + rng() % 100;\n                if (i == k_pos) continue;\n\n                int vi = route[i];\n                // Precedence Constraint Check\n                if (vi < 50) { if (i < k_pos && k_pos >= pos[vi + 50]) continue; }\n                else { if (i > k_pos && k_pos <= pos[vi - 50]) continue; }\n\n                // Distance Delta Calculation\n                int d_before, d_after;\n                if (i < k_pos) {\n                    d_before = dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]) + dist_points(route[k_pos], route[k_pos+1]);\n                    d_after = dist_points(route[i-1], route[i+1]) + dist_points(route[k_pos], route[i]) + dist_points(route[i], route[k_pos+1]);\n                } else {\n                    d_before = dist_points(route[k_pos-1], route[k_pos]) + dist_points(route[i-1], route[i]) + dist_points(route[i], route[i+1]);\n                    d_after = dist_points(route[k_pos-1], route[i]) + dist_points(route[i], route[k_pos]) + dist_points(route[i-1], route[i+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    int v = route[i];\n                    if (i < k_pos) {\n                        for (int k = i; k < k_pos; k++) { route[k] = route[k+1]; pos[route[k]] = k; }\n                    } else {\n                        for (int k = i; k > k_pos; k--) { route[k] = route[k-1]; pos[route[k]] = k; }\n                    }\n                    route[k_pos] = v; pos[v] = k_pos;\n                }\n            } else if (move_type < 90) { // Swap two points Move\n                int i = 1 + rng() % 100;\n                int j = 1 + rng() % 100;\n                if (i == j) continue;\n                int vi = route[i], vj = route[j];\n\n                // Precedence Constraint Check\n                if (vi < 50) { if (j >= pos[vi + 50]) continue; }\n                else { if (j <= pos[vi - 50]) continue; }\n                if (vj < 50) { if (i >= pos[vj + 50]) continue; }\n                else { if (i <= pos[vj - 50]) continue; }\n\n                int d_before, d_after;\n                int i_low = min(i, j), i_high = max(i, j);\n                if (i_high == i_low + 1) {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                } else {\n                    d_before = dist_points(route[i_low-1], route[i_low]) + dist_points(route[i_low], route[i_low+1]) +\n                               dist_points(route[i_high-1], route[i_high]) + dist_points(route[i_high], route[i_high+1]);\n                    d_after = dist_points(route[i_low-1], route[i_high]) + dist_points(route[i_high], route[i_low+1]) +\n                              dist_points(route[i_high-1], route[i_low]) + dist_points(route[i_low], route[i_high+1]);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    swap(route[i], route[j]);\n                    pos[route[i]] = i; pos[route[j]] = j;\n                }\n            } else { // Replace one order in S Move\n                int k = rng() % 50;\n                int old_idx = order_in_s[k];\n                int new_idx = pool[rng() % pool_size];\n                if (in_s[new_idx]) continue;\n\n                int pk_pos = pos[k], dk_pos = pos[k+50];\n                int nax = orders_a[new_idx], nay = orders_b[new_idx], ncx = orders_c[new_idx], ncy = orders_d[new_idx];\n\n                int d_before = dist_points(route[pk_pos-1], k) + dist_points(k, route[pk_pos+1]) +\n                               dist_points(route[dk_pos-1], k+50) + dist_points(k+50, route[dk_pos+1]);\n                if (pk_pos + 1 == dk_pos) {\n                    d_before = dist_points(route[pk_pos-1], k) + dist_points(k, k+50) + dist_points(k+50, route[dk_pos+1]);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_before = dist_points(route[dk_pos-1], k+50) + dist_points(k+50, k) + dist_points(k, route[pk_pos+1]);\n                }\n\n                int d_after = dist_to_coord(pk_pos-1, nax, nay) + dist_to_coord(pk_pos+1, nax, nay) +\n                              dist_to_coord(dk_pos-1, ncx, ncy) + dist_to_coord(dk_pos+1, ncx, ncy);\n                if (pk_pos + 1 == dk_pos) {\n                    d_after = dist_to_coord(pk_pos-1, nax, nay) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(dk_pos+1, ncx, ncy);\n                } else if (dk_pos + 1 == pk_pos) {\n                    d_after = dist_to_coord(dk_pos-1, ncx, ncy) + (abs(nax-ncx)+abs(nay-ncy)) + dist_to_coord(pk_pos+1, nax, nay);\n                }\n\n                int delta = d_after - d_before;\n                if (delta <= 0 || (double)rng() < exp(-delta / temp) * mt19937::max()) {\n                    current_t += delta;\n                    in_s[old_idx] = false; in_s[new_idx] = true;\n                    order_in_s[k] = new_idx;\n                    cur_x[k] = nax; cur_y[k] = nay;\n                    cur_x[k+50] = ncx; cur_y[k+50] = ncy;\n                }\n            }\n        }\n        total_iter++;\n    }\n\n    // Final Output: Number of orders and their 1-indexed IDs\n    cout << 50;\n    for (int i = 0; i < 50; i++) cout << \" \" << order_in_s[i] + 1;\n    cout << \"\\n\";\n\n    // Final Output: Route coordinates (start office, pickups/deliveries, end office)\n    cout << 102;\n    for (int i = 0; i <= 101; i++) {\n        int x, y;\n        if (i == 0 || i == 101) { x = 400; y = 400; }\n        else {\n            int p = route[i];\n            if (p < 50) { x = orders_a[order_in_s[p]]; y = orders_b[order_in_s[p]]; }\n            else { x = orders_c[order_in_s[p - 50]]; y = orders_d[order_in_s[p - 50]]; }\n        }\n        cout << \" \" << x << \" \" << y;\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cstdint>\n\nusing namespace std;\n\n/**\n * Problem Strategy:\n * This is an online version of the Minimum Spanning Tree (MST) problem. Edge lengths are revealed one by one, \n * and a decision must be made immediately.\n * \n * Algorithm:\n * 1. Connectivity Check: For each edge (u, v), we first check if u and v are already connected via\n *    adopted edges. If so, discard.\n * 2. Bridge Check: We then check if (u, v) is a \"bridge\" with respect to all future edges.\n *    If no future edges can connect the components of u and v, we MUST adopt this edge.\n * 3. Monte Carlo Simulation: For other edges, we simulate several possible \"worlds\" (scenarios).\n *    In each scenario, weights for future edges are sampled from their known distributions [d_i, 3*d_i].\n *    We adopt the edge if it's statistically likely to be part of the MST in these worlds.\n * 4. Optimization: To handle the 2.0s time limit, we use an adaptive simulation count K and\n *    highly optimized Disjoint Set Union (DSU) operations with dense component mapping.\n */\n\n// Performance-optimized DSU for simulations\nstruct SimDSU {\n    int16_t parent[400];\n    inline void init(int n) {\n        for (int16_t i = 0; i < n; ++i) parent[i] = i;\n    }\n    inline int find(int i) {\n        while (parent[i] != (int16_t)i) {\n            parent[i] = parent[parent[i]]; // Path halving\n            i = (int)parent[i];\n        }\n        return i;\n    }\n    inline void unite(int r1, int r2) {\n        if (r1 != r2) parent[r1] = (int16_t)r2;\n    }\n};\n\n// Fast DSU for maintaining the current state of adopted edges\nstruct FastDSU {\n    int parent[400];\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    void unite(int i, int j) {\n        int r1 = find(i);\n        int r2 = find(j);\n        if (r1 != r2) parent[r1] = r2;\n    }\n};\n\nstruct EdgeScenario {\n    int16_t id;\n    int16_t weight;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n    int x[N], y[N];\n    for (int i = 0; i < N; ++i) cin >> x[i] >> y[i];\n\n    int u[M], v[M], d[M];\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n        double dx = (double)x[u[i]] - x[v[i]];\n        double dy = (double)y[u[i]] - y[v[i]];\n        d[i] = (int)round(sqrt(dx * dx + dy * dy));\n    }\n\n    // Number of Monte Carlo scenarios\n    const int K = 110;\n    mt19937 rng(42);\n    vector<vector<EdgeScenario>> scenarios(K, vector<EdgeScenario>(M));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 0; i < M; ++i) {\n            scenarios[k][i] = {(int16_t)i, (int16_t)(d[i] + (int)(rng() % (2 * d[i] + 1)))};\n        }\n        // Pre-sorting scenarios by weight speeds up MST simulation\n        sort(scenarios[k].begin(), scenarios[k].end(), [](const EdgeScenario& a, const EdgeScenario& b) {\n            return a.weight < b.weight;\n        });\n    }\n\n    FastDSU dsu_base;\n    dsu_base.init(N);\n    SimDSU sim;\n    auto start_time = chrono::steady_clock::now();\n\n    int root_to_comp[400];\n    int last_update[400] = {0};\n    int16_t node_to_comp[400];\n    int16_t mu_j[M], mv_j[M];\n    double elapsed = 0.0;\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        if (!(cin >> l_i)) break;\n\n        int r_u = dsu_base.find(u[i]);\n        int r_v = dsu_base.find(v[i]);\n\n        if (r_u == r_v) {\n            cout << 0 << endl;\n            continue;\n        }\n\n        // Map current components to dense integer IDs [0, n_comp-1]\n        int n_comp = 0;\n        for (int n = 0; n < N; ++n) {\n            int root = dsu_base.find(n);\n            if (last_update[root] != i + 1) {\n                last_update[root] = i + 1;\n                root_to_comp[root] = n_comp++;\n            }\n            node_to_comp[n] = (int16_t)root_to_comp[root];\n        }\n\n        int mru = (int)node_to_comp[u[i]];\n        int mrv = (int)node_to_comp[v[i]];\n\n        // Map future edge endpoints to dense IDs for faster simulation\n        for (int j = i + 1; j < M; ++j) {\n            mu_j[j] = node_to_comp[u[j]];\n            mv_j[j] = node_to_comp[v[j]];\n        }\n\n        bool pick = false;\n        // Step 1: Bridge Check\n        sim.init(n_comp);\n        bool is_bridge = true;\n        for (int j = i + 1; j < M; ++j) {\n            if (mu_j[j] != mv_j[j]) {\n                int r1 = sim.find((int)mu_j[j]);\n                int r2 = sim.find((int)mv_j[j]);\n                if (r1 != r2) {\n                    sim.unite(r1, r2);\n                    if (sim.find(mru) == sim.find(mrv)) {\n                        is_bridge = false;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (is_bridge) {\n            pick = true;\n        } else {\n            // Step 2: Adaptive Monte Carlo Simulation\n            if ((i & 7) == 0) {\n                auto now = chrono::steady_clock::now();\n                elapsed = chrono::duration<double>(now - start_time).count();\n            }\n\n            int current_K = K;\n            if (elapsed > 1.85) current_K = 0;\n            else if (elapsed > 1.7) current_K = K / 10;\n            else if (elapsed > 1.45) current_K = K / 3;\n            else if (elapsed > 1.25) current_K = K / 2;\n\n            if (current_K > 0) {\n                int in_mst_count = 0;\n                for (int k = 0; k < current_K; ++k) {\n                    sim.init(n_comp);\n                    bool path_exists = false;\n                    for (const auto& es : scenarios[k]) {\n                        if (es.weight >= l_i) break; // MST property check optimization\n                        if (es.id <= i) continue;\n\n                        int smu = (int)mu_j[es.id];\n                        int smv = (int)mv_j[es.id];\n                        if (smu == smv) continue;\n\n                        int root1 = sim.find(smu);\n                        int root2 = sim.find(smv);\n                        if (root1 != root2) {\n                            sim.unite(root1, root2);\n                            if (sim.find(mru) == sim.find(mrv)) {\n                                path_exists = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (!path_exists) in_mst_count++;\n\n                    // Early exits for majority rule\n                    if (in_mst_count > current_K / 2) {\n                        pick = true;\n                        break;\n                    }\n                    if (in_mst_count + (current_K - 1 - k) <= current_K / 2) {\n                        pick = false;\n                        break;\n                    }\n                }\n            } else {\n                // Heuristic greedy fallback if time is low\n                if (l_i <= d[i] * 1.5) pick = true;\n            }\n        }\n\n        if (pick) {\n            dsu_base.unite(r_u, r_v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n\n    return 0;\n}\n","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int TURNS = 300;\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y; };\n\nint N_pets, M_humans;\nvector<Pet> pets;\nvector<Human> humans;\nbool is_blocked[32][32];\n\n// Check if a square (tx, ty) can be blocked according to the contest rules.\nbool can_block(int tx, int ty, const vector<Human>& current_h) {\n    if (tx < 1 || tx > GRID_SIZE || ty < 1 || ty > GRID_SIZE) return false;\n    if (is_blocked[tx][ty]) return false;\n    // Rule: Cannot block if square contains humans at the start of this turn.\n    for (int i = 0; i < M_humans; i++) {\n        if (current_h[i].x == tx && current_h[i].y == ty) return false;\n    }\n    // Rule: Cannot block if square contains a pet or any adjacent square contains a pet at the start.\n    for (int i = 0; i < N_pets; i++) {\n        if (abs(pets[i].x - tx) + abs(pets[i].y - ty) <= 1) return false;\n    }\n    return true;\n}\n\n// BFS to find the shortest path move for human h_idx towards the target (tx, ty).\nstring bfs_move(int h_idx, int tx, int ty, const bool being_blocked[32][32]) {\n    if (humans[h_idx].x == tx && humans[h_idx].y == ty) return \".\";\n    int dist[32][32];\n    pair<int, int> parent[32][32];\n    for (int r = 0; r < 32; r++) for (int c = 0; c < 32; c++) dist[r][c] = -1;\n    queue<pair<int, int>> q;\n    q.push({humans[h_idx].x, humans[h_idx].y});\n    dist[humans[h_idx].x][humans[h_idx].y] = 0;\n    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    char mc[] = {'U', 'D', 'L', 'R'};\n    while (!q.empty()) {\n        pair<int, int> curr = q.front(); q.pop();\n        if (curr.first == tx && curr.second == ty) {\n            pair<int, int> p = {tx, ty};\n            while (parent[p.first][p.second].first != humans[h_idx].x || parent[p.first][p.second].second != humans[h_idx].y) {\n                p = parent[p.first][p.second];\n            }\n            if (p.first < humans[h_idx].x) return \"U\";\n            if (p.first > humans[h_idx].x) return \"D\";\n            if (p.second < humans[h_idx].y) return \"L\";\n            if (p.second > humans[h_idx].y) return \"R\";\n        }\n        for (int k = 0; k < 4; k++) {\n            int nx = curr.first + dx[k], ny = curr.second + dy[k];\n            if (nx < 1 || nx > GRID_SIZE || ny < 1 || ny > GRID_SIZE || is_blocked[nx][ny] || being_blocked[nx][ny]) continue;\n            if (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    return \".\";\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N_pets)) return 0;\n    pets.resize(N_pets);\n    for (int i = 0; i < N_pets; i++) cin >> pets[i].x >> pets[i].y >> pets[i].type;\n    cin >> M_humans;\n    humans.resize(M_humans);\n    for (int i = 0; i < M_humans; i++) cin >> humans[i].x >> humans[i].y;\n\n    vector<int> wall_cols = {29, 26, 23, 20, 17, 14, 11, 8, 5, 2};\n    vector<int> wall_prog(wall_cols.size(), 1);\n    bool gate_done[10] = {false};\n\n    for (int t = 0; t < TURNS; t++) {\n        string actions(M_humans, '.');\n        bool being_blocked_this_turn[32][32] = {false};\n        vector<Human> next_h_pos = humans;\n\n        // Step 1: Identify humans who will block a square this turn.\n        for (int i = 0; i < M_humans; i++) {\n            // Check wall segments\n            for (int k = 0; k < (int)wall_cols.size(); k++) {\n                if (k % M_humans != i || wall_prog[k] > GRID_SIZE) continue;\n                int tx = wall_prog[k], ty = wall_cols[k];\n                if (tx == 15) continue;\n                int sx = tx, sy = ty + 1;\n                if (humans[i].x == sx && humans[i].y == sy) {\n                    if (can_block(tx, ty, humans) && !being_blocked_this_turn[tx][ty]) {\n                        if (tx < humans[i].x) actions[i] = 'u';\n                        else if (tx > humans[i].x) actions[i] = 'd';\n                        else if (ty < humans[i].y) actions[i] = 'l';\n                        else actions[i] = 'r';\n                        being_blocked_this_turn[tx][ty] = true;\n                    }\n                }\n                break;\n            }\n            // Check gates\n            if (actions[i] == '.') {\n                for (int k = 0; k < (int)wall_cols.size(); k++) {\n                    if (k % M_humans != i || wall_prog[k] <= GRID_SIZE || gate_done[k]) continue;\n                    int tx = 15, ty = wall_cols[k];\n                    int sx = 15, sy = ty + 1;\n                    if (humans[i].x == sx && humans[i].y == sy) {\n                        int min_y = ty + 1, max_y = (k == 0) ? 30 : wall_cols[k-1] - 1;\n                        bool safe = true;\n                        for (int p = 0; p < N_pets; p++) if (pets[p].y >= min_y && pets[p].y <= max_y) safe = false;\n                        if (safe || t > 250) {\n                            if (can_block(tx, ty, humans) && !being_blocked_this_turn[tx][ty]) {\n                                actions[i] = 'l';\n                                being_blocked_this_turn[tx][ty] = true;\n                                gate_done[k] = true;\n                            }\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n\n        // Step 2: Identify movement for humans not blocking.\n        for (int i = 0; i < M_humans; i++) {\n            if (actions[i] == '.') {\n                int tx = -1, ty = -1;\n                for (int k = 0; k < (int)wall_cols.size(); k++) {\n                    if (k % M_humans != i) continue;\n                    if (wall_prog[k] <= GRID_SIZE) {\n                        tx = wall_prog[k]; ty = wall_cols[k] + 1;\n                        if (tx == 15) { \n                            int next_seg = tx + 1;\n                            while (next_seg <= GRID_SIZE && is_blocked[next_seg][wall_cols[k]]) next_seg++;\n                            tx = next_seg;\n                        }\n                        break;\n                    } else if (!gate_done[k]) {\n                        tx = 15; ty = wall_cols[k] + 1;\n                        break;\n                    }\n                }\n                if (tx != -1 && tx <= GRID_SIZE) {\n                    string mv = bfs_move(i, tx, ty, being_blocked_this_turn);\n                    actions[i] = mv[0];\n                    if (mv == \"U\") next_h_pos[i].x--; else if (mv == \"D\") next_h_pos[i].x++;\n                    else if (mv == \"L\") next_h_pos[i].y--; else if (mv == \"R\") next_h_pos[i].y++;\n                }\n            }\n        }\n\n        cout << actions << endl;\n\n        for (int i = 0; i < M_humans; i++) {\n            if (actions[i] >= 'a' && actions[i] <= 'z') {\n                int bx = humans[i].x, by = humans[i].y;\n                if (actions[i] == 'u') bx--; else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--; else if (actions[i] == 'r') by++;\n                if (bx >= 1 && bx <= GRID_SIZE && by >= 1 && by <= GRID_SIZE) is_blocked[bx][by] = true;\n            } else {\n                humans[i] = next_h_pos[i];\n            }\n        }\n\n        for (int k = 0; k < 10; k++) {\n            while (wall_prog[k] <= GRID_SIZE && (wall_prog[k] == 15 || is_blocked[wall_prog[k]][wall_cols[k]])) wall_prog[k]++;\n        }\n\n        for (int i = 0; i < N_pets; i++) {\n            string pm; if (!(cin >> pm)) break;\n            for (char c : pm) {\n                if (c == 'U') pets[i].x--; else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--; else if (c == 'R') pets[i].y++;\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 <numeric>\n#include <cstring>\n#include <chrono>\n\nusing namespace std;\n\n// Directional constants: 0: Up (U), 1: Down (D), 2: Left (L), 3: Right (R)\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nint si, sj, ti, tj;\ndouble p_prob;\nstring h_wall[20], v_wall[19];\nint move_to[400][4];\ndouble V_dp[400][205];\ndouble ValueMat[205][4][400];\ndouble ReachProb[4][400];\n\n// Check if a move is possible in the given grid direction (no walls)\nbool can_move_func(int i, int j, int dir) {\n    if (dir == 0) return (i > 0 && v_wall[i - 1][j] == '0');\n    if (dir == 1) return (i < 19 && v_wall[i][j] == '0');\n    if (dir == 2) return (j > 0 && h_wall[i][j - 1] == '0');\n    if (dir == 3) return (j < 19 && h_wall[i][j] == '0');\n    return false;\n}\n\n// Precalculate transition data and DP heuristic for Beam Search\nvoid precompute() {\n    int target = ti * 20 + tj;\n    for (int i = 0; i < 400; i++) {\n        for (int d = 0; d < 4; d++) {\n            if (can_move_func(i / 20, i % 20, d))\n                move_to[i][d] = (i / 20 + di[d]) * 20 + (i % 20 + dj[d]);\n            else\n                move_to[i][d] = -1;\n            ReachProb[d][i] = (move_to[i][d] == target) ? (1.0 - p_prob) : 0.0;\n        }\n    }\n\n    memset(V_dp, 0, sizeof(V_dp));\n    for (int t = 200; t >= 1; t--) {\n        for (int i = 0; i < 400; i++) {\n            if (i == target) {\n                V_dp[i][t] = 401.0 - (double)t;\n                continue;\n            }\n            double max_v = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = move_to[i][d];\n                double res;\n                if (ni == -1) res = V_dp[i][t + 1];\n                else if (ni == target) res = (1.0 - p_prob) * (401.0 - (double)t) + p_prob * V_dp[i][t + 1];\n                else res = (1.0 - p_prob) * V_dp[ni][t + 1] + p_prob * V_dp[i][t + 1];\n                ValueMat[t][d][i] = res;\n                if (res > max_v) max_v = res;\n            }\n            V_dp[i][t] = max_v;\n        }\n    }\n}\n\n// Structure to store probability distribution and state in Beam Search/HC\nstruct State {\n    double P[400];\n    int nonzero[400];\n    int num_nonzero;\n    double current_E_S;\n    double score;\n    string s;\n\n    State() : num_nonzero(0), current_E_S(0), score(0), s(\"\") {\n        memset(P, 0, sizeof(P));\n    }\n};\n\n// Candidate for expanding states in Beam Search\nstruct Candidate {\n    double score;\n    double p_reached_k;\n    int state_idx;\n    int dir;\n    bool operator>(const Candidate& o) const { return score > o.score; }\n};\n\ndouble tmp_P[400];\nbool used_node[400];\n\n// Execute one turn in the simulation given current distribution and direction\nvoid step_simulation(const State& prev, int dir, int k, State& next, int target_node) {\n    memset(next.P, 0, sizeof(next.P));\n    next.num_nonzero = 0;\n    next.current_E_S = prev.current_E_S;\n    double p_reach = 0;\n    for (int i = 0; i < prev.num_nonzero; i++) {\n        int idx = prev.nonzero[i];\n        double p_val = prev.P[idx];\n        int ni = move_to[idx][dir];\n        if (ni != -1) {\n            if (!used_node[idx]) { used_node[idx] = true; next.nonzero[next.num_nonzero++] = idx; }\n            tmp_P[idx] += p_val * p_prob;\n            if (ni == target_node) {\n                p_reach += p_val * (1.0 - p_prob);\n            } else {\n                if (!used_node[ni]) { used_node[ni] = true; next.nonzero[next.num_nonzero++] = ni; }\n                tmp_P[ni] += p_val * (1.0 - p_prob);\n            }\n        } else {\n            if (!used_node[idx]) { used_node[idx] = true; next.nonzero[next.num_nonzero++] = idx; }\n            tmp_P[idx] += p_val;\n        }\n    }\n    next.current_E_S += (401.0 - (double)k) * p_reach;\n    int nn = 0;\n    for (int i = 0; i < next.num_nonzero; i++) {\n        int idx = next.nonzero[i];\n        if (tmp_P[idx] > 1e-15) {\n            next.P[idx] = tmp_P[idx];\n            next.nonzero[nn++] = idx;\n        }\n        tmp_P[idx] = 0; used_node[idx] = false;\n    }\n    next.num_nonzero = nn;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> si >> sj >> ti >> tj >> p_prob)) return 0;\n    for (int i = 0; i < 20; i++) cin >> h_wall[i];\n    for (int i = 0; i < 19; i++) cin >> v_wall[i];\n\n    auto start_time = chrono::steady_clock::now();\n    precompute();\n\n    int start_node = si * 20 + sj;\n    int target_node = ti * 20 + tj;\n\n    // 1. Initial robust string generation using Beam Search\n    vector<State> beam;\n    State initial_st;\n    initial_st.P[start_node] = 1.0;\n    initial_st.nonzero[0] = start_node;\n    initial_st.num_nonzero = 1;\n    initial_st.score = V_dp[start_node][1];\n    beam.push_back(move(initial_st));\n\n    const int B = 1200;\n    for (int k = 1; k <= 200; k++) {\n        vector<Candidate> cands;\n        cands.reserve(beam.size() * 4);\n        for (int b = 0; b < (int)beam.size(); b++) {\n            const State& st = beam[b];\n            for (int d = 0; d < 4; d++) {\n                double c_score = st.current_E_S;\n                double p_reach = 0;\n                const double* vm_k_d = ValueMat[k][d];\n                const double* rp_d = ReachProb[d];\n                for (int i = 0; i < st.num_nonzero; i++) {\n                    int idx = st.nonzero[i];\n                    double p = st.P[idx];\n                    c_score += p * vm_k_d[idx];\n                    p_reach += p * rp_d[idx];\n                }\n                cands.push_back({c_score, p_reach, b, d});\n            }\n        }\n        sort(cands.begin(), cands.end(), greater<Candidate>());\n        if ((int)cands.size() > B) cands.resize(B);\n\n        vector<State> next_beam(cands.size());\n        for (int c = 0; c < (int)cands.size(); c++) {\n            const auto& cand = cands[c];\n            const State& prev = beam[cand.state_idx];\n            State& next_st = next_beam[c];\n            next_st.s = prev.s + dc[cand.dir];\n            next_st.score = cand.score;\n            step_simulation(prev, cand.dir, k, next_st, target_node);\n        }\n        beam = move(next_beam);\n    }\n\n    // 2. Local refinement using Hill Climbing with Suffix expectation calculation\n    string S = beam[0].s;\n    double best_es = beam[0].current_E_S;\n    static State path[205];\n    for(int k=0; k<205; k++) memset(path[k].P, 0, sizeof(path[k].P));\n    path[0].num_nonzero = 1;\n    path[0].nonzero[0] = start_node;\n    path[0].P[start_node] = 1.0;\n    path[0].current_E_S = 0;\n\n    auto get_d = [&](char c) {\n        if(c=='U') return 0; if(c=='D') return 1; if(c=='L') return 2; if(c=='R') return 3; return -1;\n    };\n\n    auto update_forward = [&](int t_start) {\n        for (int k = t_start; k < 200; k++) step_simulation(path[k], get_d(S[k]), k + 1, path[k + 1], target_node);\n    };\n    update_forward(0);\n\n    static double E_hc[400][205];\n    memset(E_hc, 0, sizeof(E_hc));\n    auto update_backward = [&](int t_start, int t_end) {\n        for (int k = t_end; k >= t_start; k--) {\n            int d = get_d(S[k]);\n            for (int i = 0; i < 400; i++) {\n                if (i == target_node) { E_hc[i][k] = 0; continue; }\n                int ni = move_to[i][d];\n                if (ni == -1) E_hc[i][k] = E_hc[i][k + 1];\n                else if (ni == target_node) E_hc[i][k] = p_prob * E_hc[i][k + 1] + (1.0 - p_prob) * (401.0 - (k + 1));\n                else E_hc[i][k] = p_prob * E_hc[i][k + 1] + (1.0 - p_prob) * E_hc[ni][k + 1];\n            }\n        }\n    };\n\n    bool any = true;\n    while (any) {\n        any = false;\n        update_backward(0, 199);\n        for (int i = 0; i < 200; i++) {\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 1.95) break;\n            int orig_d = get_d(S[i]);\n            int best_new = orig_d;\n            for (int d = 0; d < 4; d++) {\n                if (d == orig_d) continue;\n                double score_sum = path[i].current_E_S;\n                for (int j = 0; j < path[i].num_nonzero; j++) {\n                    int idx = path[i].nonzero[j];\n                    double p = path[i].P[idx];\n                    int m_ni = move_to[idx][d];\n                    if (m_ni == -1) score_sum += p * E_hc[idx][i + 1];\n                    else if (m_ni == target_node) score_sum += p * (p_prob * E_hc[idx][i + 1] + (1.0 - p_prob) * (401.0 - (i + 1)));\n                    else score_sum += p * (p_prob * E_hc[idx][i + 1] + (1.0 - p_prob) * E_hc[m_ni][i + 1]);\n                }\n                if (score_sum > best_es + 1e-9) {\n                    best_es = score_sum;\n                    best_new = d;\n                }\n            }\n            if (best_new != orig_d) {\n                S[i] = dc[best_new];\n                update_forward(i);\n                update_backward(0, i);\n                any = true;\n            }\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 1.95) break;\n    }\n    cout << S << endl;\n    return 0;\n}\n","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Problem-defined constants\nconst int N = 30;\nconst int P = N * N * 4; // Total number of ports: 30x30 tiles * 4 ports per tile\n\n// Movement vectors for port 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// Tile connectivity table based on the provided hint.\n// Each row represents a tile type (0-7).\n// Each column represents the direction a train enters from (0-3).\n// The value is the direction it exits from (-1 if no connection).\nconst int to_tbl[8][4] = {\n    {1, 0, -1, -1}, // Tile 0: Connects Left(0) and Top(1)\n    {3, -1, -1, 0}, // Tile 1: Connects Left(0) and Bottom(3)\n    {-1, -1, 3, 2}, // Tile 2: Connects Right(2) and Bottom(3)\n    {-1, 2, 1, -1}, // Tile 3: Connects Right(2) and Top(1)\n    {1, 0, 3, 2},   // Tile 4: Double curve (0-1, 2-3)\n    {3, 2, 1, 0},   // Tile 5: Double curve (0-3, 1-2)\n    {2, -1, 0, -1}, // Tile 6: Straight line (0-2)\n    {-1, 3, -1, 1}  // Tile 7: Straight line (1-3)\n};\n\n// Global simulation state\nint initial_grid[N * N];\nint current_tiles[N * N];\nint rot[N * N];\nint best_rot[N * N];\nint next_port[P];\nint visited[P];\nint timer = 0;\n\n// Determine the resulting tile type after applying a CCW rotation\ninline int get_tile_type(int initial_type, int rotation) {\n    if (initial_type <= 3) return (initial_type + rotation) % 4;\n    if (initial_type <= 5) return 4 + (initial_type - 4 + rotation) % 2;\n    if (initial_type <= 7) return 6 + (initial_type - 6 + rotation) % 2;\n    return initial_type;\n}\n\n// Full evaluation of the current grid to identify loop lines and compute lengths.\n// Uses a heuristic score to provide a gradient for Simulated Annealing.\nlong long evaluate(int& m1, int& m2) {\n    timer++;\n    m1 = 0; m2 = 0;\n    long long sum_all = 0;\n    int num_loops = 0;\n\n    for (int p = 0; p < P; ++p) {\n        if (visited[p] == timer) continue;\n        \n        int start_tile = p >> 2;\n        int d_in = p & 3;\n        if (to_tbl[current_tiles[start_tile]][d_in] == -1) {\n            visited[p] = timer;\n            continue;\n        }\n\n        int curr_p = p;\n        int len = 0;\n        bool is_loop = false;\n        \n        while (true) {\n            int c_tile = curr_p >> 2;\n            int c_d_in = curr_p & 3;\n            int c_d_out = to_tbl[current_tiles[c_tile]][c_d_in];\n            \n            if (c_d_out == -1) {\n                visited[curr_p] = timer;\n                break;\n            }\n            \n            visited[curr_p] = timer;\n            visited[(c_tile << 2) | c_d_out] = timer;\n            \n            int np = next_port[(c_tile << 2) | c_d_out];\n            len++;\n            \n            if (np == -1) break;\n            if (np == p) {\n                is_loop = true;\n                break;\n            }\n            if (visited[np] == timer) break;\n            curr_p = np;\n        }\n        \n        if (is_loop) {\n            num_loops++;\n            sum_all += len;\n            if (len > m1) { m2 = m1; m1 = len; }\n            else if (len > m2) { m2 = len; }\n        }\n    }\n    \n    // Smooth heuristic to favor grids with multiple large loops\n    if (num_loops >= 2) return 100000000LL + (long long)m1 * m2 * 100LL + sum_all;\n    return (long long)m1 * 100LL + sum_all;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Robustly read 900 tile digits from standard input\n    int count = 0;\n    while (count < N * N) {\n        string s;\n        if (!(cin >> s)) break;\n        for (char c : s) {\n            if (isdigit(c)) {\n                initial_grid[count++] = c - '0';\n            }\n        }\n    }\n\n    // Pre-calculate port connectivity across neighboring tiles\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                int p_idx = (i * N + j) * 4 + d;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_port[p_idx] = -1;\n                } else {\n                    next_port[p_idx] = (ni * N + nj) * 4 + (d ^ 2);\n                }\n            }\n        }\n    }\n\n    // Initialize state with random tile rotations\n    mt19937 rng(42);\n    for (int i = 0; i < N * N; ++i) {\n        rot[i] = rng() % 4;\n        current_tiles[i] = get_tile_type(initial_grid[i], rot[i]);\n        best_rot[i] = rot[i];\n    }\n\n    int m1, m2;\n    long long current_score = evaluate(m1, m2);\n    long long best_actual_score = (long long)m1 * m2;\n\n    auto start_time = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.95;\n    double T_start = 500.0, T_end = 0.5, T = T_start;\n    uniform_real_distribution<double> dist_u(0.0, 1.0);\n\n    // Simulated Annealing optimization loop\n    for (int iter = 0; ; ++iter) {\n        if ((iter & 511) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count() / 1000.0;\n            if (elapsed > TIME_LIMIT) break;\n            T = T_start * pow(T_end / T_start, elapsed / TIME_LIMIT);\n        }\n\n        // Neighborhood move: rotate one tile randomly\n        int idx = rng() % (N * N);\n        int old_r = rot[idx];\n        rot[idx] = (old_r + (rng() % 3) + 1) % 4;\n        current_tiles[idx] = get_tile_type(initial_grid[idx], rot[idx]);\n\n        int nm1, nm2;\n        long long next_score = evaluate(nm1, nm2);\n\n        // Standard Metropolis acceptance criterion\n        if (next_score >= current_score || (T > 0 && exp((double)(next_score - current_score) / T) > dist_u(rng))) {\n            current_score = next_score;\n            long long current_actual = (long long)nm1 * nm2;\n            if (current_actual > best_actual_score) {\n                best_actual_score = current_actual;\n                for (int k = 0; k < N * N; ++k) best_rot[k] = rot[k];\n            }\n        } else {\n            // Revert tile rotation\n            rot[idx] = old_r;\n            current_tiles[idx] = get_tile_type(initial_grid[idx], old_r);\n        }\n    }\n\n    // Output final string of 900 tile rotations\n    for (int i = 0; i < N * N; ++i) cout << best_rot[i];\n    cout << endl;\n\n    return 0;\n}\n","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nint N, T_max;\nint initial_board[10][10];\nint initial_er, initial_ec;\n\n// Global buffers to avoid allocation\nint current_board[10][10];\nint next_board[10][10];\nbool vis[10][10];\nint qr[100], qc[100];\n\nint get_tree_score(const int board[10][10], int& total_edges) {\n    int max_s = 0;\n    total_edges = 0;\n    memset(vis, 0, sizeof(vis));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != 0 && !vis[i][j]) {\n                int nodes = 0, edges = 0;\n                int head = 0, tail = 0;\n                qr[tail] = i; qc[tail] = j; tail++;\n                vis[i][j] = true;\n                while (head < tail) {\n                    int r = qr[head], c = qc[head]; head++;\n                    nodes++;\n                    int type_u = board[r][c];\n                    // mask: 1 left, 2 up, 4 right, 8 down\n                    if (r > 0 && (type_u & 2) && (board[r-1][c] & 8)) {\n                        edges++;\n                        if (!vis[r-1][c]) { vis[r-1][c] = true; qr[tail] = r-1; qc[tail] = c; tail++; }\n                    }\n                    if (r < N - 1 && (type_u & 8) && (board[r+1][c] & 2)) {\n                        edges++;\n                        if (!vis[r+1][c]) { vis[r+1][c] = true; qr[tail] = r+1; qc[tail] = c; tail++; }\n                    }\n                    if (c > 0 && (type_u & 1) && (board[r][c-1] & 4)) {\n                        edges++;\n                        if (!vis[r][c-1]) { vis[r][c-1] = true; qr[tail] = r; qc[tail] = c-1; tail++; }\n                    }\n                    if (c < N - 1 && (type_u & 4) && (board[r][c+1] & 1)) {\n                        edges++;\n                        if (!vis[r][c+1]) { vis[r][c+1] = true; qr[tail] = r; qc[tail] = c+1; tail++; }\n                    }\n                }\n                if (edges == (nodes - 1) * 2) max_s = max(max_s, nodes);\n                total_edges += edges / 2;\n            }\n        }\n    }\n    return max_s;\n}\n\ndouble get_score(int tree_size, int move_count, int total_edges) {\n    if (tree_size == N * N - 1) {\n        return 2000000.0 + (T_max - move_count);\n    }\n    return (double)tree_size * 1000.0 + total_edges;\n}\n\nbool simulate(const string& moves, int& er, int& ec, int board[10][10]) {\n    er = initial_er; ec = initial_ec;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            board[i][j] = initial_board[i][j];\n        }\n    }\n    for (char m : moves) {\n        int nr = er, nc = ec;\n        if (m == 'U') nr--;\n        else if (m == 'D') nr++;\n        else if (m == 'L') nc--;\n        else if (m == 'R') nc++;\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n        board[er][ec] = board[nr][nc];\n        er = nr; ec = nc;\n    }\n    board[er][ec] = 0;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> T_max)) return 0;\n    for (int i = 0; i < N; i++) {\n        string row; cin >> row;\n        for (int j = 0; j < N; j++) {\n            int type = (row[j] >= 'a' ? row[j] - 'a' + 10 : row[j] - '0');\n            initial_board[i][j] = type;\n            if (type == 0) { initial_er = i; initial_ec = j; }\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    uniform_real_distribution<double> dist_u(0, 1);\n\n    string current_moves = \"\";\n    int current_er, current_ec;\n    simulate(current_moves, current_er, current_ec, current_board);\n    int current_edges;\n    int current_tree = get_tree_score(current_board, current_edges);\n    double current_score = get_score(current_tree, 0, current_edges);\n\n    string best_moves = current_moves;\n    double best_score = current_score;\n\n    double initial_temp = 50.0;\n    double final_temp = 0.1;\n\n    long long iter = 0;\n    while (true) {\n        if ((iter & 0x3FF) == 0) {\n            auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > 2900) break;\n        }\n        iter++;\n\n        string next_moves = current_moves;\n        int m = rng() % 5;\n        if (m == 0 && next_moves.size() < T_max) { // Append\n            next_moves += \"UDLR\"[rng() % 4];\n        } else if (m == 1 && next_moves.size() > 0) { // Pop\n            next_moves.pop_back();\n        } else if (m == 2 && next_moves.size() > 0) { // Replace\n            next_moves[rng() % next_moves.size()] = \"UDLR\"[rng() % 4];\n        } else if (m == 3 && next_moves.size() > 0) { // Delete\n            next_moves.erase(next_moves.begin() + (rng() % next_moves.size()));\n        } else if (m == 4 && next_moves.size() < T_max) { // Insert\n            next_moves.insert(next_moves.begin() + (rng() % (next_moves.size() + 1)), \"UDLR\"[rng() % 4]);\n        }\n\n        int next_er, next_ec;\n        if (simulate(next_moves, next_er, next_ec, next_board)) {\n            int next_edges;\n            int next_tree = get_tree_score(next_board, next_edges);\n            double next_score = get_score(next_tree, (int)next_moves.size(), next_edges);\n\n            auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n            double temp = initial_temp * pow(final_temp / initial_temp, elapsed / 2900.0);\n\n            if (next_score >= current_score || dist_u(rng) < exp((next_score - current_score) / temp)) {\n                current_moves = next_moves;\n                current_score = next_score;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_moves = current_moves;\n                }\n            }\n        }\n    }\n\n    cout << best_moves << endl;\n\n    return 0;\n}\n","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Strawberry structure to keep track of its coordinates and its grid cell\nstruct Strawberry {\n    int x, y;\n    int sx, sy;\n    int posInSlabX;\n    int posInSlabY;\n};\n\n// Global counts and pieces\nint count_grid[52][52];\nint b[5505];\nint a[11];\nint current_sum_min = 0;\n\n// Efficient update of b_d and the score sum(min(a_d, b_d))\nvoid update_b(int d, int delta) {\n    if (d >= 1 && d <= 10) current_sum_min -= min(a[d], b[d]);\n    b[d] += delta;\n    if (d >= 1 && d <= 10) current_sum_min += min(a[d], b[d]);\n}\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K_limit;\n    if (!(cin >> N >> K_limit)) return 0;\n\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Strawberry> strawberries(N);\n    vector<int> all_x, all_y;\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        all_x.push_back(strawberries[i].x);\n        all_y.push_back(strawberries[i].y);\n    }\n\n    // kx and ky are the number of vertical and horizontal cuts, kx+ky <= 100\n    int kx = 50, ky = 50;\n    vector<int> X(kx + 2), Y(ky + 2);\n    X[0] = -1000000; X[kx + 1] = 1000000;\n    Y[0] = -1000000; Y[ky + 1] = 1000000;\n\n    // Initialize cuts based on strawberry density\n    sort(all_x.begin(), all_x.end());\n    sort(all_y.begin(), all_y.end());\n    for (int i = 1; i <= kx; ++i) X[i] = all_x[i * N / (kx + 1)];\n    for (int j = 1; j <= ky; ++j) Y[j] = all_y[j * N / (ky + 1)];\n\n    // Ensure all cuts are strictly increasing and within integer point boundaries\n    for (int i = 1; i <= kx; ++i) if (X[i] <= X[i - 1]) X[i] = X[i - 1] + 1;\n    for (int i = kx; i >= 1; --i) if (X[i] >= X[i + 1]) X[i] = X[i + 1] - 1;\n    for (int j = 1; j <= ky; ++j) if (Y[j] <= Y[j - 1]) Y[j] = Y[j - 1] + 1;\n    for (int j = ky; j >= 1; --j) if (Y[j] >= Y[j + 1]) Y[j] = Y[j + 1] - 1;\n\n    vector<vector<int>> SlabX(kx + 1), SlabY(ky + 1);\n    for (int d = 0; d <= N; ++d) b[d] = 0;\n\n    // Assign strawberries to slabs and grid cells\n    for (int i = 0; i < N; ++i) {\n        int sx = 0;\n        while (sx < kx && strawberries[i].x > X[sx + 1]) sx++;\n        int sy = 0;\n        while (sy < ky && strawberries[i].y > Y[sy + 1]) sy++;\n\n        strawberries[i].sx = sx;\n        strawberries[i].sy = sy;\n        strawberries[i].posInSlabX = SlabX[sx].size();\n        SlabX[sx].push_back(i);\n        strawberries[i].posInSlabY = SlabY[sy].size();\n        SlabY[sy].push_back(i);\n\n        update_b(count_grid[sx][sy], -1);\n        count_grid[sx][sy]++;\n        update_b(count_grid[sx][sy], 1);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    long long iterations = 0;\n\n    // Optimization through Hill Climbing\n    while (true) {\n        if ((iterations & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2850) break;\n        }\n        iterations++;\n\n        bool is_x = rng() % 2 == 0;\n        if (is_x) {\n            int i = rng() % kx + 1;\n            int oldX = X[i];\n            int range = X[i + 1] - X[i - 1] - 1;\n            if (range <= 0) continue;\n\n            int newX;\n            int r = rng() % 100;\n            if (r < 50) newX = X[i] + (rng() % 21 - 10);\n            else if (r < 80) newX = strawberries[rng() % N].x;\n            else newX = X[i - 1] + 1 + rng() % range;\n            if (newX <= X[i - 1] || newX >= X[i + 1]) newX = X[i - 1] + 1 + (rng() % range);\n            if (newX == oldX) continue;\n\n            vector<int> moved_k;\n            if (newX > oldX) {\n                for (int k : SlabX[i]) if (strawberries[k].x <= newX) moved_k.push_back(k);\n            } else {\n                for (int k : SlabX[i - 1]) if (strawberries[k].x > newX) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sy = strawberries[k].sy;\n                if (newX > oldX) { // move from SlabX[i] to SlabX[i-1]\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                } else { // move from SlabX[i-1] to SlabX[i]\n                    update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                    update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                }\n            }\n\n            // Accept if score improved or stayed the same (plateau-walking)\n            if (current_sum_min >= prev_sum) {\n                X[i] = newX;\n                for (int k : moved_k) {\n                    int old_sx = strawberries[k].sx;\n                    int new_sx = (newX > oldX) ? i - 1 : i;\n                    // Slab update: O(1) remove/add\n                    int pos = strawberries[k].posInSlabX;\n                    int last_k = SlabX[old_sx].back();\n                    SlabX[old_sx][pos] = last_k;\n                    strawberries[last_k].posInSlabX = pos;\n                    SlabX[old_sx].pop_back();\n                    strawberries[k].sx = new_sx;\n                    strawberries[k].posInSlabX = SlabX[new_sx].size();\n                    SlabX[new_sx].push_back(k);\n                }\n            } else { // Undo changes if rejected\n                for (int k : moved_k) {\n                    int sy = strawberries[k].sy;\n                    if (newX > oldX) {\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]--; update_b(count_grid[i - 1][sy], 1);\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]++; update_b(count_grid[i][sy], 1);\n                    } else {\n                        update_b(count_grid[i][sy], -1); count_grid[i][sy]--; update_b(count_grid[i][sy], 1);\n                        update_b(count_grid[i - 1][sy], -1); count_grid[i - 1][sy]++; update_b(count_grid[i - 1][sy], 1);\n                    }\n                }\n            }\n        } else {\n            // Symmetrical horizontal move\n            int j = rng() % ky + 1;\n            int oldY = Y[j];\n            int range = Y[j + 1] - Y[j - 1] - 1;\n            if (range <= 0) continue;\n\n            int newY;\n            int r = rng() % 100;\n            if (r < 50) newY = Y[j] + (rng() % 21 - 10);\n            else if (r < 80) newY = strawberries[rng() % N].y;\n            else newY = Y[j - 1] + 1 + rng() % range;\n            if (newY <= Y[j - 1] || newY >= Y[j + 1]) newY = Y[j - 1] + 1 + (rng() % range);\n            if (newY == oldY) continue;\n\n            vector<int> moved_k;\n            if (newY > oldY) {\n                for (int k : SlabY[j]) if (strawberries[k].y <= newY) moved_k.push_back(k);\n            } else {\n                for (int k : SlabY[j - 1]) if (strawberries[k].y > newY) moved_k.push_back(k);\n            }\n\n            int prev_sum = current_sum_min;\n            for (int k : moved_k) {\n                int sx = strawberries[k].sx;\n                if (newY > oldY) { // move from SlabY[j] to SlabY[j-1]\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                } else { // move from SlabY[j-1] to SlabY[j]\n                    update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                    update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                }\n            }\n\n            if (current_sum_min >= prev_sum) {\n                Y[j] = newY;\n                for (int k : moved_k) {\n                    int old_sy = strawberries[k].sy;\n                    int new_sy = (newY > oldY) ? j - 1 : j;\n                    int pos = strawberries[k].posInSlabY;\n                    int last_k = SlabY[old_sy].back();\n                    SlabY[old_sy][pos] = last_k;\n                    strawberries[last_k].posInSlabY = pos;\n                    SlabY[old_sy].pop_back();\n                    strawberries[k].sy = new_sy;\n                    strawberries[k].posInSlabY = SlabY[new_sy].size();\n                    SlabY[new_sy].push_back(k);\n                }\n            } else {\n                for (int k : moved_k) {\n                    int sx = strawberries[k].sx;\n                    if (newY > oldY) {\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]--; update_b(count_grid[sx][j - 1], 1);\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]++; update_b(count_grid[sx][j], 1);\n                    } else {\n                        update_b(count_grid[sx][j], -1); count_grid[sx][j]--; update_b(count_grid[sx][j], 1);\n                        update_b(count_grid[sx][j - 1], -1); count_grid[sx][j - 1]++; update_b(count_grid[sx][j - 1], 1);\n                    }\n                }\n            }\n        }\n    }\n\n    // Output formatting\n    cout << kx + ky << endl;\n    for (int i = 1; i <= kx; ++i) {\n        // Vertical lines x ~ X[i] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << X[i] << \" -1000000000 \" << X[i] + 1 << \" 1000000000\" << endl;\n    }\n    for (int j = 1; j <= ky; ++j) {\n        // Horizontal lines y ~ Y[j] + 0.5 using tilted integer coordinates to avoid center hits\n        cout << \"-1000000000 \" << Y[j] << \" 1000000000 \" << Y[j] + 1 << endl;\n    }\n\n    return 0;\n}\n","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\n/**\n * RectJoin Solver\n * \n * Approach: Multi-start Global Greedy using a Priority Queue.\n * \n * Each trial starts from the initial grid configuration and iteratively adds \n * the globally best rectangle move based on a heuristic score.\n * \n * Heuristic Score: Score = (weight of p1)^w_bias / (rectangle_size)^alpha\n * Weights favor grid points further from the center, encouraging boundary expansion.\n * \n * After each move, the solver re-evaluates all points collinear with the new dots \n * and segments, updating the priority queue with potential new best moves.\n */\n\nstruct Point {\n    int8_t 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 Move {\n    int8_t x1, y1;\n    int8_t p2x, p2y, p3x, p3y, p4x, p4y;\n    int8_t d1, d2;\n    float score;\n    bool operator<(const Move& other) const { return score < other.score; }\n};\n\n// Standard 8 directions: Right, UR, Up, UL, Left, DL, Down, DR.\nconst int dx[] = {1, 1, 0, -1, -1, -1, 0, 1};\nconst int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};\n\n// 90-degree corner pairs from the 8 direction array indices.\nconst pair<int, int> ortho[] = {{0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}, {6, 0}, {7, 1}};\n\nint N, M;\nlong long weights[61][61];\nbool init_has_dot[61][61];\nbool has_dot[61][61];\nbool used[61][61][8];\ndouble weight_score_cache[61][61];\ndouble d_sq_pow_cache[8000];\n\n/**\n * find_nearest: Locates the nearest existing dot from point (x, y) in direction d.\n * Checks for segments blocking the path according to Rule 3.\n */\ninline Point find_nearest(int x, int y, int d) {\n    int cx = x, cy = y;\n    while (true) {\n        if (used[cx][cy][d]) return {-1, -1};\n        int nx = cx + dx[d], ny = cy + dy[d];\n        if (nx < 0 || nx >= N || ny < 0 || ny >= N) break;\n        cx = nx; cy = ny;\n        if (has_dot[cx][cy]) return {(int8_t)cx, (int8_t)cy};\n    }\n    return {-1, -1};\n}\n\n/**\n * mark_used: Marks all unit segments along a rectangle side as used.\n */\ninline void mark_used(int x1, int y1, int x2, int y2, int d) {\n    int cx = x1, cy = y1;\n    while (cx != x2 || cy != y2) {\n        used[cx][cy][d] = true;\n        int nx = cx + dx[d], ny = cy + dy[d];\n        used[nx][ny][(d + 4) % 8] = true;\n        cx = nx; cy = ny;\n    }\n}\n\n/**\n * find_best_move_for_p1: Evaluates all corner orientations for an empty grid point.\n */\ninline Move find_best_move_for_p1(int x1, int y1, double noise) {\n    Move best_m = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1.0f};\n    for (int i = 0; i < 8; i++) {\n        int d1 = ortho[i].first, d2 = ortho[i].second;\n        Point p2 = find_nearest(x1, y1, d1);\n        if (p2.x == -1) continue;\n        Point p4 = find_nearest(x1, y1, d2);\n        if (p4.x == -1) continue;\n        int p3x = p2.x + p4.x - x1, p3y = p2.y + p4.y - y1;\n        if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N || !has_dot[p3x][p3y]) continue;\n        \n        // Rule 2 & 3: Ensure remaining paths p2-p3 and p4-p3 are clear.\n        if (find_nearest(p2.x, p2.y, d2) != Point{(int8_t)p3x, (int8_t)p3y}) continue;\n        if (find_nearest(p4.x, p4.y, d1) != Point{(int8_t)p3x, (int8_t)p3y}) continue;\n        \n        int d_sq = (x1 - p2.x) * (x1 - p2.x) + (y1 - p2.y) * (y1 - p2.y) +\n                   (x1 - p4.x) * (x1 - p4.x) + (y1 - p4.y) * (y1 - p4.y);\n        float score = (float)(weight_score_cache[x1][y1] / d_sq_pow_cache[min(d_sq, 7999)] * noise);\n        if (score > best_m.score) {\n            best_m = {(int8_t)x1, (int8_t)y1, (int8_t)p2.x, (int8_t)p2.y, (int8_t)p3x, (int8_t)p3y, (int8_t)p4.x, (int8_t)p4.y, (int8_t)d1, (int8_t)d2, score};\n        }\n    }\n    return best_m;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(NULL);\n    if (!(cin >> N >> M)) return 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) init_has_dot[i][j] = false;\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; init_has_dot[x][y] = true; }\n    \n    int center = (N - 1) / 2;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            weights[x][y] = (long long)(x - center) * (x - center) + (long long)(y - center) * (y - center) + 1;\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(42);\n    long long global_best_weight_sum = -1;\n    vector<Move> global_best_ops;\n    vector<pair<int, int>> p1_candidates;\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!init_has_dot[x][y]) p1_candidates.push_back({x, y});\n\n    int trial = 0;\n    while (true) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 4750) break;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                has_dot[i][j] = init_has_dot[i][j];\n                for (int d = 0; d < 8; d++) used[i][j][d] = false;\n            }\n        }\n\n        double alpha, w_bias;\n        if (trial == 0) { alpha = 1.8; w_bias = 1.0; }\n        else if (trial == 1) { alpha = 3.5; w_bias = 1.0; }\n        else if (trial == 2) { alpha = 1.2; w_bias = 1.2; }\n        else if (trial == 3) { alpha = 2.0; w_bias = 0.5; }\n        else if (trial == 4) { alpha = 4.5; w_bias = 1.0; }\n        else if (trial == 5) { alpha = 1.5; w_bias = 2.0; }\n        else {\n            alpha = 1.0 + (rng() % 4001) / 1000.0;\n            w_bias = 0.5 + (rng() % 1501) / 1000.0;\n        }\n        \n        for (int i = 0; i < 8000; i++) d_sq_pow_cache[i] = (i == 0) ? 1.0 : pow((double)i, alpha);\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) weight_score_cache[i][j] = pow((double)weights[i][j], w_bias);\n        \n        vector<double> point_noise(N * N);\n        for (int i = 0; i < N * N; i++) point_noise[i] = 0.9 + 0.2 * (double)(rng() % 10001) / 10000.0;\n\n        priority_queue<Move> pq;\n        vector<float> best_score_at(N * N, -1.0f);\n        for (auto& p : p1_candidates) {\n            Move m = find_best_move_for_p1(p.first, p.second, point_noise[p.first * N + p.second]);\n            if (m.score > 0) {\n                best_score_at[p.first * N + p.second] = m.score;\n                pq.push(m);\n            }\n        }\n\n        vector<Move> trial_ops;\n        long long current_weight_sum = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (has_dot[x][y]) current_weight_sum += weights[x][y];\n        \n        while (!pq.empty()) {\n            Move m = pq.top(); pq.pop();\n            if (has_dot[m.x1][m.y1] || abs(m.score - best_score_at[m.x1 * N + m.y1]) > 1e-7f) continue;\n            \n            bool valid = true;\n            Point p2 = find_nearest(m.x1, m.y1, m.d1);\n            if (p2.x != m.p2x || p2.y != m.p2y) valid = false;\n            else {\n                Point p4 = find_nearest(m.x1, m.y1, m.d2);\n                if (p4.x != m.p4x || p4.y != m.p4y) valid = false;\n                else if (find_nearest(m.p2x, m.p2y, m.d2) != Point{m.p3x, m.p3y}) valid = false;\n                else if (find_nearest(m.p4x, m.p4y, m.d1) != Point{m.p3x, m.p3y}) valid = false;\n            }\n            \n            if (valid) {\n                has_dot[m.x1][m.y1] = true;\n                mark_used(m.x1, m.y1, m.p2x, m.p2y, m.d1);\n                mark_used(m.p2x, m.p2y, m.p3x, m.p3y, m.d2);\n                mark_used(m.p3x, m.p3y, m.p4x, m.p4y, (m.d1 + 4) % 8);\n                mark_used(m.p4x, m.p4y, m.x1, m.y1, (m.d2 + 4) % 8);\n                trial_ops.push_back(m);\n                current_weight_sum += weights[m.x1][m.y1];\n                \n                Point corners[4] = {{m.x1, m.y1}, {m.p2x, m.p2y}, {m.p3x, m.p3y}, {m.p4x, m.p4y}};\n                for (int i = 0; i < 4; ++i) {\n                    Point c = corners[i];\n                    for (int d = 0; d < 8; d++) {\n                        int cx = c.x, cy = c.y;\n                        while (true) {\n                            cx += dx[d]; cy += dy[d];\n                            if (cx < 0 || cx >= N || cy < 0 || cy >= N) break;\n                            if (!has_dot[cx][cy]) {\n                                int cx_idx = cx * N + cy;\n                                Move nm = find_best_move_for_p1(cx, cy, point_noise[cx_idx]);\n                                best_score_at[cx_idx] = nm.score;\n                                if (nm.score > 0) pq.push(nm);\n                            }\n                        }\n                    }\n                }\n            } else {\n                Move nm = find_best_move_for_p1(m.x1, m.y1, point_noise[m.x1 * N + m.y1]);\n                best_score_at[m.x1 * N + m.y1] = nm.score;\n                if (nm.score > 0) pq.push(nm);\n            }\n        }\n\n        if (current_weight_sum > global_best_weight_sum) {\n            global_best_weight_sum = current_weight_sum;\n            global_best_ops = trial_ops;\n        }\n        trial++;\n    }\n\n    cout << global_best_ops.size() << \"\\n\";\n    for (const auto& m : global_best_ops) {\n        cout << (int)m.x1 << \" \" << (int)m.y1 << \" \" << (int)m.p2x << \" \" << (int)m.p2y << \" \"\n             << (int)m.p3x << \" \" << (int)m.p3y << \" \" << (int)m.p4x << \" \" << (int)m.p4y << \"\\n\";\n    }\n    return 0;\n}\n","ahc015":"#include <iostream>\n#include <vector>\n#include <chrono>\n#include <algorithm>\n#include <cstdint>\n\nusing namespace std;\nusing namespace std::chrono;\n\n/**\n * Xorshift algorithm for fast pseudo-random number generation.\n * Essential for getting more Monte Carlo trials within the time limit.\n */\nstruct Xorshift {\n    uint32_t x;\n    Xorshift(uint32_t seed = 123456789) : x(seed) {}\n    uint32_t next() {\n        x ^= (x << 13);\n        x ^= (x >> 17);\n        x ^= (x << 5);\n        return x;\n    }\n};\n\n/**\n * Represents the 10x10 candy box grid.\n * We use a 1D array of 100 elements for better cache performance.\n */\nstruct Board {\n    int8_t grid[100]; // 0: empty, 1-3: flavors\n\n    Board() {\n        for (int i = 0; i < 100; ++i) grid[i] = 0;\n    }\n\n    /**\n     * Tilts the box in the specified direction.\n     * 0: Forward (Up), 1: Backward (Down), 2: Left, 3: Right.\n     */\n    bool tilt(int dir) {\n        bool changed = false;\n        if (dir == 0) { // Up\n            for (int j = 0; j < 10; ++j) {\n                int last = 0;\n                for (int i = 0; i < 10; ++i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 1) { // Down\n            for (int j = 0; j < 10; ++j) {\n                int last = 9;\n                for (int i = 9; i >= 0; --i) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (i != last) {\n                            grid[last * 10 + j] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        } else if (dir == 2) { // Left\n            for (int i = 0; i < 10; ++i) {\n                int last = 0;\n                for (int j = 0; j < 10; ++j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last++;\n                    }\n                }\n            }\n        } else if (dir == 3) { // Right\n            for (int i = 0; i < 10; ++i) {\n                int last = 9;\n                for (int j = 9; j >= 0; --j) {\n                    int idx = i * 10 + j;\n                    if (grid[idx]) {\n                        if (j != last) {\n                            grid[i * 10 + last] = grid[idx];\n                            grid[idx] = 0;\n                            changed = true;\n                        }\n                        last--;\n                    }\n                }\n            }\n        }\n        return changed;\n    }\n\n    /**\n     * Places the actual candy received into the p-th available empty cell.\n     */\n    void place_actual(int p, int flavor) {\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                if (++count == p) {\n                    grid[i] = (int8_t)flavor;\n                    return;\n                }\n            }\n        }\n    }\n\n    /**\n     * Randomly places a candy of the given flavor into an empty cell.\n     */\n    void place_randomly(int flavor, Xorshift& rng) {\n        int empty_indices[100], num_empty = 0;\n        for (int i = 0; i < 100; ++i) if (grid[i] == 0) empty_indices[num_empty++] = i;\n        if (num_empty > 0) {\n            grid[empty_indices[rng.next() % num_empty]] = (int8_t)flavor;\n        }\n    }\n\n    /**\n     * Calculates the sum of squares of connected component sizes.\n     * Note: This function modifies the grid to mark visited nodes.\n     */\n    int eval_score_and_destroy() {\n        int sum_sq = 0;\n        int q[100];\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] <= 0) continue;\n            int head = 0, tail = 0, flavor = grid[i];\n            q[tail++] = i;\n            grid[i] = -flavor; // Mark as visited\n            while (head < tail) {\n                int cur = q[head++];\n                if (cur >= 10 && grid[cur - 10] == flavor) { grid[cur - 10] = -flavor; q[tail++] = cur - 10; }\n                if (cur < 90 && grid[cur + 10] == flavor) { grid[cur + 10] = -flavor; q[tail++] = cur + 10; }\n                if (cur % 10 > 0 && grid[cur - 1] == flavor) { grid[cur - 1] = -flavor; q[tail++] = cur - 1; }\n                if (cur % 10 < 9 && grid[cur + 1] == flavor) { grid[cur + 1] = -flavor; q[tail++] = cur + 1; }\n            }\n            sum_sq += tail * tail;\n        }\n        return sum_sq;\n    }\n};\n\n// 4 different corner-clustering strategies for rollouts\nconst int policies[4][4] = {\n    {0, 2, 3, 1}, // Up, Left priority (Top-Left corner)\n    {0, 3, 2, 1}, // Up, Right priority (Top-Right corner)\n    {1, 2, 3, 0}, // Down, Left priority (Bottom-Left corner)\n    {1, 3, 2, 0}  // Down, Right priority (Bottom-Right corner)\n};\n\ninline void apply_policy(Board& b, int p_idx) {\n    const int* p = policies[p_idx];\n    if (b.tilt(p[0])) return;\n    if (b.tilt(p[1])) return;\n    if (b.tilt(p[2])) return;\n    b.tilt(p[3]);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Xorshift rng;\n    Board current_board;\n    char d_chars[] = {'F', 'B', 'L', 'R'};\n    auto start_prog = steady_clock::now();\n\n    for (int t = 0; t < 100; ++t) {\n        int p; cin >> p;\n        current_board.place_actual(p, flavors[t]);\n\n        auto turn_start = steady_clock::now();\n        double elapsed = duration<double>(turn_start - start_prog).count();\n        double turn_time = (1.95 - elapsed) / (100.0 - t);\n        if (turn_time < 0.002) turn_time = 0.002;\n\n        double scores[4] = {0};\n        int trials[4] = {0};\n        int total_trials = 0;\n        int d_idx = rng.next() % 4;\n\n        while (true) {\n            if (total_trials % 32 == 0) {\n                if (duration<double>(steady_clock::now() - turn_start).count() > turn_time) break;\n            }\n\n            int d = d_idx % 4;\n            Board sim = current_board;\n            sim.tilt(d);\n\n            int p_idx = rng.next() % 4; // Use one of the 4 corner policies\n            for (int k = t + 1; k < 100; ++k) {\n                sim.place_randomly(flavors[k], rng);\n                apply_policy(sim, p_idx);\n            }\n\n            scores[d] += sim.eval_score_and_destroy();\n            trials[d]++;\n            total_trials++;\n            d_idx++;\n        }\n\n        int best_d = 0;\n        double max_avg = -1.0;\n        for (int d = 0; d < 4; ++d) {\n            if (trials[d] > 0) {\n                double avg = scores[d] / trials[d];\n                if (avg > max_avg) {\n                    max_avg = avg;\n                    best_d = d;\n                }\n            }\n        }\n\n        cout << d_chars[best_d] << endl;\n        current_board.tilt(best_d);\n    }\n\n    return 0;\n}\n","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Normal CDF function: Phi(x) = 0.5 * (1 + erf((x - mean) / (sigma * sqrt(2))))\n * This function calculates the probability that a random variable following a normal \n * distribution with the given mean and sigma is less than x.\n */\ndouble normal_cdf(double x, double mean, double sigma) {\n    if (sigma < 1e-9) {\n        if (x < mean) return 0.0;\n        if (x > mean) return 1.0;\n        return 0.5;\n    }\n    return 0.5 * (1.0 + erf((x - mean) / (sigma * sqrt(2.0))));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    double eps;\n    // Read the number of graphs M and the error rate epsilon.\n    if (!(cin >> M >> eps)) return 0;\n\n    int bestN = 4;\n    double bestExpectedScore = -1.0;\n\n    // Iterate through all possible values for N (the number of vertices) to find the one that \n    // maximizes the expected score. The score is calculated based on the expected number of \n    // errors using an edge count encoding/decoding method.\n    for (int N = 4; N <= 100; ++N) {\n        int K = N * (N - 1) / 2; // Maximum number of possible edges.\n        vector<int> Es(M);\n        for (int s = 0; s < M; ++s) {\n            // Encode the number of edges for each graph G_s.\n            Es[s] = (int)round((double)s * K / (M - 1));\n        }\n\n        // Standard deviation of the edge count after noise (Binomial sum approximation).\n        double sigma = sqrt((double)K * eps * (1.0 - eps));\n        double P_avg = 0.0;\n\n        for (int s = 0; s < M; ++s) {\n            // Count how many graphs have the same number of edges as G_s.\n            int c = 0;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] == Es[s]) c++;\n            }\n\n            // The expected mean number of edges in the noisy graph H generated from G_s.\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n\n            // Find the closest different edge counts to identify the decision boundaries.\n            double E_prev = -1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] < Es[s]) {\n                    if (E_prev < -1e17 || Es[j] > E_prev) {\n                        E_prev = (double)Es[j];\n                    }\n                }\n            }\n\n            double E_next = 1e18;\n            for (int j = 0; j < M; ++j) {\n                if (Es[j] > Es[s]) {\n                    if (E_next > 1e17 || Es[j] < E_next) {\n                        E_next = (double)Es[j];\n                    }\n                }\n            }\n\n            double low, high;\n            if (E_prev < -1e17) {\n                low = -1e18; // No lower bound for the first category.\n            } else {\n                double mu_prev = E_prev * (1.0 - 2.0 * eps) + (double)K * eps;\n                low = (mu_s + mu_prev) / 2.0;\n            }\n\n            if (E_next > 1e17) {\n                high = 1e18; // No upper bound for the last category.\n            } else {\n                double mu_next = E_next * (1.0 - 2.0 * eps) + (double)K * eps;\n                high = (mu_s + mu_next) / 2.0;\n            }\n\n            // Estimate the probability of correct decoding for the s-th graph.\n            double prob_correct_in_range;\n            if (sigma < 1e-9) {\n                prob_correct_in_range = 1.0;\n            } else {\n                prob_correct_in_range = normal_cdf(high, mu_s, sigma) - normal_cdf(low, mu_s, sigma);\n            }\n            // If multiple graphs have the same edge count, they are indistinguishable.\n            P_avg += prob_correct_in_range / (double)c;\n        }\n\n        // Calculate the overall expected probability of a correct prediction.\n        P_avg /= (double)M;\n        double p_error = 1.0 - P_avg;\n        // Expected absolute score formula: (1 - 0.1 * p_error)^100 / N.\n        double expectedScore = pow(1.0 - 0.1 * p_error, 100) / (double)N;\n\n        if (expectedScore > bestExpectedScore) {\n            bestExpectedScore = expectedScore;\n            bestN = N;\n        }\n    }\n\n    // Set up the selected N and the corresponding graphs G_0, ..., G_{M-1}.\n    int N = bestN;\n    int K = N * (N - 1) / 2;\n    vector<int> Es(M);\n    for (int s = 0; s < M; ++s) {\n        Es[s] = (int)round((double)s * K / (M - 1));\n    }\n\n    // Output the chosen number of vertices N.\n    cout << N << endl;\n    // Output the string representations for the M graphs.\n    for (int s = 0; s < M; ++s) {\n        string g(K, '0');\n        for (int i = 0; i < Es[s]; ++i) {\n            g[i] = '1';\n        }\n        cout << g << endl;\n    }\n    cout.flush();\n\n    // Process 100 noisy graph queries.\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        if (!(cin >> H)) break;\n        // Count the number of edges in the received graph H.\n        int EH = 0;\n        for (char c : H) {\n            if (c == '1') EH++;\n        }\n\n        // Find the graph s whose expected noisy edge count mean is closest to EH.\n        int best_s = 0;\n        double min_diff = 1e18;\n        for (int s = 0; s < M; ++s) {\n            double mu_s = (double)Es[s] * (1.0 - 2.0 * eps) + (double)K * eps;\n            double diff = abs((double)EH - mu_s);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        // Output the prediction for the current query.\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}\n","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Takahashi City Road Repair Problem\n * \n * Objective: Minimize the average frustration level for road repairs over D days.\n * Frustration is defined as the expected increase in shortest distance between\n * all pairs of vertices when some edges are closed for repair on a given day.\n * \n * Strategy:\n * 1. Initial Assignment: Sort edges based on their spatial orientation (angle from \n *    the centroid of the city) and distribute them across D days using a round-robin \n *    method. This ensures that roads under repair on any single day are geographically \n *    spread out, reducing the likelihood of major detours or disconnection.\n * 2. Proxy Frustration Function: Instead of computing all-pairs shortest paths, we \n *    compute paths from a fixed set of S=8 source vertices selected via Farthest \n *    Point Sampling (FPS) to ensure uniform spatial coverage. S=8 provides a \n *    balance between proxy fidelity and the number of optimization iterations.\n * 3. Local Optimization (Hill Climbing): Iteratively improve the repair schedule \n *    by swapping the repair days of two edges or moving an edge from one day to \n *    another. The algorithm focuses 80% of its attempts on the day with the \n *    highest current frustration level to flatten peaks and minimize the total sum.\n * 4. Time Management: Runs as many iterations as possible within a 5.85s limit.\n */\n\n// Global Constants\nconst int INF_VAL = 1000000000;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int to, weight, id;\n};\n\n// Global graph and problem data\nvector<Edge> adj[MAXN];\nint edge_u[MAXM], edge_v[MAXM], edge_w[MAXM];\nint edge_day_arr[MAXM];\nint base_dists[15][MAXN]; // Original shortest path distances from selected sources\nint X[MAXN], Y[MAXN];\nint N, M, D, K;\n\n// Dijkstra global state for efficiency\nint dists_buf[MAXN];\nint vis[MAXN];\nint timer = 0;\nvector<int> sources;\npriority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n\n/**\n * Optimized Dijkstra's algorithm.\n * Calculates shortest paths from 'start' node while ignoring edges assigned to 'repair_day'.\n */\nvoid dijkstra(int start, int repair_day) {\n    timer++;\n    dists_buf[start] = 0;\n    vis[start] = timer;\n    pq.push({0, start});\n    \n    while (!pq.empty()) {\n        pair<int, int> top = pq.top();\n        pq.pop();\n        int d = top.first;\n        int u = top.second;\n        if (d > dists_buf[u]) continue;\n        \n        for (const auto& e : adj[u]) {\n            if (edge_day_arr[e.id] == repair_day) continue;\n            int vd = d + e.weight;\n            if (vis[e.to] != timer || vd < dists_buf[e.to]) {\n                dists_buf[e.to] = vd;\n                vis[e.to] = timer;\n                pq.push({vd, e.to});\n            }\n        }\n    }\n}\n\n/**\n * Proxy for a day's frustration level.\n * Sum over selected sources of (modified_shortest_path - original_shortest_path).\n */\nlong long compute_frustration(int day) {\n    long long total = 0;\n    for (int i = 0; i < (int)sources.size(); ++i) {\n        dijkstra(sources[i], day);\n        for (int j = 1; j <= N; ++j) {\n            int d_orig = base_dists[i][j];\n            int d_new = (vis[j] == timer) ? min(dists_buf[j], INF_VAL) : INF_VAL;\n            total += (long long)(d_new - d_orig);\n        }\n    }\n    return total;\n}\n\nstruct EdgeInfo {\n    int id;\n    double angle;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read Input\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    for (int i = 1; i <= M; ++i) {\n        cin >> edge_u[i] >> edge_v[i] >> edge_w[i];\n        adj[edge_u[i]].push_back({edge_v[i], edge_w[i], i});\n        adj[edge_v[i]].push_back({edge_u[i], edge_w[i], i});\n    }\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    mt19937 rng(42);\n\n    // 1. Source vertex selection using Farthest Point Sampling (FPS)\n    int S_count = 8;\n    sources.push_back(1);\n    for (int i = 1; i < S_count; ++i) {\n        int best_v = -1;\n        long long max_d = -1;\n        for (int v = 1; v <= N; ++v) {\n            long long min_d = 1e18;\n            for (int s : sources) {\n                long long d = (long long)(X[v]-X[s])*(X[v]-X[s]) + (long long)(Y[v]-Y[s])*(Y[v]-Y[s]);\n                if (d < min_d) min_d = d;\n            }\n            if (min_d > max_d) { max_d = min_d; best_v = v; }\n        }\n        sources.push_back(best_v);\n    }\n\n    // 2. Precompute original distances from selected sources\n    for (int j = 1; j <= M; j++) edge_day_arr[j] = -1;\n    for (int i = 0; i < S_count; ++i) {\n        dijkstra(sources[i], -2);\n        for (int j = 1; j <= N; ++j) {\n            base_dists[i][j] = (vis[j] == timer) ? min(dists_buf[j], INF_VAL) : INF_VAL;\n        }\n    }\n\n    // 3. Spatially sorted initial assignment (Angular sort)\n    double cx = 0, cy = 0;\n    for (int i = 1; i <= N; ++i) { cx += X[i]; cy += Y[i]; }\n    cx /= (double)N; cy /= (double)N;\n    vector<EdgeInfo> sorted_edges(M);\n    for (int i = 1; i <= M; ++i) {\n        double mx = (X[edge_u[i]] + X[edge_v[i]]) / 2.0;\n        double my = (Y[edge_u[i]] + Y[edge_v[i]]) / 2.0;\n        sorted_edges[i-1] = {i, atan2(my - cy, mx - cx)};\n    }\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const EdgeInfo& a, const EdgeInfo& b) {\n        return a.angle < b.angle;\n    });\n\n    vector<vector<int>> day_lists(D + 1);\n    for (int i = 0; i < M; ++i) {\n        int d = (i % D) + 1;\n        edge_day_arr[sorted_edges[i].id] = d;\n        day_lists[d].push_back(sorted_edges[i].id);\n    }\n\n    // Initial frustration values per day\n    vector<long long> day_frust(D + 1);\n    for (int d = 1; d <= D; ++d) day_frust[d] = compute_frustration(d);\n\n    // 4. Local Optimization (Hill Climbing)\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n    while (true) {\n        if ((++iterations & 63) == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5850) break;\n        }\n\n        int d1, d2;\n        // 80% bias to pick the highest frustration day as a target for reduction\n        if (uniform_int_distribution<int>(0, 4)(rng) > 0) {\n            int best_d = 1;\n            for (int d = 2; d <= D; d++) if (day_frust[d] > day_frust[best_d]) best_d = d;\n            d1 = best_d;\n        } else {\n            d1 = uniform_int_distribution<int>(1, D)(rng);\n        }\n        d2 = uniform_int_distribution<int>(1, D)(rng);\n        while (d1 == d2) d2 = uniform_int_distribution<int>(1, D)(rng);\n\n        if (day_lists[d1].empty()) continue;\n\n        // Choice: either Move an edge or Swap two edges between days\n        if (uniform_int_distribution<int>(0, 9)(rng) < 3 && (int)day_lists[d2].size() < K) {\n            // Move operation: transfer e1 from day d1 to d2\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            edge_day_arr[e1] = d2;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1; day_frust[d2] = nf2;\n                day_lists[d2].push_back(e1);\n                day_lists[d1][idx1] = day_lists[d1].back();\n                day_lists[d1].pop_back();\n            } else {\n                edge_day_arr[e1] = d1;\n            }\n        } else if (!day_lists[d2].empty()) {\n            // Swap operation: exchange e1 from d1 and e2 from d2\n            int idx1 = uniform_int_distribution<int>(0, (int)day_lists[d1].size() - 1)(rng);\n            int idx2 = uniform_int_distribution<int>(0, (int)day_lists[d2].size() - 1)(rng);\n            int e1 = day_lists[d1][idx1];\n            int e2 = day_lists[d2][idx2];\n            edge_day_arr[e1] = d2;\n            edge_day_arr[e2] = d1;\n            long long nf1 = compute_frustration(d1);\n            long long nf2 = compute_frustration(d2);\n            if (nf1 + nf2 < day_frust[d1] + day_frust[d2]) {\n                day_frust[d1] = nf1; day_frust[d2] = nf2;\n                day_lists[d1][idx1] = e2;\n                day_lists[d2][idx2] = e1;\n            } else {\n                edge_day_arr[e1] = d1; edge_day_arr[e2] = d2;\n            }\n        }\n    }\n\n    // Final Output (Output repair day for each original edge)\n    for (int i = 1; i <= M; ++i) {\n        cout << edge_day_arr[i] << (i == M ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}\n","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <chrono>\n\nusing namespace std;\n\n// Represents a 1x1x1 cube (voxel) in a 3D grid\nstruct Voxel {\n    int x, y, z;\n    Voxel operator+(const Voxel& o) const { return {x + o.x, y + o.y, z + o.z}; }\n    Voxel operator-(const Voxel& o) const { return {x - o.x, y - o.y, z - o.z}; }\n};\n\n// Represents a 3x3 rotation matrix for 90-degree axis-aligned rotations\nstruct Matrix {\n    int m[3][3];\n};\n\n// Applies a rotation matrix to a voxel coordinate\nVoxel rotate(Voxel v, const Matrix& R) {\n    return {\n        R.m[0][0] * v.x + R.m[0][1] * v.y + R.m[0][2] * v.z,\n        R.m[1][0] * v.x + R.m[1][1] * v.y + R.m[1][2] * v.z,\n        R.m[2][0] * v.x + R.m[2][1] * v.y + R.m[2][2] * v.z\n    };\n}\n\n// Stores info about a potential common polycube block between the two objects\nstruct Candidate {\n    int volume;\n    int ri; // Rotation index\n    int8_t dx, dy, dz; // Translation vector\n    int start_idx; // A starting voxel index in Q1\n\n    // Sorting order: volume descending, then others to make it deterministic\n    bool operator<(const Candidate& o) const {\n        if (volume != o.volume) return volume > o.volume;\n        if (ri != o.ri) return ri < o.ri;\n        if (dx != o.dx) return dx < o.dx;\n        if (dy != o.dy) return dy < o.dy;\n        if (dz != o.dz) return dz < o.dz;\n        return start_idx < o.start_idx;\n    }\n};\n\nint D;\nstring f_sil1[14], r_sil1[14], f_sil2[14], r_sil2[14];\nbool g1[14][14][14], g2[14][14][14]; // Grid occupancy for the maximal set of voxels\nvector<Voxel> Q1, Q2; // Voxel lists for construction 1 and 2\nvector<int> adj1[2744]; // Adjacency list for Q1 voxels\nvector<Matrix> rotations;\nvector<int> inter_v[24][41][41][41]; // Intersection list for each (Rotation, Translation)\nint in_I[2744], vis[2744], t_timer = 0; // Timers for efficient BFS and intersection checks\nbool u1[2744], u2[2744]; // Marks voxels as already used in some block\nbool cf1[14][14], cr1[14][14], cf2[14][14], cr2[14][14]; // Tracks silhouette coverage\nint b1_g[14][14][14], b2_g[14][14][14]; // Block ID grids for Obj 1 and Obj 2\nVoxel Q1r[24][2744]; // Pre-calculated rotated voxel coordinates\nint q1_idx_grid[14][14][14], q2_idx_grid[14][14][14];\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    if (!(cin >> D)) return 0;\n    for (int i=0; i<D; ++i) cin >> f_sil1[i];\n    for (int i=0; i<D; ++i) cin >> r_sil1[i];\n    for (int i=0; i<D; ++i) cin >> f_sil2[i];\n    for (int i=0; i<D; ++i) cin >> r_sil2[i];\n\n    // Compute maximal voxel sets Q1 and Q2 from silhouettes\n    for (int x=0; x<D; ++x) for (int y=0; y<D; ++y) for (int z=0; z<D; ++z) {\n        q1_idx_grid[x][y][z] = q2_idx_grid[x][y][z] = -1;\n        if (f_sil1[z][x]=='1' && r_sil1[z][y]=='1') {\n            g1[x][y][z] = 1;\n            q1_idx_grid[x][y][z] = Q1.size();\n            Q1.push_back({x, y, z});\n        }\n        if (f_sil2[z][x]=='1' && r_sil2[z][y]=='1') {\n            g2[x][y][z] = 1;\n            q2_idx_grid[x][y][z] = Q2.size();\n            Q2.push_back({x, y, z});\n        }\n    }\n\n    // Connectivity info for Q1 voxels\n    int dxs[]={1,-1,0,0,0,0}, dys[]={0,0,1,-1,0,0}, dzs[]={0,0,0,0,1,-1};\n    for (int i=0; i<Q1.size(); ++i) {\n        for (int d=0; d<6; ++d) {\n            int nx=Q1[i].x+dxs[d], ny=Q1[i].y+dys[d], nz=Q1[i].z+dzs[d];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && g1[nx][ny][nz]) {\n                adj1[i].push_back(q1_idx_grid[nx][ny][nz]);\n            }\n        }\n    }\n\n    // Generate all 24 orthonormal matrices with det = 1 (axis-aligned rotations)\n    vector<Voxel> axes = {{1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}};\n    for (auto& ax : axes) for (auto& ay : axes) {\n        if (ax.x*ay.x + ax.y*ay.y + ax.z*ay.z == 0) {\n            Voxel az = {ax.y*ay.z - ax.z*ay.y, ax.z*ay.x - ax.x*ay.z, ax.x*ay.y - ax.y*ay.x};\n            Matrix R;\n            R.m[0][0]=ax.x; R.m[1][0]=ax.y; R.m[2][0]=ax.z;\n            R.m[0][1]=ay.x; R.m[1][1]=ay.y; R.m[2][1]=ay.z;\n            R.m[0][2]=az.x; R.m[1][2]=az.y; R.m[2][2]=az.z;\n            rotations.push_back(R);\n        }\n    }\n\n    // Determine all possible transformations that overlap Q1 and Q2\n    const int OFF = 14;\n    for (int ri=0; ri<24; ++ri) {\n        for (int i=0; i<Q1.size(); ++i) {\n            Q1r[ri][i] = rotate(Q1[i], rotations[ri]);\n            for (int j=0; j<Q2.size(); ++j) {\n                Voxel T = Q2[j] - Q1r[ri][i];\n                inter_v[ri][T.x+OFF][T.y+OFF][T.z+OFF].push_back(i);\n            }\n        }\n    }\n\n    // Decompose transformed intersections into connected components (poly-cube blocks)\n    vector<Candidate> cands;\n    for (int ri=0; ri<24; ++ri) {\n        for (int dx=-14; dx<=14; ++dx) for (int dy=-14; dy<=14; ++dy) for (int dz=-14; dz<=14; ++dz) {\n            auto& I = inter_v[ri][dx+OFF][dy+OFF][dz+OFF];\n            if (I.size() < 2) continue;\n            t_timer++;\n            for (int idx : I) in_I[idx] = t_timer;\n            for (int idx : I) {\n                if (vis[idx] != t_timer) {\n                    vector<int> comp;\n                    queue<int> q; q.push(idx); vis[idx] = t_timer;\n                    while (!q.empty()) {\n                        int u = q.front(); q.pop(); comp.push_back(u);\n                        for (int v : adj1[u]) {\n                            if (in_I[v] == t_timer && vis[v] != t_timer) {\n                                vis[v] = t_timer; q.push(v);\n                            }\n                        }\n                    }\n                    if (comp.size() >= 2) cands.push_back({(int)comp.size(), ri, (int8_t)dx, (int8_t)dy, (int8_t)dz, comp[0]});\n                }\n            }\n        }\n    }\n\n    // Sort and greedily select common blocks that improve silhouette coverage\n    sort(cands.begin(), cands.end());\n    int block_id = 1;\n    for (auto& c : cands) {\n        t_timer++;\n        vector<int> I;\n        for (int i=0; i<Q1.size(); ++i) {\n            Voxel v2 = Q1r[c.ri][i];\n            v2.x += c.dx; v2.y += c.dy; v2.z += c.dz;\n            if (v2.x>=0 && v2.x<D && v2.y>=0 && v2.y<D && v2.z>=0 && v2.z<D && g2[v2.x][v2.y][v2.z]) {\n                in_I[i] = t_timer; I.push_back(i);\n            }\n        }\n        vector<int> comp;\n        queue<int> q; q.push(c.start_idx); vis[c.start_idx] = t_timer;\n        while (!q.empty()) {\n            int u = q.front(); q.pop(); comp.push_back(u);\n            for (int v : adj1[u]) {\n                if (in_I[v] == t_timer && vis[v] != t_timer) {\n                    vis[v] = t_timer; q.push(v);\n                }\n            }\n        }\n        bool available = 1;\n        for (int idx : comp) {\n            Voxel v2 = Q1r[c.ri][idx];\n            v2.x += c.dx; v2.y += c.dy; v2.z += c.dz;\n            if (u1[idx] || u2[q2_idx_grid[v2.x][v2.y][v2.z]]) { available = 0; break; }\n        }\n        if (available) {\n            int covers_new = 0;\n            for (int idx : comp) {\n                Voxel v1 = Q1[idx], v2 = Q1r[c.ri][idx];\n                v2.x += c.dx; v2.y += c.dy; v2.z += c.dz;\n                if (!cf1[v1.z][v1.x] || !cr1[v1.z][v1.y] || !cf2[v2.z][v2.x] || !cr2[v2.z][v2.y]) covers_new++;\n            }\n            if (covers_new > 0) {\n                for (int idx : comp) {\n                    Voxel v1 = Q1[idx], v2 = Q1r[c.ri][idx];\n                    v2.x += c.dx; v2.y += c.dy; v2.z += c.dz;\n                    u1[idx] = 1; u2[q2_idx_grid[v2.x][v2.y][v2.z]] = 1;\n                    cf1[v1.z][v1.x] = 1; cr1[v1.z][v1.y] = 1;\n                    cf2[v2.z][v2.x] = 1; cr2[v2.z][v2.y] = 1;\n                    b1_g[v1.x][v1.y][v1.z] = block_id;\n                    b2_g[v2.x][v2.y][v2.z] = block_id;\n                }\n                block_id++;\n            }\n        }\n    }\n\n    // Cover remaining silhouette pixels with 1x1x1 blocks (shared if possible)\n    auto collect_remaining = [&](int obj) {\n        vector<int> rem;\n        while (1) {\n            int best_v = -1, mx_cov = 0;\n            auto& Q = (obj==1 ? Q1 : Q2);\n            auto& used_ref = (obj==1 ? u1 : u2);\n            auto& f_cov = (obj==1 ? cf1 : cf2);\n            auto& r_cov = (obj==1 ? cr1 : cr2);\n            for (int i=0; i<Q.size(); ++i) {\n                if (used_ref[i]) continue;\n                int n = (!f_cov[Q[i].z][Q[i].x]) + (!r_cov[Q[i].z][Q[i].y]);\n                if (n > mx_cov) { mx_cov = n; best_v = i; }\n            }\n            if (mx_cov == 0) break;\n            rem.push_back(best_v);\n            used_ref[best_v] = 1;\n            f_cov[Q[best_v].z][Q[best_v].x] = 1;\n            r_cov[Q[best_v].z][Q[best_v].y] = 1;\n        }\n        return rem;\n    };\n    vector<int> E1 = collect_remaining(1), E2 = collect_remaining(2);\n    int shared_1x1 = min(E1.size(), E2.size());\n    for (int i=0; i<shared_1x1; ++i) {\n        b1_g[Q1[E1[i]].x][Q1[E1[i]].y][Q1[E1[i]].z] = block_id;\n        b2_g[Q2[E2[i]].x][Q2[E2[i]].y][Q2[E2[i]].z] = block_id;\n        block_id++;\n    }\n    for (int i=shared_1x1; i<E1.size(); ++i) b1_g[Q1[E1[i]].x][Q1[E1[i]].y][Q1[E1[i]].z] = block_id++;\n    for (int i=shared_1x1; i<E2.size(); ++i) b2_g[Q2[E2[i]].x][Q2[E2[i]].y][Q2[E2[i]].z] = block_id++;\n\n    // Output block ID grids\n    cout << block_id - 1 << \"\\n\";\n    for (int x=0; x<D; ++x) for (int y=0; y<D; ++y) for (int z=0; z<D; ++z)\n        cout << b1_g[x][y][z] << (x*D*D+y*D+z == D*D*D-1 ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int x=0; x<D; ++x) for (int y=0; y<D; ++y) for (int z=0; z<D; ++z)\n        cout << b2_g[x][y][z] << (x*D*D+y*D+z == D*D*D-1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) {\n        parent.resize(n + 1);\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    void reset(int n) {\n        for (int i = 0; i <= n; ++i) parent[i] = i;\n    }\n};\n\ninline long long dist2_pts(int x1, int y1, int x2, int y2) {\n    return (long long)(x1 - x2) * (x1 - x2) + (long long)(y1 - y2) * (y1 - y2);\n}\n\nconst long long INF = 1e16;\n\nint main() {\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<pair<int, int>> stations(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> stations[i].first >> stations[i].second;\n\n    vector<Edge> edges(M);\n    vector<vector<int>> adj(N + 1);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) cin >> residents[k].first >> residents[k].second;\n\n    vector<vector<long long>> dist(N + 1, vector<long long>(N + 1, INF));\n    for (int i = 1; i <= N; ++i) dist[i][i] = 0;\n    for (int j = 0; j < M; ++j) {\n        dist[edges[j].u][edges[j].v] = min(dist[edges[j].u][edges[j].v], edges[j].w);\n        dist[edges[j].v][edges[j].u] = min(dist[edges[j].v][edges[j].u], edges[j].w);\n    }\n    for (int k = 1; k <= N; ++k)\n        for (int i = 1; i <= N; ++i)\n            for (int j = 1; j <= N; ++j)\n                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n\n    vector<int> path_edges[101][101];\n    for (int i = 1; i <= N; ++i) {\n        for (int j = 1; j <= N; ++j) {\n            if (i == j) continue;\n            int curr = i;\n            while (curr != j) {\n                bool found = false;\n                for (int e_idx : adj[curr]) {\n                    int next = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);\n                    if (edges[e_idx].w + dist[next][j] == dist[curr][j]) {\n                        path_edges[i][j].push_back(e_idx);\n                        curr = next;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n    }\n\n    vector<vector<long long>> dist2_v_r(N + 1, vector<long long>(K));\n    vector<vector<int>> sorted_v_for_r(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        for (int i = 1; i <= N; ++i) dist2_v_r[i][k] = dist2_pts(stations[i].first, stations[i].second, residents[k].first, residents[k].second);\n        iota(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), 1);\n        sort(sorted_v_for_r[k].begin(), sorted_v_for_r[k].end(), [&](int a, int b) { return dist2_v_r[a][k] < dist2_v_r[b][k]; });\n    }\n\n    vector<int> sorted_edge_indices(M);\n    iota(sorted_edge_indices.begin(), sorted_edge_indices.end(), 0);\n    sort(sorted_edge_indices.begin(), sorted_edge_indices.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n\n    mt19937 rng(42);\n    vector<bool> is_active(N + 1, true);\n    vector<int> nearest_v(K);\n    for (int k = 0; k < K; ++k) nearest_v[k] = sorted_v_for_r[k][0];\n\n    auto start_time = chrono::steady_clock::now();\n    static long long max_d2[101];\n    static int v_req_list[101];\n    static long long prim_min_d[101];\n    static int prim_parent[101];\n    static bool prim_visited[101];\n\n    auto get_cost = [&]() {\n        for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n        int n_req = 0;\n        v_req_list[n_req++] = 1;\n        for (int k = 0; k < K; ++k) {\n            int nv = nearest_v[k];\n            if (dist2_v_r[nv][k] > max_d2[nv]) max_d2[nv] = dist2_v_r[nv][k];\n        }\n\n        long long coverage_cost = 0;\n        for (int i = 1; i <= N; ++i) {\n            if (max_d2[i] > 0) {\n                if (i != 1) v_req_list[n_req++] = i;\n                long long p = (long long)sqrt(max_d2[i]);\n                while (p * p < max_d2[i]) p++;\n                coverage_cost += p * p;\n            }\n        }\n\n        long long tree_cost = 0;\n        if (n_req > 1) {\n            for (int i = 0; i < n_req; ++i) { prim_min_d[i] = INF; prim_visited[i] = false; }\n            prim_min_d[0] = 0; prim_parent[0] = -1;\n            for (int i = 0; i < n_req; ++i) {\n                int u = -1;\n                for (int j = 0; j < n_req; ++j) if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n                if (u == -1) break;\n                prim_visited[u] = true;\n                tree_cost += prim_min_d[u];\n                for (int v = 0; v < n_req; ++v) if (!prim_visited[v]) {\n                    long long d = dist[v_req_list[u]][v_req_list[v]];\n                    if (d < prim_min_d[v]) { prim_min_d[v] = d; prim_parent[v] = u; }\n                }\n            }\n        }\n        return coverage_cost + tree_cost;\n    };\n\n    long long cur_cost = get_cost(), best_cost = cur_cost;\n    vector<bool> best_is_active = is_active;\n    double T_start = 1e6, T_end = 1e3;\n    int iter = 0;\n    uniform_real_distribution<double> dist_unif(0, 1);\n    uniform_int_distribution<int> dist_v_gen(2, N);\n\n    while (true) {\n        if ((iter & 255) == 0) {\n            double elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > 1850.0) break;\n        }\n        iter++;\n        \n        int v = dist_v_gen(rng);\n        bool was_active = is_active[v];\n        is_active[v] = !was_active;\n        vector<pair<int, int>> changes;\n        if (is_active[v]) {\n            for (int k = 0; k < K; ++k) if (dist2_v_r[v][k] < dist2_v_r[nearest_v[k]][k]) {\n                changes.push_back({k, nearest_v[k]});\n                nearest_v[k] = v;\n            }\n        } else {\n            for (int k = 0; k < K; ++k) if (nearest_v[k] == v) {\n                changes.push_back({k, v});\n                for (int nv : sorted_v_for_r[k]) if (is_active[nv]) { nearest_v[k] = nv; break; }\n            }\n        }\n\n        long long next_cost = get_cost();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n        double T = T_start * pow(T_end / T_start, elapsed / 1850.0);\n        if (next_cost < cur_cost || dist_unif(rng) < exp((double)(cur_cost - next_cost) / T)) {\n            cur_cost = next_cost;\n            if (cur_cost < best_cost) { best_cost = cur_cost; best_is_active = is_active; }\n        } else {\n            is_active[v] = was_active;\n            for (auto& p : changes) nearest_v[p.first] = p.second;\n        }\n    }\n\n    is_active = best_is_active;\n    for (int k = 0; k < K; ++k) for (int v : sorted_v_for_r[k]) if (is_active[v]) { nearest_v[k] = v; break; }\n    for (int i = 1; i <= N; ++i) max_d2[i] = 0;\n    for (int k = 0; k < K; ++k) max_d2[nearest_v[k]] = max(max_d2[nearest_v[k]], dist2_v_r[nearest_v[k]][k]);\n    int n_req = 0; v_req_list[n_req++] = 1;\n    for (int i = 2; i <= N; ++i) if (max_d2[i] > 0) v_req_list[n_req++] = i;\n\n    vector<int> final_B(M, 0);\n    if (n_req > 1) {\n        vector<int> union_edges;\n        static int edge_ts[301] = {0};\n        int ts = 1;\n        for (int i = 0; i < n_req; ++i) { prim_min_d[i] = INF; prim_visited[i] = false; }\n        prim_min_d[0] = 0; prim_parent[0] = -1;\n        for (int i = 0; i < n_req; ++i) {\n            int u = -1;\n            for (int j = 0; j < n_req; ++j) if (!prim_visited[j] && (u == -1 || prim_min_d[j] < prim_min_d[u])) u = j;\n            if (u == -1) break;\n            prim_visited[u] = true;\n            if (prim_parent[u] != -1) {\n                for (int e_id : path_edges[v_req_list[u]][v_req_list[prim_parent[u]]]) {\n                    if (edge_ts[e_id] != ts) { edge_ts[e_id] = ts; union_edges.push_back(e_id); }\n                }\n            }\n            for (int v = 0; v < n_req; ++v) if (!prim_visited[v]) {\n                long long d = dist[v_req_list[u]][v_req_list[v]];\n                if (d < prim_min_d[v]) { prim_min_d[v] = d; prim_parent[v] = u; }\n            }\n        }\n        DSU dsu(N);\n        sort(union_edges.begin(), union_edges.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n        for (int e_id : union_edges) if (dsu.unite(edges[e_id].u, edges[e_id].v)) final_B[e_id] = 1;\n    }\n\n    vector<int> reach; vector<int> q = {1}; vector<bool> vis(N + 1, false); vis[1] = true;\n    int head = 0;\n    while(head < (int)q.size()){\n        int u = q[head++]; reach.push_back(u);\n        for(int e_idx : adj[u]) if(final_B[e_idx]){\n            int v = (edges[e_idx].u == u ? edges[e_idx].v : edges[e_idx].u);\n            if(!vis[v]) { vis[v] = true; q.push_back(v); }\n        }\n    }\n    vector<long long> f_max_d2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        long long md = 8e18; int bv = -1;\n        for (int v : reach) { long long d = dist2_v_r[v][k]; if (d < md) { md = d; bv = v; } }\n        if (bv != -1) f_max_d2[bv] = max(f_max_d2[bv], md);\n    }\n    vector<int> final_P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) if (f_max_d2[i] > 0) {\n        long long p = (long long)sqrt(f_max_d2[i]);\n        while (p * p < f_max_d2[i]) p++;\n        final_P[i] = (int)p;\n    }\n    while (true) {\n        bool cg = false; vector<int> d_deg(N + 1, 0);\n        for (int j = 0; j < M; ++j) if (final_B[j]) { d_deg[edges[j].u]++; d_deg[edges[j].v]++; }\n        for (int i = 2; i <= N; ++i) if (d_deg[i] == 1 && final_P[i] == 0) {\n            for (int j = 0; j < M; ++j) if (final_B[j] && (edges[j].u == i || edges[j].v == i)) { final_B[j] = 0; cg = true; break; }\n        }\n        if (!cg) break;\n    }\n\n    for (int i = 1; i <= N; ++i) cout << min(final_P[i], 5000) << (i == N ? \"\" : \" \");\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) cout << final_B[j] << (j == M - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc021":"#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 Summary:\n * We need to arrange 465 balls in a 30-tiered pyramid (N=30) to satisfy the min-heap property.\n * Every ball (x, y) must be smaller than its children (x+1, y) and (x+1, y+1).\n * The goal is to minimize the number of swaps K while ensuring no violations (E=0).\n */\n\nconst int N = 30;\nconst int NUM_BALLS = N * (N + 1) / 2;\n\nstruct Move {\n    int x1, y1, x2, y2;\n};\n\nint initial_pyramid[N][N];\nint pyramid[N][N];\nint pos_x[NUM_BALLS];\nint pos_y[NUM_BALLS];\nint ideal_row[NUM_BALLS];\ndouble initial_y_ratio[NUM_BALLS];\n\n// Fast Xorshift random number generator for efficient trial simulations.\nstruct FastRandom {\n    uint32_t x = 123456789, y = 362436069, z = 521288629;\n    uint32_t next() {\n        x ^= x << 16; x ^= x >> 5; x ^= x << 1;\n        uint32_t t = x; x = y; y = z; z = t ^ x ^ y;\n        return z;\n    }\n    double next_double() {\n        return (double)(next() & 0x7FFFFFFF) / 0x80000000;\n    }\n};\n\nvoid precompute_ideal_rows() {\n    for (int v = 0; v < NUM_BALLS; ++v) {\n        ideal_row[v] = (int)((sqrt(8.0 * v + 1.0) - 1.0) / 2.0);\n    }\n}\n\nint main() {\n    // Fast I/O to minimize output latency.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial pyramid and calculate initial y-ratios.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j <= i; ++j) {\n            if (!(cin >> initial_pyramid[i][j])) break;\n            int v = initial_pyramid[i][j];\n            initial_y_ratio[v] = (i == 0) ? 0.5 : (double)j / i;\n        }\n    }\n\n    precompute_ideal_rows();\n\n    auto start_time = chrono::high_resolution_clock::now();\n    FastRandom frnd;\n    vector<Move> best_moves;\n    int min_K = 10001;\n    int trials = 0;\n\n    // Run randomized simulation trials within the 2.0s time limit.\n    while (true) {\n        trials++;\n        if ((trials & 255) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1920) break;\n        }\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j <= i; ++j) {\n                pyramid[i][j] = initial_pyramid[i][j];\n                pos_x[pyramid[i][j]] = i;\n                pos_y[pyramid[i][j]] = j;\n            }\n        }\n\n        vector<Move> current_moves;\n        int current_K = 0;\n\n        bool is_bubble_up = (frnd.next() % 2 == 0);\n        double w_ideal = frnd.next_double() * 150.0;\n        double w_val = frnd.next_double() * 1.5;\n        double w_ratio = frnd.next_double() * 100.0;\n        double noise = frnd.next_double() * 50.0;\n\n        if (is_bubble_up) {\n            // Bubble-Up: Iterate 0 to 464 and move up if smaller than parents.\n            for (int v = 0; v < NUM_BALLS; ++v) {\n                while (true) {\n                    int x = pos_x[v], y = pos_y[v];\n                    if (x == 0) break;\n\n                    int p1x = x - 1, p1y = y - 1, p2x = x - 1, p2y = y;\n                    int v1 = (p1y >= 0) ? pyramid[p1x][p1y] : -1;\n                    int v2 = (p2y <= x - 1) ? pyramid[p2x][p2y] : -1;\n                    if (v1 <= v && v2 <= v) break;\n\n                    int tx, ty;\n                    if (v1 > v && v2 > v) {\n                        // Heuristic to pick the \"best\" parent to swap with.\n                        double s1 = w_ideal * (ideal_row[v1] - p1x) + w_val * v1 + frnd.next_double() * noise;\n                        s1 += w_ratio * (abs(p1y / (double)max(1, p1x) - initial_y_ratio[v1]) - abs(y / (double)max(1, x) - initial_y_ratio[v1]));\n                        double s2 = w_ideal * (ideal_row[v2] - p2x) + w_val * v2 + frnd.next_double() * noise;\n                        s2 += w_ratio * (abs(p2y / (double)max(1, p2x) - initial_y_ratio[v2]) - abs(y / (double)max(1, x) - initial_y_ratio[v2]));\n                        if (s1 > s2) { tx = p1x; ty = p1y; } else { tx = p2x; ty = p2y; }\n                    } else if (v1 > v) { tx = p1x; ty = p1y; } else { tx = p2x; ty = p2y; }\n\n                    int other_v = pyramid[tx][ty];\n                    swap(pyramid[x][y], pyramid[tx][ty]);\n                    pos_x[v] = tx; pos_y[v] = ty; pos_x[other_v] = x; pos_y[other_v] = y;\n                    current_moves.push_back({x, y, tx, ty});\n                    current_K++;\n                    if (current_K >= min_K) break;\n                }\n                if (current_K >= min_K) break;\n            }\n        } else {\n            // Sink-Down: Iterate 464 to 0 and move down if larger than children.\n            for (int v = NUM_BALLS - 1; v >= 0; --v) {\n                while (true) {\n                    int x = pos_x[v], y = pos_y[v];\n                    if (x == N - 1) break;\n\n                    int c1x = x + 1, c1y = y, c2x = x + 1, c2y = y + 1;\n                    int v1 = (c1y <= c1x) ? pyramid[c1x][c1y] : -1;\n                    int v2 = (c2y <= c2x) ? pyramid[c2x][c2y] : -1;\n                    if ((v1 == -1 || v1 >= v) && (v2 == -1 || v2 >= v)) break;\n\n                    int tx, ty;\n                    if (v1 != -1 && v1 < v && v2 != -1 && v2 < v) {\n                        double s1 = w_ideal * (c1x - ideal_row[v1]) - w_val * v1 + frnd.next_double() * noise;\n                        s1 += w_ratio * (abs(c1y / (double)max(1, c1x) - initial_y_ratio[v1]) - abs(y / (double)max(1, x) - initial_y_ratio[v1]));\n                        double s2 = w_ideal * (c2x - ideal_row[v2]) - w_val * v2 + frnd.next_double() * noise;\n                        s2 += w_ratio * (abs(c2y / (double)max(1, c2x) - initial_y_ratio[v2]) - abs(y / (double)max(1, x) - initial_y_ratio[v2]));\n                        if (s1 > s2) { tx = c1x; ty = c1y; } else { tx = c2x; ty = c2y; }\n                    } else if (v1 != -1 && v1 < v) { tx = c1x; ty = c1y; } else { tx = c2x; ty = c2y; }\n\n                    int other_v = pyramid[tx][ty];\n                    swap(pyramid[x][y], pyramid[tx][ty]);\n                    pos_x[v] = tx; pos_y[v] = ty; pos_x[other_v] = x; pos_y[other_v] = y;\n                    current_moves.push_back({x, y, tx, ty});\n                    current_K++;\n                    if (current_K >= min_K) break;\n                }\n                if (current_K >= min_K) break;\n            }\n        }\n\n        if (current_K < min_K) {\n            min_K = current_K;\n            best_moves = current_moves;\n        }\n    }\n\n    cout << best_moves.size() << \"\\n\";\n    for (const auto& m : best_moves) {\n        cout << m.x1 << \" \" << m.y1 << \" \" << m.x2 << \" \" << m.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// Warehouse dimensions and constants\nconst int D = 9;\nconst int ENTRANCE_I = 0;\nconst int ENTRANCE_J = 4; // Center of the northernmost row\n\n// Represents a square in the DxD warehouse grid\nstruct Square {\n    int i, j;\n    bool operator<(const Square& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Square& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint V[D][D];         // Storage/Removal priority rank (higher = deeper, remove later)\nbool obstacle[D][D]; // Grid status: true if square is an obstacle\nint grid[D][D];      // Current grid state: -3=entrance, -2=obstacle, -1=empty, >=0=container ID\n\n/**\n * Precalculates the ideal removal order (V ranks) for each storage square.\n * This simulation identifies squares that can be removed as \"leaves\" (not blocking others)\n * and assigns them higher ranks based on their distance from the entrance.\n */\nvoid precalculate_V(int M) {\n    int dist_bfs[D][D];\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) dist_bfs[i][j] = -1;\n\n    // Initial BFS to calculate minimal distance from the entrance for all squares\n    queue<Square> q;\n    q.push({ENTRANCE_I, ENTRANCE_J});\n    dist_bfs[ENTRANCE_I][ENTRANCE_J] = 0;\n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n    while (!q.empty()) {\n        Square curr = q.front(); q.pop();\n        for (int k = 0; k < 4; ++k) {\n            int ni = curr.i + di[k], nj = curr.j + dj[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && dist_bfs[ni][nj] == -1) {\n                dist_bfs[ni][nj] = dist_bfs[curr.i][curr.j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Determine the ideal sequence of retrieval using a greedy approach\n    set<Square> E_v;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j)\n            if (!obstacle[i][j] && !(i == ENTRANCE_I && j == ENTRANCE_J)) E_v.insert({i, j});\n\n    // We simulate retrieval in reverse order (M-1 down to 0) to assign ranks\n    for (int k = M - 1; k >= 0; --k) {\n        Square best_s = {-1, -1};\n        int max_score = -1;\n        for (auto const& s : E_v) {\n            // Check connectivity: removing square 's' shouldn't isolate any other empty square\n            int count = 0;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int ni = curr.i + di[d], nj = curr.j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && !obstacle[ni][nj] && \n                        E_v.count({ni, nj}) && !visited[ni][nj] && !(ni == s.i && nj == s.j)) {\n                        visited[ni][nj] = true;\n                        q_safe.push({ni, nj});\n                        count++;\n                    }\n                }\n            }\n            if (count == (int)E_v.size() - 1) {\n                // Tie-breaker prioritizing deeper/further squares for higher ranks\n                int score = dist_bfs[s.i][s.j] * 1000 + abs(s.j - ENTRANCE_J) * 10 + s.i;\n                if (score > max_score) { max_score = score; best_s = s; }\n            }\n        }\n        if (best_s.i != -1) {\n            V[best_s.i][best_s.j] = k;\n            E_v.erase(best_s);\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    for (int i = 0; i < D; ++i)\n        for (int j = 0; j < D; ++j) obstacle[i][j] = false;\n    for (int i = 0; i < N; ++i) {\n        int r, c; cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n\n    int M = D * D - 1 - N; // Total containers\n    precalculate_V(M);\n\n    vector<int> remaining_t;\n    for (int i = 0; i < M; ++i) remaining_t.push_back(i);\n\n    set<Square> E; // Set of currently empty storage squares\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == ENTRANCE_I && j == ENTRANCE_J) grid[i][j] = -3;\n            else if (obstacle[i][j]) grid[i][j] = -2;\n            else { grid[i][j] = -1; E.insert({i, j}); }\n        }\n    }\n\n    // 1. Online Storage Phase\n    for (int d = 0; d < M; ++d) {\n        int t_d; cin >> t_d;\n        int t_rank = 0;\n        for (int t : remaining_t) if (t < t_d) t_rank++;\n\n        // Find all reachable empty squares that are also \"safe\" (not blocking others)\n        vector<Square> safe_reachable;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n        for (auto const& s : E) {\n            int count = 0;\n            bool s_reachable = false;\n            vector<vector<bool>> visited(D, vector<bool>(D, false));\n            queue<Square> q_safe;\n            q_safe.push({ENTRANCE_I, ENTRANCE_J});\n            visited[ENTRANCE_I][ENTRANCE_J] = true;\n            while (!q_safe.empty()) {\n                Square curr = q_safe.front(); q_safe.pop();\n                for (int k = 0; k < 4; ++k) {\n                    int ni = curr.i + di[k], nj = curr.j + dj[k];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] != -2 && !visited[ni][nj]) {\n                        if (ni == s.i && nj == s.j) { s_reachable = true; visited[ni][nj] = true; }\n                        else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                            visited[ni][nj] = true; q_safe.push({ni, nj});\n                            if (grid[ni][nj] == -1) count++;\n                        }\n                    }\n                }\n            }\n            if (s_reachable && count == (int)E.size() - 1) safe_reachable.push_back(s);\n        }\n\n        // Match the current container's rank to the available storage square ranks\n        Square best_s = {-1, -1};\n        int min_diff = 1e9;\n        for (auto const& s : safe_reachable) {\n            int v_rank = 0;\n            for (auto const& other : E) if (V[other.i][other.j] < V[s.i][s.j]) v_rank++;\n            if (abs(v_rank - t_rank) < min_diff) { min_diff = abs(v_rank - t_rank); best_s = s; }\n            else if (abs(v_rank - t_rank) == min_diff) {\n                if (best_s.i == -1 || V[s.i][s.j] > V[best_s.i][best_s.j]) best_s = s;\n            }\n        }\n        if (best_s.i == -1) best_s = *E.begin(); // Safety fallback\n\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = t_d;\n        E.erase(best_s);\n        remaining_t.erase(find(remaining_t.begin(), remaining_t.end(), t_d));\n    }\n\n    // 2. Offline Removal Phase\n    for (int d = 0; d < M; ++d) {\n        vector<Square> reachable_containers;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<Square> q;\n        q.push({ENTRANCE_I, ENTRANCE_J});\n        visited[ENTRANCE_I][ENTRANCE_J] = true;\n        int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n\n        while (!q.empty()) {\n            Square curr = q.front(); q.pop();\n            for (int k = 0; k < 4; ++k) {\n                int ni = curr.i + di[k], nj = curr.j + dj[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] != -2) {\n                    if (grid[ni][nj] >= 0) {\n                        reachable_containers.push_back({ni, nj});\n                        visited[ni][nj] = true;\n                    } else if (grid[ni][nj] == -1 || grid[ni][nj] == -3) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        Square best_s = {-1, -1};\n        int min_t = 1e9;\n        for (auto const& s : reachable_containers) {\n            if (grid[s.i][s.j] < min_t) { min_t = grid[s.i][s.j]; best_s = s; }\n        }\n        cout << best_s.i << \" \" << best_s.j << endl;\n        grid[best_s.i][best_s.j] = -1; // Mark square as empty for future retrieval paths\n    }\n\n    return 0;\n}\n","ahc024":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Takahashi City grid size is fixed to 50x50 and number of wards is 100.\nconst int N = 50;\nconst int M = 100;\n\nint original_grid[N][N];\nint current_grid[N][N];\nint best_grid[N][N];\nint E[M + 1][M + 1];\nint ward_size[M + 1];\nbool original_adj[M + 1][M + 1];\nbool is_locked[N][N];\nint dx[] = {0, 0, 1, -1};\nint dy[] = {1, -1, 0, 0};\n\n// Static structures for BFS connectivity checks.\nint vis[N][N];\nint vis_token = 0;\npair<int, int> q_arr[N * N];\n\n/**\n * Helper to get grid color, returning 0 (outside) for out-of-bounds coordinates.\n */\ninline int get_color(int r, int c) {\n    if (r < 0 || r >= N || c < 0 || c >= N) return 0;\n    return current_grid[r][c];\n}\n\n/**\n * Checks if a ward (color c_old) remains connected if square (r, c) is removed.\n * Ensures that all same-colored neighbors of (r, c) can still reach each other.\n */\nbool check_connectivity(int r, int c, int c_old, const vector<pair<int, int>>& neighbors) {\n    if (neighbors.size() <= 1) return true;\n    vis_token++;\n    int head = 0, tail = 0;\n    q_arr[tail++] = neighbors[0];\n    vis[neighbors[0].first][neighbors[0].second] = vis_token;\n    vis[r][c] = vis_token; // Act as a wall (as square (r, c) will be changed to 0).\n\n    int found_count = 1;\n    while (head < tail) {\n        pair<int, int> curr = q_arr[head++];\n        for (int k = 0; k < 4; k++) {\n            int ni = curr.first + dx[k], nj = curr.second + dy[k];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && current_grid[ni][nj] == c_old && vis[ni][nj] != vis_token) {\n                vis[ni][nj] = vis_token;\n                q_arr[tail++] = {ni, nj};\n                for (auto& neighbor : neighbors) {\n                    if (ni == neighbor.first && nj == neighbor.second) {\n                        found_count++;\n                        break;\n                    }\n                }\n                // Stop BFS early if all target neighbor squares are reached.\n                if (found_count == (int)neighbors.size()) return true;\n            }\n        }\n    }\n    return false;\n}\n\n/**\n * Validates if square (r, c) can be changed to color 0 without violating connectivity or adjacency rules.\n */\nbool can_remove(int r, int c) {\n    int c_old = current_grid[r][c];\n    if (ward_size[c_old] <= 1) return false;\n\n    // Constraint: Color 0 must remain connected.\n    // Ensure the new 0-tile is part of a component that touches the boundary.\n    bool next_to_0 = false;\n    if (r == 0 || r == N - 1 || c == 0 || c == N - 1) next_to_0 = true;\n    else {\n        for (int k = 0; k < 4; k++) {\n            if (current_grid[r + dx[k]][c + dy[k]] == 0) {\n                next_to_0 = true;\n                break;\n            }\n        }\n    }\n    if (!next_to_0) return false;\n\n    // Check ward-ward and ward-0 adjacency constraints.\n    vector<pair<int, int>> c_old_neighbors;\n    int neighbor_wards[4];\n    int edges_to_ward[4];\n    int num_neighbor_wards = 0;\n\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c + dy[k];\n        int d = get_color(ni, nj);\n        if (d == c_old) {\n            c_old_neighbors.push_back({ni, nj});\n        } else if (d > 0) {\n            int found_idx = -1;\n            for (int j = 0; j < num_neighbor_wards; j++) {\n                if (neighbor_wards[j] == d) { found_idx = j; break; }\n            }\n            if (found_idx == -1) {\n                neighbor_wards[num_neighbor_wards] = d;\n                edges_to_ward[num_neighbor_wards] = 1;\n                num_neighbor_wards++;\n            } else {\n                edges_to_ward[found_idx]++;\n            }\n        }\n    }\n\n    // Ensure ward-ward adjacencies are not lost.\n    for (int j = 0; j < num_neighbor_wards; j++) {\n        if (E[c_old][neighbor_wards[j]] - edges_to_ward[j] <= 0) return false;\n    }\n\n    // Ensure ward c_old remains connected.\n    return check_connectivity(r, c, c_old, c_old_neighbors);\n}\n\n/**\n * Updates the current grid and global adjacency tallies.\n */\nvoid remove_and_update(int r, int c) {\n    int c_old = current_grid[r][c];\n    for (int k = 0; k < 4; k++) {\n        int ni = r + dx[k], nj = c + dy[k];\n        int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : current_grid[ni][nj];\n        E[c_old][d]--;\n        E[d][c_old]--;\n        E[0][d]++;\n        E[d][0]++;\n    }\n    current_grid[r][c] = 0;\n    ward_size[c_old]--;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> original_grid[i][j];\n\n    // Calculate original ward-to-ward adjacencies.\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 + dx[k], nj = j + dy[k];\n                int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : original_grid[ni][nj];\n                original_adj[c][d] = true;\n                original_adj[d][c] = true;\n            }\n        }\n    }\n\n    // Identify squares that can never be turned into 0 due to adjacency constraints.\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int c = original_grid[i][j];\n            is_locked[i][j] = false;\n            // A square is locked if its ward or any neighbor ward was not originally adjacent to 0.\n            if (!original_adj[c][0]) is_locked[i][j] = true;\n            else {\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dx[k], nj = j + dy[k];\n                    int d = (ni < 0 || ni >= N || nj < 0 || nj >= N) ? 0 : original_grid[ni][nj];\n                    if (d > 0 && d != c && !original_adj[d][0]) {\n                        is_locked[i][j] = true;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> candidate_coords;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!is_locked[i][j]) candidate_coords.push_back({i, j});\n        }\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(1337);\n    int best_E_count = -1;\n\n    // Restart the greedy search from the original grid within the time limit.\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        // Initialize current state.\n        for (int i = 0; i <= M; i++) {\n            ward_size[i] = 0;\n            for (int j = 0; j <= M; j++) E[i][j] = 0;\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                current_grid[i][j] = original_grid[i][j];\n                ward_size[current_grid[i][j]]++;\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int k = 0; k < 4; k++) {\n                    int d = get_color(i + dx[k], j + dy[k]);\n                    E[current_grid[i][j]][d]++;\n                }\n            }\n        }\n\n        // Apply greedy removals until a local optimum is reached.\n        while (true) {\n            shuffle(candidate_coords.begin(), candidate_coords.end(), rng);\n            bool changed_any = false;\n            for (auto& p : candidate_coords) {\n                if (current_grid[p.first][p.second] != 0 && can_remove(p.first, p.second)) {\n                    remove_and_update(p.first, p.second);\n                    changed_any = true;\n                }\n            }\n            if (!changed_any) break;\n        }\n\n        int current_E_count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) if (current_grid[i][j] == 0) current_E_count++;\n        }\n\n        if (current_E_count > best_E_count) {\n            best_E_count = current_E_count;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) best_grid[i][j] = current_grid[i][j];\n        }\n    }\n\n    // Output the grid with the maximum number of 0 squares.\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_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 <numeric>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Heuristic approach for Weight Partitioning with unknown weights:\n * \n * 1. Initial Sorting: Uses a MergeSort-based approach to establish a relative order \n *    of item weights using a portion of the query budget.\n * 2. Initial Weight Estimation: Initializes weights based on the expected values \n *    of order statistics for an exponential distribution (harmonic mean sequence).\n * 3. Feedback Loop: \n *    a. Generates a balanced partition using current estimates via local Hill Climbing.\n *    b. Compares two sets that are estimated to have close total weights.\n *    c. Refines weight estimates using an iterative relaxation method that satisfies \n *       set-sum constraints multiplicatively.\n *    d. Applies Isotonic Regression (Pool Adjacent Violators Algorithm) to ensure \n *       estimates remain consistent with the item-level sorting.\n * 4. Final Optimization: Performs a large-scale Hill Climbing search using the \n *    final refined weight estimates to produce the output partition.\n */\n\nint N, D, Q;\nint q_count = 0;\n\nstruct Constraint {\n    vector<int> L, R;\n    int res; // 1: L > R, -1: L < R, 0: L == R\n};\n\nvector<Constraint> all_constraints;\nvector<int> sorted_items;\n\n// Function to perform a balance query\nchar query(const vector<int>& L, const vector<int>& R) {\n    if (q_count >= Q) return '=';\n    q_count++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res;\n    if (!(cin >> res)) exit(0);\n    return res;\n}\n\n// Pool Adjacent Violators Algorithm (Isotonic Regression)\n// Ensures estimated weights w[sorted_items[i]] follow the monotonic order.\nvoid isotonic_regression(vector<double>& w) {\n    struct Block { double sum; int count; };\n    vector<Block> blocks;\n    blocks.reserve(N);\n    for (int i = 0; i < N; ++i) {\n        blocks.push_back({w[sorted_items[i]], 1});\n        while (blocks.size() >= 2) {\n            auto& b_last = blocks.back();\n            auto& b_prev = blocks[blocks.size() - 2];\n            if (b_prev.sum / b_prev.count > b_last.sum / b_last.count) {\n                b_prev.sum += b_last.sum;\n                b_prev.count += b_last.count;\n                blocks.pop_back();\n            } else break;\n        }\n    }\n    int idx = 0;\n    for (const auto& b : blocks) {\n        double avg = b.sum / b.count;\n        for (int i = 0; i < b.count; ++i) w[sorted_items[idx++]] = avg;\n    }\n}\n\n// Relaxation-based weight adjustment loop\nvoid adjust_weights(vector<double>& w, int iters, chrono::steady_clock::time_point deadline) {\n    for (int it = 0; it < iters; ++it) {\n        if ((it & 7) == 0 && chrono::steady_clock::now() > deadline) break;\n        bool changed = false;\n        for (const auto& c : all_constraints) {\n            double sL = 0, sR = 0;\n            for (int x : c.L) sL += w[x];\n            for (int x : c.R) sR += w[x];\n\n            // Adjust weights multiplicatively if the current estimates contradict balance feedback\n            if (c.res == 1 && sL <= sR) {\n                double m = sqrt((sR + 1.0) / (sL + 1.0)) * 1.01;\n                for (int x : c.L) w[x] *= m;\n                for (int x : c.R) w[x] /= m;\n                changed = true;\n            } else if (c.res == -1 && sL >= sR) {\n                double m = sqrt((sL + 1.0) / (sR + 1.0)) * 1.01;\n                for (int x : c.R) w[x] *= m;\n                for (int x : c.L) w[x] /= m;\n                changed = true;\n            }\n        }\n        if (!changed && it > 5) break;\n        isotonic_regression(w);\n    }\n    // Normalize weights to keep mean stable\n    double sum_w = accumulate(w.begin(), w.end(), 0.0);\n    double scale = (100000.0 * N) / (sum_w + 1e-9);\n    for (double& val : w) val *= scale;\n    isotonic_regression(w);\n}\n\n// Hill Climbing algorithm for multi-way number partitioning\nvoid optimize_partition(vector<vector<int>>& sets, vector<double>& set_sums, const vector<double>& w, int iters, chrono::steady_clock::time_point deadline) {\n    double total_w = accumulate(w.begin(), w.end(), 0.0);\n    double target = total_w / D;\n    mt19937 rng(42);\n\n    for (int i = 0; i < iters; ++i) {\n        if ((i & 1023) == 0 && chrono::steady_clock::now() > deadline) break;\n        int a = rng() % D;\n        int b = (a + 1 + rng() % (D - 1)) % D;\n\n        double current_error = pow(set_sums[a] - target, 2) + pow(set_sums[b] - target, 2);\n\n        // Greedy local move\n        if (!sets[a].empty()) {\n            int ia = rng() % sets[a].size();\n            int item = sets[a][ia];\n            double ns_a = set_sums[a] - w[item];\n            double ns_b = set_sums[b] + w[item];\n            if (pow(ns_a - target, 2) + pow(ns_b - target, 2) < current_error) {\n                set_sums[a] = ns_a; set_sums[b] = ns_b;\n                sets[b].push_back(item);\n                sets[a][ia] = sets[a].back(); sets[a].pop_back();\n                current_error = pow(ns_a - target, 2) + pow(ns_b - target, 2);\n            }\n        }\n        // Greedy local swap\n        if (!sets[a].empty() && !sets[b].empty()) {\n            int ia = rng() % sets[a].size(), ib = rng() % sets[b].size();\n            int item_a = sets[a][ia], item_b = sets[b][ib];\n            double ns_a = set_sums[a] - w[item_a] + w[item_b], ns_b = set_sums[b] - w[item_b] + w[item_a];\n            if (pow(ns_a - target, 2) + pow(ns_b - target, 2) < current_error) {\n                set_sums[a] = ns_a; set_sums[b] = ns_b;\n                swap(sets[a][ia], sets[b][ib]);\n            }\n        }\n    }\n}\n\n// Sorting phase using MergeSort with query limits\nvoid merge_parts(vector<int>& arr, int l, int m, int r, int Q_limit) {\n    if (q_count >= Q_limit) return;\n    vector<int> L_seg(arr.begin() + l, arr.begin() + m), R_seg(arr.begin() + m, arr.begin() + r);\n    int i = 0, j = 0, k = l;\n    while (i < (int)L_seg.size() && j < (int)R_seg.size()) {\n        if (q_count < Q_limit) {\n            char res = query({L_seg[i]}, {R_seg[j]});\n            if (res == '<') arr[k++] = L_seg[i++];\n            else arr[k++] = R_seg[j++];\n        } else arr[k++] = L_seg[i++];\n    }\n    while (i < (int)L_seg.size()) arr[k++] = L_seg[i++];\n    while (j < (int)R_seg.size()) arr[k++] = R_seg[j++];\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r, int Q_limit) {\n    if (r - l <= 1 || q_count >= Q_limit) return;\n    int m = l + (r - l) / 2;\n    merge_sort(arr, l, m, Q_limit);\n    merge_sort(arr, m, r, Q_limit);\n    merge_parts(arr, l, m, r, Q_limit);\n}\n\nint main() {\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n\n    if (!(cin >> N >> D >> Q)) return 0;\n    sorted_items.resize(N);\n    iota(sorted_items.begin(), sorted_items.end(), 0);\n\n    // Initial item-sorting\n    int Q_sort_limit = min(Q - D - 10, (int)(N * log2(N) + N));\n    merge_sort(sorted_items, 0, N, max(0, Q_sort_limit));\n\n    // Initialize weight estimates based on harmonic sequence\n    vector<double> hat_w(N);\n    double h_sum = 0;\n    for (int i = 0; i < N; ++i) {\n        h_sum += 1.0 / (N - i);\n        hat_w[sorted_items[i]] = 100000.0 * h_sum;\n    }\n\n    auto loop_limit = start_time + chrono::milliseconds(1700);\n    mt19937 rng(456);\n\n    // Iterative refinement with set comparisons\n    while (q_count < Q) {\n        if (chrono::steady_clock::now() > loop_limit) {\n            query({sorted_items[0]}, {sorted_items[N-1]});\n            continue;\n        }\n\n        vector<vector<int>> sets(D);\n        vector<double> set_sums(D, 0);\n        vector<int> rev_order = sorted_items;\n        reverse(rev_order.begin(), rev_order.end());\n        for (int x : rev_order) {\n            int b = 0;\n            for (int j = 1; j < D; j++) if (set_sums[j] < set_sums[b]) b = j;\n            sets[b].push_back(x);\n            set_sums[b] += hat_w[x];\n        }\n        optimize_partition(sets, set_sums, hat_w, 1500, loop_limit);\n\n        vector<int> s_idx(D); iota(s_idx.begin(), s_idx.end(), 0);\n        sort(s_idx.begin(), s_idx.end(), [&](int i, int j) { return set_sums[i] < set_sums[j]; });\n\n        int p_idx = 0;\n        if (rng() % 10 < 8) {\n            double min_diff = 1e18;\n            for (int i = 0; i < D - 1; i++) {\n                if (set_sums[s_idx[i+1]] - set_sums[s_idx[i]] < min_diff) {\n                    min_diff = set_sums[s_idx[i+1]] - set_sums[s_idx[i]];\n                    p_idx = i;\n                }\n            }\n        } else p_idx = rng() % (D - 1);\n\n        int a = s_idx[p_idx], b = s_idx[p_idx + 1];\n\n        if (sets[a].empty() || sets[b].empty()) {\n            query({sorted_items[0]}, {sorted_items[N-1]});\n        } else {\n            char r_char = query(sets[a], sets[b]);\n            int res = (r_char == '>' ? 1 : (r_char == '<' ? -1 : 0));\n            all_constraints.push_back({sets[a], sets[b], res});\n            if (all_constraints.size() > 500) all_constraints.erase(all_constraints.begin());\n            adjust_weights(hat_w, 10, loop_limit);\n        }\n    }\n\n    // Final partition search\n    adjust_weights(hat_w, 500, start_time + chrono::milliseconds(1850));\n    vector<vector<int>> final_sets(D);\n    vector<double> final_sums(D, 0);\n    vector<int> rev_order = sorted_items; reverse(rev_order.begin(), rev_order.end());\n    for (int x : rev_order) {\n        int b = 0;\n        for (int j = 1; j < D; j++) if (final_sums[j] < final_sums[b]) b = j;\n        final_sets[b].push_back(x);\n        final_sums[b] += hat_w[x];\n    }\n    optimize_partition(final_sets, final_sums, hat_w, 3000000, start_time + chrono::milliseconds(1980));\n\n    vector<int> ans(N);\n    for (int i = 0; i < D; i++) for (int x : final_sets[i]) ans[x] = i;\n    for (int i = 0; i < N; i++) cout << ans[i] << (i == N - 1 ? \"\" : \" \");\n    cout << endl;\n\n    return 0;\n}\n","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We have n=200 cardboard boxes in m=10 vertical stacks. We must carry them out in \n * order 1 to n. Moving a block of k boxes from one stack to another costs k+1 energy.\n * Carrying out the current smallest box from the top of its stack costs 0 energy.\n * Goal: Minimize the total energy expended within 5000 operations and 2.0s time limit.\n *\n * Strategy:\n * 1. Greedy Simulation: Simulates the entire carry-out process for boxes 1..n.\n * 2. Sub-block Splitting: To access the target box v, the boxes stacked on top of it \n *    are moved in descending \"well-ordered\" sub-blocks. This creates sequences that \n *    can potentially be carried out later without being moved again.\n * 3. Detailed Heuristic Scoring: Evaluates all destination stacks for a sub-block based on\n *    tightness of fit, future retrieval cost (burial penalty), urgency of buried \n *    boxes (lookahead), and stack balance.\n * 4. Optimization: Uses a two-phase optimization: \n *    - Phase 1: Random parameter sampling to find several good regions in the parameter space.\n *    - Phase 2: Hill Climbing on the best parameters found to refine the result.\n */\n\n// Move represents an Operation 1 (v, i > 0) or an Operation 2 (v, 0).\nstruct Move {\n    int v, i;\n};\n\n// Simulation state stores current stack configurations and tracks energy consumption.\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<int> box_to_stack;\n    vector<Move> moves;\n    long long energy;\n\n    State(int n, int m, const vector<vector<int>>& initial_stacks) \n        : n(n), m(m), stacks(initial_stacks), energy(0) {\n        box_to_stack.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            for (int val : stacks[i]) {\n                box_to_stack[val] = i;\n            }\n        }\n    }\n\n    // Executes Operation 1: moves box v and everything stacked above it to another stack.\n    void move_block(int v, int dest_idx) {\n        int src_idx = box_to_stack[v];\n        if (src_idx == dest_idx) return;\n        auto& src = stacks[src_idx];\n        auto& dst = stacks[dest_idx];\n        int pos = -1;\n        for (int i = (int)src.size() - 1; i >= 0; --i) {\n            if (src[i] == v) { pos = i; break; }\n        }\n        if (pos == -1) return; // Should not happen\n        int k = (int)src.size() - pos;\n        energy += (k + 1);\n        moves.push_back({v, dest_idx + 1});\n        for (int i = pos; i < (int)src.size(); ++i) {\n            box_to_stack[src[i]] = dest_idx;\n            dst.push_back(src[i]);\n        }\n        src.resize(pos);\n    }\n\n    // Executes Operation 2: carries out box v from the top of its stack.\n    void carry_out(int v) {\n        int s_idx = box_to_stack[v];\n        if (s_idx == -1) return; // Already carried out\n        stacks[s_idx].pop_back();\n        moves.push_back({v, 0});\n    }\n};\n\n// Hyper-parameters for the heuristic scoring function.\nstruct Params {\n    int limit, wf, ws, wu, la, tdp, tdn, pb, wes;\n};\n\n// Evaluates the heuristic fitness of a destination stack for a moving block S.\ninline long long calculate_score(int n, const vector<int>& stack_d, const vector<int>& S, int v, const Params& p) {\n    int bottom_v = S[0]; \n    int S_size = (int)S.size();\n    long long score = 0;\n\n    if (stack_d.empty()) {\n        score = (long long)(n - bottom_v) * p.tdp + p.wes;\n    } else {\n        int top_v = stack_d.back();\n        if (top_v >= bottom_v) {\n            score = (long long)(top_v - bottom_v) * p.tdp;\n        } else {\n            score = (long long)p.pb + (long long)(bottom_v - top_v) * p.tdn;\n        }\n\n        int height = (int)stack_d.size();\n        for (int j = 0; j < height; ++j) {\n            int x = stack_d[j];\n            if (x < bottom_v) {\n                int dist = x - v;\n                if (dist <= 0) continue;\n                int boxes_above_x = (height - 1 - j) + S_size;\n                long long cost_estimate = (long long)(boxes_above_x + 1);\n                if (dist <= p.la) {\n                    score += cost_estimate * p.wu * (p.la - dist + 1);\n                } else {\n                    score += cost_estimate * p.wf;\n                }\n            }\n        }\n    }\n    score += (long long)stack_d.size() * p.ws;\n    if (stack_d.size() > 25) {\n        score += (long long)(stack_d.size() - 25) * (stack_d.size() - 25) * p.ws;\n    }\n    return score;\n}\n\n// Runs a full simulation of carrying out all boxes for a given set of heuristic parameters.\nlong long simulate(int n, int m, const vector<vector<int>>& initial_stacks, const Params& p, vector<Move>& out_moves) {\n    State state(n, m, initial_stacks);\n    for (int v = 1; v <= n; ++v) {\n        int s_idx = state.box_to_stack[v];\n        if (s_idx == -1) continue;\n        if (state.stacks[s_idx].back() != v) {\n            auto& s = state.stacks[s_idx];\n            int pos = -1;\n            for (int i = (int)s.size() - 1; i >= 0; --i) {\n                if (s[i] == v) { pos = i; break; }\n            }\n            if (pos == -1) continue;\n\n            vector<vector<int>> sub_blocks;\n            vector<int> current_S = {s[pos + 1]};\n            for (int i = pos + 2; i < (int)s.size(); ++i) {\n                if (s[i-1] < s[i] || s[i-1] - s[i] > p.limit) {\n                    sub_blocks.push_back(current_S);\n                    current_S = {s[i]};\n                } else {\n                    current_S.push_back(s[i]);\n                }\n            }\n            sub_blocks.push_back(current_S);\n\n            for (int i = (int)sub_blocks.size() - 1; i >= 0; --i) {\n                const auto& S = sub_blocks[i];\n                int best_d = -1;\n                long long min_score = LLONG_MAX;\n                for (int d = 0; d < m; ++d) {\n                    if (d == s_idx) continue;\n                    long long score = calculate_score(n, state.stacks[d], S, v, p);\n                    if (score < min_score) {\n                        min_score = score;\n                        best_d = d;\n                    }\n                }\n                state.move_block(S[0], best_d);\n            }\n        }\n        state.carry_out(v);\n        if (state.moves.size() > 5000) return LLONG_MAX;\n    }\n    out_moves = state.moves;\n    return state.energy;\n}\n\nstruct Candidate {\n    long long energy;\n    Params p;\n    bool operator<(const Candidate& other) const { return energy < other.energy; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> initial_stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int b; cin >> b;\n            initial_stacks[i].push_back(b);\n        }\n    }\n\n    long long global_min_energy = LLONG_MAX;\n    vector<Move> global_best_moves;\n    mt19937 rng(424242);\n    auto start_time = chrono::steady_clock::now();\n\n    auto get_rand_params = [&]() {\n        return Params{\n            uniform_int_distribution<int>(1, 150)(rng),\n            uniform_int_distribution<int>(1, 100)(rng),\n            uniform_int_distribution<int>(1, 100)(rng),\n            uniform_int_distribution<int>(100, 5000)(rng),\n            uniform_int_distribution<int>(5, 80)(rng),\n            uniform_int_distribution<int>(0, 100)(rng),\n            uniform_int_distribution<int>(0, 100)(rng),\n            uniform_int_distribution<int>(0, 20000)(rng),\n            uniform_int_distribution<int>(-5000, 5000)(rng)\n        };\n    };\n\n    vector<Candidate> top_candidates;\n    int phase1_count = 0;\n    while (true) {\n        if ((phase1_count & 63) == 0) {\n            auto cur_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(cur_time - start_time).count() > 700) break;\n        }\n        phase1_count++;\n        Params p = get_rand_params();\n        vector<Move> cur_moves;\n        long long energy = simulate(n, m, initial_stacks, p, cur_moves);\n        if (energy != LLONG_MAX) {\n            top_candidates.push_back({energy, p});\n            if (energy < global_min_energy) {\n                global_min_energy = energy;\n                global_best_moves = cur_moves;\n            }\n        }\n    }\n\n    sort(top_candidates.begin(), top_candidates.end());\n    if (top_candidates.size() > 15) top_candidates.resize(15);\n\n    int phase2_count = 0;\n    uniform_int_distribution<int> dist_delta(-10, 10);\n    while (true) {\n        if ((phase2_count & 31) == 0) {\n            auto cur_time = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(cur_time - start_time).count() > 1900) break;\n        }\n        phase2_count++;\n        int idx = phase2_count % top_candidates.size();\n        Params p = top_candidates[idx].p;\n        int choice = uniform_int_distribution<int>(0, 8)(rng);\n        int delta = dist_delta(rng);\n        if (choice == 0) p.limit = max(1, p.limit + delta);\n        else if (choice == 1) p.wf = max(1, p.wf + delta);\n        else if (choice == 2) p.ws = max(1, p.ws + delta);\n        else if (choice == 3) p.wu = max(1, p.wu + delta * 50);\n        else if (choice == 4) p.la = max(1, p.la + delta);\n        else if (choice == 5) p.tdp = max(0, p.tdp + delta);\n        else if (choice == 6) p.tdn = max(0, p.tdn + delta);\n        else if (choice == 7) p.pb = max(0, p.pb + delta * 200);\n        else if (choice == 8) p.wes = p.wes + delta * 100;\n\n        vector<Move> cur_moves;\n        long long energy = simulate(n, m, initial_stacks, p, cur_moves);\n        if (energy != LLONG_MAX && energy < top_candidates[idx].energy) {\n            top_candidates[idx].energy = energy;\n            top_candidates[idx].p = p;\n            if (energy < global_min_energy) {\n                global_min_energy = energy;\n                global_best_moves = cur_moves;\n            }\n        }\n    }\n\n    for (const auto& move : global_best_moves) {\n        cout << move.v << \" \" << move.i << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * PROBLEM ANALYSIS & STRATEGY:\n * The goal is to minimize average dirtiness S_bar = (1/L) * sum_{t=L to 2L-1} S_t.\n * Average dirtiness for a repeated route of length L is approximately:\n * S_bar \u2248 (1/L) * sum_{i,j} d_{i,j} * sum_{m=1 to k_ij} (g_{i,j,m}^2 / 2),\n * where g_{i,j,m} are the time intervals (gaps) between successive cleanings of square (i,j).\n * \n * Our approach uses a Spanning Tree DFS tour as the base cleaning route.\n * In a DFS tour on a spanning tree, each edge is traversed twice, so the route length L = 2*(N^2 - 1).\n * The gaps g_{i,j,m} for a square u are determined by the sizes of the connected components\n * formed by removing node u from the tree.\n * \n * We optimize the spanning tree using Simulated Annealing (SA) with an objective function\n * that estimates the average dirtiness. After SA, we perform greedy shortcutting on the \n * resulting DFS tour to further reduce the average dirtiness.\n */\n\nconst int MAXN = 45;\nconst int MAXN2 = 1605;\nint N, N2;\nint flat_d[MAXN2];\nstring h_walls[MAXN], v_walls[MAXN];\nvector<int> tree_adj[MAXN2];\nbool is_in_tree_arr[MAXN2][MAXN2];\nint parent_in_tree[MAXN2];\nint subtree_size[MAXN2];\nbool adj_matrix[MAXN2][MAXN2];\n\nstruct Edge {\n    int u, v;\n};\nvector<Edge> all_edges;\n\n/**\n * Iteratively computes subtree sizes and parent pointers for the spanning tree.\n * Iterative approach avoids stack overflow issues for deep trees.\n */\nvoid dfs_size_iterative(int start_node) {\n    static int stack_arr[MAXN2];\n    static int child_idx[MAXN2];\n    int top = 0;\n    stack_arr[top++] = start_node;\n    parent_in_tree[start_node] = -1;\n    for (int i = 0; i < N2; ++i) {\n        child_idx[i] = 0;\n        subtree_size[i] = 1;\n    }\n    while (top > 0) {\n        int u = stack_arr[top - 1];\n        if (child_idx[u] < (int)tree_adj[u].size()) {\n            int v = tree_adj[u][child_idx[u]++];\n            if (v != parent_in_tree[u]) {\n                parent_in_tree[v] = u;\n                stack_arr[top++] = v;\n            }\n        } else {\n            top--;\n            if (top > 0) {\n                subtree_size[stack_arr[top - 1]] += subtree_size[u];\n            }\n        }\n    }\n}\n\n/**\n * Objective function for SA: Estimates average dirtiness for a DFS tour on the current tree.\n * Formula: S_bar \u2248 (1 / (N^2-1)) * sum_{u} (d_u * sum_{branches} size_of_branch^2).\n */\ndouble compute_tree_avg_dirtiness() {\n    double total = 0;\n    for (int u = 0; u < N2; ++u) {\n        long long sum_sq = 0;\n        for (int v : tree_adj[u]) {\n            if (v == parent_in_tree[u]) {\n                long long s = N2 - subtree_size[u];\n                sum_sq += s * s;\n            } else {\n                long long s = subtree_size[v];\n                sum_sq += s * s;\n            }\n        }\n        total += (double)flat_d[u] * (double)sum_sq;\n    }\n    return total / (double)(N2 - 1);\n}\n\n// Spanning tree modification utilities\nvoid add_tree_edge(int u, int v) {\n    tree_adj[u].push_back(v);\n    tree_adj[v].push_back(u);\n    is_in_tree_arr[u][v] = is_in_tree_arr[v][u] = true;\n}\n\nvoid remove_tree_edge(int u, int v) {\n    tree_adj[u].erase(remove(tree_adj[u].begin(), tree_adj[u].end(), v), tree_adj[u].end());\n    tree_adj[v].erase(remove(tree_adj[v].begin(), tree_adj[v].end(), u), tree_adj[v].end());\n    is_in_tree_arr[u][v] = is_in_tree_arr[v][u] = false;\n}\n\nvector<int> get_path_to_root(int u) {\n    vector<int> path;\n    while (u != -1) {\n        path.push_back(u);\n        u = parent_in_tree[u];\n    }\n    return path;\n}\n\n// Union-Find for initial spanning tree construction\nint dsu_arr[MAXN2];\nint find_dsu(int i) {\n    return dsu_arr[i] == i ? i : dsu_arr[i] = find_dsu(dsu_arr[i]);\n}\n\nvoid gen_tour_recursive(int u, int p, vector<int>& tour) {\n    tour.push_back(u);\n    for (int v : tree_adj[u]) {\n        if (v != p) {\n            gen_tour_recursive(v, u, tour);\n            tour.push_back(u);\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // 1. Read input\n    if (!(cin >> N)) return 0;\n    N2 = N * N;\n    for (int i = 0; i < N - 1; i++) cin >> h_walls[i];\n    for (int i = 0; i < N; i++) cin >> v_walls[i];\n    for (int i = 0; i < N2; i++) cin >> flat_d[i];\n\n    // Identify all valid moves (edges) in the grid\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = i * N + j;\n            if (i + 1 < N && h_walls[i][j] == '0') {\n                int v = (i + 1) * N + j;\n                all_edges.push_back({u, v});\n                adj_matrix[u][v] = adj_matrix[v][u] = true;\n            }\n            if (j + 1 < N && v_walls[i][j] == '0') {\n                int v = i * N + (j + 1);\n                all_edges.push_back({u, v});\n                adj_matrix[u][v] = adj_matrix[v][u] = true;\n            }\n        }\n    }\n\n    // 2. Initialize spanning tree\n    mt19937 rng(123);\n    vector<Edge> edges = all_edges;\n    shuffle(edges.begin(), edges.end(), rng);\n    for (int i = 0; i < N2; i++) dsu_arr[i] = i;\n    for (auto& e : edges) {\n        int r1 = find_dsu(e.u), r2 = find_dsu(e.v);\n        if (r1 != r2) {\n            dsu_arr[r1] = r2;\n            add_tree_edge(e.u, e.v);\n        }\n    }\n\n    // 3. Simulated Annealing to optimize spanning tree\n    dfs_size_iterative(0);\n    double current_avg = compute_tree_avg_dirtiness();\n    \n    double start_temp = 1e6;\n    double end_temp = 1e2;\n    auto start_time = chrono::steady_clock::now();\n    int iterations = 0;\n\n    while (true) {\n        if ((iterations & 255) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 1.85) break;\n            double progress = elapsed / 1.85;\n            double T = start_temp * pow(end_temp / start_temp, progress);\n\n            // Edge swap move: Add a non-tree edge, find the cycle, remove a tree edge from it\n            Edge e_in = all_edges[uniform_int_distribution<int>(0, (int)all_edges.size() - 1)(rng)];\n            if (is_in_tree_arr[e_in.u][e_in.v]) { iterations++; continue; }\n\n            vector<int> path_u = get_path_to_root(e_in.u);\n            vector<int> path_v = get_path_to_root(e_in.v);\n            int iu = (int)path_u.size() - 1, iv = (int)path_v.size() - 1;\n            while (iu >= 0 && iv >= 0 && path_u[iu] == path_v[iv]) { iu--; iv--; }\n            vector<Edge> cycle_edges;\n            for (int k = 0; k <= iu; k++) cycle_edges.push_back({path_u[k], path_u[k+1]});\n            for (int k = 0; k <= iv; k++) cycle_edges.push_back({path_v[k], path_v[k+1]});\n            if (cycle_edges.empty()) { iterations++; continue; }\n\n            Edge e_out = cycle_edges[uniform_int_distribution<int>(0, (int)cycle_edges.size() - 1)(rng)];\n            remove_tree_edge(e_out.u, e_out.v);\n            add_tree_edge(e_in.u, e_in.v);\n            dfs_size_iterative(0);\n            double next_avg = compute_tree_avg_dirtiness();\n\n            if (next_avg < current_avg || uniform_real_distribution<double>(0, 1)(rng) < exp((current_avg - next_avg) / T)) {\n                current_avg = next_avg;\n            } else {\n                remove_tree_edge(e_in.u, e_in.v);\n                add_tree_edge(e_out.u, e_out.v);\n                dfs_size_iterative(0);\n            }\n        }\n        iterations++;\n    }\n\n    // 4. Generate DFS tour and perform greedy shortcutting\n    vector<int> tour;\n    gen_tour_recursive(0, -1, tour);\n    int L = (int)tour.size();\n    vector<int> counts(N2, 0);\n    for (int i = 0; i < L - 1; i++) counts[tour[i]]++;\n\n    vector<bool> removed(L, false);\n    static int counts_in_seg[MAXN2];\n    for (int i = 0; i < L - 1; i++) {\n        if (removed[i]) continue;\n        int best_j = -1;\n        for (int k = 0; k < N2; k++) counts_in_seg[k] = 0;\n        bool possible = true;\n        for (int j = i + 1; j < L; j++) {\n            if (removed[j]) continue;\n            // A shortcut from tour[i] to tour[j] is valid if they are adjacent and \n            // no square is completely skipped by the shortcut.\n            if (j > i + 1 && adj_matrix[tour[i]][tour[j]] && possible) {\n                best_j = j;\n            }\n            int u = tour[j];\n            counts_in_seg[u]++;\n            if (counts_in_seg[u] == counts[u]) possible = false;\n        }\n        if (best_j != -1) {\n            for (int k = i + 1; k < best_j; k++) {\n                if (!removed[k]) {\n                    counts[tour[k]]--;\n                    removed[k] = true;\n                }\n            }\n        }\n    }\n\n    // 5. Build final result move string\n    vector<int> final_nodes;\n    for (int i = 0; i < L; i++) if (!removed[i]) final_nodes.push_back(tour[i]);\n\n    string res = \"\";\n    for (size_t i = 0; i + 1 < final_nodes.size(); i++) {\n        int u = final_nodes[i], v = final_nodes[i+1];\n        if (v == u + 1) res += 'R';\n        else if (v == u - 1) res += 'L';\n        else if (v == u + N) res += 'D';\n        else if (v == u - N) res += 'U';\n    }\n    cout << res << endl;\n\n    return 0;\n}\n","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\n\n// Movement cost: Manhattan distance between finger positions p1 and p2, plus 1 for the typing itself.\ninline int get_dist(int p1, int p2) {\n    return abs(p1 / N - p2 / N) + abs(p1 % N - p2 % N) + 1;\n}\n\n// Calculate the maximum prefix-suffix overlap between two lucky strings.\n// Since all words are length 5, overlap can be 0 to 4 characters.\nint get_overlap(const string& a, const string& b) {\n    for (int o = 4; o >= 1; --o) {\n        bool match = true;\n        for (int k = 0; k < o; ++k) {\n            if (a[5 - o + k] != b[k]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return o;\n    }\n    return 0;\n}\n\n// Global data tables\nint min_suffix_cost[M][6][N * N];\nint dist_matrix[M][M];\nint d_start[M];\nint overlap_table[M][M];\nvector<int> pos_of_char[26];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read initial grid dimensions, finger starting location, keyboard, and lucky words.\n    int n_in, m_in, si, sj;\n    if (!(cin >> n_in >> m_in)) return 0;\n    cin >> si >> sj;\n\n    vector<string> keyboard(N);\n    for (int i = 0; i < N; ++i) cin >> keyboard[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // Store every grid coordinate for each character A-Z.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            pos_of_char[keyboard[i][j] - 'A'].push_back(i * N + j);\n        }\n    }\n\n    // Precompute the minimum cost to type any suffix (of length 1 to 5) of each lucky word,\n    // given the finger is starting at any grid position.\n    for (int w = 0; w < M; ++w) {\n        for (int p = 0; p < N * N; ++p) min_suffix_cost[w][0][p] = 0;\n        for (int len = 1; len <= 5; ++len) {\n            int char_idx = words[w][5 - len] - 'A';\n            for (int ps = 0; ps < N * N; ++ps) {\n                int best = 1e9;\n                for (int pc : pos_of_char[char_idx]) {\n                    int c = get_dist(ps, pc) + min_suffix_cost[w][len - 1][pc];\n                    if (c < best) best = c;\n                }\n                min_suffix_cost[w][len][ps] = best;\n            }\n        }\n    }\n\n    // Build the overlap table for all pairs of lucky words.\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < M; ++j) {\n            overlap_table[i][j] = get_overlap(words[i], words[j]);\n        }\n    }\n\n    // Build a distance matrix for the word-order optimization (TSP).\n    // dist_matrix[i][j] is the cost to type word j given we just typed word i.\n    for (int i = 0; i < M; ++i) {\n        int last_char_i = words[i][4] - 'A';\n        for (int j = 0; j < M; ++j) {\n            int overlap = overlap_table[i][j];\n            int suffix_len = 5 - overlap;\n            int min_v = 1e9;\n            for (int p_last : pos_of_char[last_char_i]) {\n                if (min_suffix_cost[j][suffix_len][p_last] < min_v)\n                    min_v = min_suffix_cost[j][suffix_len][p_last];\n            }\n            // Use a large weight for suffix_len to prioritize maximizing string overlaps.\n            dist_matrix[i][j] = suffix_len * 1000 + min_v;\n        }\n        // Distance to type the very first word from the finger's starting position.\n        d_start[i] = min_suffix_cost[i][5][si * N + sj];\n    }\n\n    // Generate an initial path using multi-start greedy search.\n    vector<int> best_p;\n    long long best_total_cost = 2e18;\n    for (int s = 0; s < M; ++s) {\n        vector<int> cur_p; cur_p.push_back(s);\n        vector<bool> used(M, false); used[s] = true;\n        long long cur_c = d_start[s];\n        for (int i = 1; i < M; ++i) {\n            int last = cur_p.back(), next_v = -1; int min_d = 2e9;\n            for (int v = 0; v < M; ++v) {\n                if (!used[v] && dist_matrix[last][v] < min_d) {\n                    min_d = dist_matrix[last][v]; next_v = v;\n                }\n            }\n            cur_p.push_back(next_v); used[next_v] = true; cur_c += min_d;\n        }\n        if (cur_c < best_total_cost) { best_total_cost = cur_c; best_p = cur_p; }\n    }\n\n    // Refine the word sequence using Simulated Annealing (SA) with 2-opt, Swap, and Shift moves.\n    auto start_time = chrono::steady_clock::now();\n    mt19937 rng(12345);\n    vector<int> p = best_p;\n    long long current_cost = best_total_cost;\n    double T_start = 100.0, T_end = 0.1, temp = T_start;\n\n    for (int iter = 0; ; ++iter) {\n        if ((iter & 511) == 0) {\n            auto now = chrono::steady_clock::now();\n            long long ms = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (ms > 1925) break;\n            temp = T_start * pow(T_end / T_start, (double)ms / 1925.0);\n        }\n\n        int move_type = uniform_int_distribution<int>(0, 2)(rng);\n        int i = uniform_int_distribution<int>(0, M - 1)(rng);\n        int j = uniform_int_distribution<int>(0, M - 1)(rng);\n        if (i == j) continue;\n\n        if (move_type == 0) { // Move 1: 2-opt\n            if (i > j) swap(i, j);\n            long long next_cost = current_cost;\n            if (i == 0) {\n                next_cost -= d_start[p[0]]; next_cost += d_start[p[j]];\n            } else {\n                next_cost -= dist_matrix[p[i - 1]][p[i]]; next_cost += dist_matrix[p[i - 1]][p[j]];\n            }\n            if (j < M - 1) {\n                next_cost -= dist_matrix[p[j]][p[j + 1]]; next_cost += dist_matrix[p[i]][p[j + 1]];\n            }\n            for (int k = i; k < j; ++k) {\n                next_cost -= dist_matrix[p[k]][p[k + 1]]; next_cost += dist_matrix[p[k + 1]][p[k]];\n            }\n            if (next_cost < current_cost || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_cost - next_cost) / temp)) {\n                current_cost = next_cost; reverse(p.begin() + i, p.begin() + j + 1);\n            }\n        } else { // Move 2 & 3: Swap or Shift\n            vector<int> next_p = p;\n            if (move_type == 1) swap(next_p[i], next_p[j]);\n            else { int val = next_p[i]; next_p.erase(next_p.begin() + i); next_p.insert(next_p.begin() + j, val); }\n            long long next_cost = d_start[next_p[0]];\n            for (int k = 0; k < M - 1; ++k) next_cost += dist_matrix[next_p[k]][next_p[k + 1]];\n            if (next_cost < current_cost || uniform_real_distribution<double>(0, 1)(rng) < exp((double)(current_cost - next_cost) / temp)) {\n                current_cost = next_cost; p = next_p;\n            }\n        }\n        if (current_cost < best_total_cost) { best_total_cost = current_cost; best_p = p; }\n    }\n\n    // Build the superstring containing all lucky words using the optimized order.\n    string S = words[best_p[0]];\n    for (int i = 1; i < M; ++i) {\n        S += words[best_p[i]].substr(overlap_table[best_p[i - 1]][best_p[i]]);\n    }\n\n    // Use Dynamic Programming (DP) to determine the exact grid coordinates for each character\n    // in the superstring to minimize total Manhattan movement cost.\n    int L_str = S.size();\n    vector<vector<int>> dp_v(L_str), dp_p(L_str), cand(L_str);\n    for (int k = 0; k < L_str; ++k) {\n        cand[k] = pos_of_char[S[k] - 'A'];\n        dp_v[k].assign(cand[k].size(), 1e9); dp_p[k].assign(cand[k].size(), -1);\n    }\n    for (int i = 0; i < (int)cand[0].size(); ++i)\n        dp_v[0][i] = get_dist(si * N + sj, cand[0][i]);\n\n    for (int k = 1; k < L_str; ++k) {\n        for (int i = 0; i < (int)cand[k].size(); ++i) {\n            int cp = cand[k][i];\n            for (int j = 0; j < (int)cand[k - 1].size(); ++j) {\n                int c = dp_v[k - 1][j] + get_dist(cand[k - 1][j], cp);\n                if (c < dp_v[k][i]) { dp_v[k][i] = c; dp_p[k][i] = j; }\n            }\n        }\n    }\n\n    // Find the best ending coordinate and backtrack to get the full coordinate sequence.\n    int bi = 0, mv = 2e9;\n    for (int i = 0; i < (int)cand[L_str - 1].size(); ++i)\n        if (dp_v[L_str - 1][i] < mv) { mv = dp_v[L_str - 1][i]; bi = i; }\n\n    vector<int> res(L_str);\n    for (int k = L_str - 1; k >= 0; --k) { res[k] = cand[k][bi]; bi = dp_p[k][bi]; }\n\n    // Output the resulting finger movements.\n    for (int ps : res) cout << ps / N << \" \" << ps % N << \"\\n\";\n\n    return 0;\n}\n","ahc030":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Constants for normal distribution calculations\n#ifndef M_SQRT1_2\n#define M_SQRT1_2 0.70710678118654752440\n#endif\n\nconst int MAX_CELLS = 405;\nconst int MAX_DIVINE = 105;\nconst int MAX_FIELDS = 21;\nconst int MAX_POSITIONS = 405;\n\nstruct Point { int r, c; };\n\nstruct Polyomino {\n    int d;\n    vector<Point> ps;\n    vector<vector<int>> positions; // Flattened square indices\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<pair<vector<int>, int>> divine_queries;\nvector<vector<double>> log_p_table;\nvector<pair<int, int>> drills;\nint drilled_val[MAX_CELLS];\n\n// Optimized precomputed structures\nint W_pre[MAX_FIELDS][MAX_POSITIONS][MAX_DIVINE];\nchar is_covered_pre[MAX_FIELDS][MAX_POSITIONS][MAX_CELLS];\n\ndouble normal_cdf(double x) {\n    return 0.5 * erfc(-x * M_SQRT1_2);\n}\n\ndouble get_prob(int k, int v_sum, int v_obs) {\n    double mu = (double)k * eps + (double)v_sum * (1.0 - 2.0 * eps);\n    double sigma = sqrt((double)k * eps * (1.0 - eps));\n    if (sigma < 1e-9) sigma = 1e-9;\n    \n    if (v_obs == 0) {\n        return max(1e-18, normal_cdf((0.5 - mu) / sigma));\n    } else {\n        double p = normal_cdf((v_obs + 0.5 - mu) / sigma) - normal_cdf((v_obs - 0.5 - mu) / sigma);\n        return max(1e-18, p);\n    }\n}\n\nvoid add_divine_query(const vector<int>& S, int obs, int table_size) {\n    divine_queries.push_back({S, obs});\n    vector<double> table(table_size);\n    for (int v = 0; v < table_size; ++v) {\n        table[v] = log(get_prob((int)S.size(), v, obs));\n    }\n    log_p_table.push_back(table);\n    \n    int q_idx = (int)divine_queries.size() - 1;\n    for (int i = 0; i < M; ++i) {\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            int count = 0;\n            for (int idx : S) if (is_covered_pre[i][p][idx]) count++;\n            W_pre[i][p][q_idx] = count;\n        }\n    }\n}\n\nstruct Config {\n    vector<int> pos_idx;\n    vector<int> v_sums;\n    vector<int> grid_v;\n\n    Config() : pos_idx(M), v_sums(), grid_v(MAX_CELLS, 0) {}\n\n    void compute_all() {\n        fill(grid_v.begin(), grid_v.end(), 0);\n        for (int i = 0; i < M; ++i) {\n            for (int idx : oil_fields[i].positions[pos_idx[i]]) grid_v[idx]++;\n        }\n        v_sums.assign(divine_queries.size(), 0);\n        for (size_t q = 0; q < divine_queries.size(); ++q) {\n            for (int k = 0; k < M; ++k) v_sums[q] += W_pre[k][pos_idx[k]][q];\n        }\n    }\n};\n\nint main() {\n    auto start_time = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n    \n    int total_max_sum = 0;\n    oil_fields.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int d; cin >> d;\n        oil_fields[i].d = d;\n        total_max_sum += d;\n        vector<Point> ps(d);\n        int mr = 0, mc = 0;\n        for (int j = 0; j < d; ++j) {\n            cin >> ps[j].r >> ps[j].c;\n            mr = max(mr, ps[j].r); mc = max(mc, ps[j].c);\n        }\n        for (int r = 0; r <= N - 1 - mr; ++r) {\n            for (int c = 0; c <= N - 1 - mc; ++c) {\n                vector<int> pos;\n                for (auto p : ps) pos.push_back((p.r + r) * N + (p.c + c));\n                oil_fields[i].positions.push_back(pos);\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) {\n        for (int p = 0; p < (int)oil_fields[i].positions.size(); ++p) {\n            for (int idx : oil_fields[i].positions[p]) is_covered_pre[i][p][idx] = 1;\n        }\n    }\n\n    for (int i = 0; i < MAX_CELLS; ++i) drilled_val[i] = -1;\n    int ops = 0;\n    mt19937 rng(42);\n\n    int num_init = 2 * N + 10;\n    int table_size = MAX_CELLS;\n    for (int i = 0; i < num_init && ops < 2 * N * N; ++i) {\n        vector<int> S;\n        double p_thr = uniform_real_distribution<double>(0.1, 0.4)(rng);\n        for (int j = 0; j < N * N; ++j) if (uniform_real_distribution<double>(0, 1)(rng) < p_thr) S.push_back(j);\n        if (S.size() < 2) { S.clear(); S.push_back(0); S.push_back(1); }\n        cout << \"q \" << S.size();\n        for (int idx : S) cout << \" \" << idx / N << \" \" << idx % N;\n        cout << endl; ops++;\n        int resp; if (!(cin >> resp)) return 0;\n        add_divine_query(S, resp, table_size);\n    }\n\n    const int n_s = 40;\n    vector<Config> samples(n_s);\n    for (int i = 0; i < n_s; ++i) {\n        for (int j = 0; j < M; ++j) samples[i].pos_idx[j] = uniform_int_distribution<int>(0, (int)oil_fields[j].positions.size() - 1)(rng);\n        samples[i].compute_all();\n    }\n\n    while (ops < 2 * N * N) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.8) break;\n\n        int steps = (ops <= num_init + 1) ? 1000 : 250;\n        for (int i = 0; i < n_s; ++i) {\n            for (int s = 0; s < steps; ++s) {\n                int m = uniform_int_distribution<int>(0, M - 1)(rng);\n                int op = samples[i].pos_idx[m];\n                int np = uniform_int_distribution<int>(0, (int)oil_fields[m].positions.size() - 1)(rng);\n                if (op == np) continue;\n\n                double delta = 0;\n                for (size_t q = 0; q < divine_queries.size(); ++q) {\n                    const double* table = log_p_table[q].data();\n                    delta += table[samples[i].v_sums[q] + W_pre[m][np][q] - W_pre[m][op][q]] - table[samples[i].v_sums[q]];\n                }\n                for (int idx : oil_fields[m].positions[op]) {\n                    if (drilled_val[idx] != -1 && !is_covered_pre[m][np][idx]) {\n                        int cur = samples[i].grid_v[idx];\n                        if (cur != drilled_val[idx]) delta += 1e6;\n                        if (cur - 1 != drilled_val[idx]) delta -= 1e6;\n                    }\n                }\n                for (int idx : oil_fields[m].positions[np]) {\n                    if (drilled_val[idx] != -1 && !is_covered_pre[m][op][idx]) {\n                        int cur = samples[i].grid_v[idx];\n                        if (cur != drilled_val[idx]) delta += 1e6;\n                        if (cur + 1 != drilled_val[idx]) delta -= 1e6;\n                    }\n                }\n\n                if (delta >= 0 || (delta > -30.0 && uniform_real_distribution<double>(0, 1)(rng) < exp(delta))) {\n                    for (int idx : oil_fields[m].positions[op]) samples[i].grid_v[idx]--;\n                    for (int idx : oil_fields[m].positions[np]) samples[i].grid_v[idx]++;\n                    for (size_t q = 0; q < divine_queries.size(); ++q) {\n                        samples[i].v_sums[q] += W_pre[m][np][q] - W_pre[m][op][q];\n                    }\n                    samples[i].pos_idx[m] = np;\n                }\n            }\n        }\n\n        double po[MAX_CELLS] = {0}, pv[MAX_CELLS][35] = {0};\n        int possible_samples = 0;\n        for (int i = 0; i < n_s; ++i) {\n            bool ok = true;\n            for (const auto& d : drills) if (samples[i].grid_v[d.first] != d.second) { ok = false; break; }\n            if (ok) {\n                possible_samples++;\n                for (int j = 0; j < N * N; ++j) {\n                    if (samples[i].grid_v[j] > 0) po[j] += 1.0;\n                    if (samples[i].grid_v[j] < 35) pv[j][samples[i].grid_v[j]] += 1.0;\n                }\n            }\n        }\n\n        int denom = possible_samples > 0 ? possible_samples : n_s;\n        if (possible_samples == 0) {\n            for (int i = 0; i < n_s; ++i) {\n                for (int j = 0; j < N * N; ++j) {\n                    if (samples[i].grid_v[j] > 0) po[j] += 1.0;\n                    if (samples[i].grid_v[j] < 35) pv[j][samples[i].grid_v[j]] += 1.0;\n                }\n            }\n        }\n\n        bool cert = true;\n        for (int j = 0; j < N * N; ++j) {\n            double p = po[j] / denom;\n            if (p > 0.05 && p < 0.95) cert = false;\n        }\n\n        double max_e = -1.0; int best_i = -1;\n        for (int j = 0; j < N * N; ++j) {\n            if (drilled_val[j] == -1) {\n                double e = 0;\n                for (int v = 0; v < 35; ++v) {\n                    double p = pv[j][v] / denom;\n                    if (p > 1e-9) e -= p * log(p);\n                }\n                if (e > max_e) { max_e = e; best_i = j; }\n            }\n        }\n\n        if (cert || ops >= 2 * N * N - 1 || best_i == -1) {\n            vector<int> g;\n            for (int j = 0; j < N * N; ++j) if (drilled_val[j] != 0 && (drilled_val[j] > 0 || po[j] / denom > 0.5)) g.push_back(j);\n            cout << \"a \" << g.size();\n            for (int idx : g) cout << \" \" << idx / N << \" \" << idx % N;\n            cout << endl; ops++;\n            int resp; if (!(cin >> resp) || resp == 1) return 0;\n            // Incorrect guess, resolve uncertainty by drilling\n            if (best_i != -1 && ops < 2 * N * N) {\n                cout << \"q 1 \" << best_i / N << \" \" << best_i % N << endl; ops++;\n                if (!(cin >> resp)) return 0;\n                drilled_val[best_i] = resp; drills.push_back({best_i, resp});\n                for (int i = 0; i < n_s; ++i) samples[i].compute_all();\n            }\n        } else {\n            cout << \"q 1 \" << best_i / N << \" \" << best_i % N << endl; ops++;\n            int resp; if (!(cin >> resp)) return 0;\n            drilled_val[best_i] = resp; drills.push_back({best_i, resp});\n            for (int i = 0; i < n_s; ++i) samples[i].compute_all();\n        }\n    }\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <deque>\n#include <cstring>\n#include <chrono>\n\nusing namespace std;\n\ntypedef long long ll;\nconst ll INF = 1e16;\nint W_global = 1000;\n\n// Representation of a rented rectangular section.\nstruct Rectangle {\n    int r1, c1, r2, c2;\n};\n\n/**\n * Calculates the total actual cost for the given rectangular divisions across all days.\n * The total cost is composed of:\n * 1. Area deficit penalty: 100 * (requested_area - assigned_area) if deficit > 0.\n * 2. Partition change cost: Length of horizontal and vertical segments added or removed \n *    relative to the configuration on the previous day. $L_0=0$ is assumed.\n */\nll calculate_actual_cost(int W, int D, int N, const vector<vector<ll>>& a, const vector<vector<Rectangle>>& all_rects) {\n    ll total_penalty = 0;\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            ll area = (ll)(all_rects[d][k].r2 - all_rects[d][k].r1) * (all_rects[d][k].c2 - all_rects[d][k].c1);\n            if (a[d][k] > area) total_penalty += 100 * (a[d][k] - area);\n        }\n    }\n\n    ll total_movement = 0;\n    // Static arrays to avoid repeated large memory allocations.\n    static bool h_p[1001][1000], v_p[1000][1001], h_c[1001][1000], v_c[1000][1001];\n    for (int d = 1; d < D; ++d) {\n        for (int i = 0; i <= W; ++i) for (int j = 0; j < W; ++j) h_p[i][j] = h_c[i][j] = false;\n        for (int i = 0; i < W; ++i) for (int j = 0; j <= W; ++j) v_p[i][j] = v_c[i][j] = false;\n\n        auto fill_partition = [&](const vector<Rectangle>& rects, bool h[1001][1000], bool v[1000][1001]) {\n            for (const auto& r : rects) {\n                if (r.r1 > 0 && r.r1 < W) for (int j = r.c1; j < r.c2; ++j) h[r.r1][j] = true;\n                if (r.r2 > 0 && r.r2 < W) for (int j = r.c1; j < r.c2; ++j) h[r.r2][j] = true;\n                if (r.c1 > 0 && r.c1 < W) for (int i = r.r1; i < r.r2; ++i) v[i][r.c1] = true;\n                if (r.c2 > 0 && r.c2 < W) for (int i = r.r1; i < r.r2; ++i) v[i][r.c2] = true;\n            }\n        };\n        fill_partition(all_rects[d - 1], h_p, v_p);\n        fill_partition(all_rects[d], h_c, v_c);\n        // Compute the symmetric difference of segments to find Ld.\n        for (int i = 1; i < W; ++i) for (int j = 0; j < W; ++j) if (h_p[i][j] != h_c[i][j]) total_movement++;\n        for (int i = 0; i < W; ++i) for (int j = 1; j < W; ++j) if (v_p[i][j] != v_c[i][j]) total_movement++;\n    }\n    return total_penalty + total_movement;\n}\n\n// Estimates the expected area penalty for a strip of height h to inform height selection.\nll approx_area_penalty(const vector<ll>& strip_a, int h, int W) {\n    if (h < 1) return INF;\n    ll sum_a = 0;\n    for (ll x : strip_a) sum_a += x;\n    ll penalty = 100LL * max(0LL, sum_a - (ll)h * W);\n    ll min_w_sum = 0;\n    for (ll x : strip_a) min_w_sum += max(1LL, (x + h - 1) / h);\n    if (min_w_sum > W) penalty += 100LL * (min_w_sum - W) * h;\n    return penalty;\n}\n\nint main() {\n    auto start_time = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_in, D, N;\n    if (!(cin >> W_in >> D >> N)) return 0;\n    W_global = W_in;\n    const int W = W_global;\n    vector<vector<ll>> a(D, vector<ll>(N));\n    for (int d = 0; d < D; ++d) for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    ll best_overall_cost = -1;\n    vector<vector<Rectangle>> best_all_rects;\n\n    // Explore several strip counts R. Horizontal/Vertical strips with fixed boundaries minimize partition change costs.\n    vector<int> try_R = {1, 2, 5, 10, 20, 30, 40, 50, N};\n    sort(try_R.begin(), try_R.end());\n    try_R.erase(unique(try_R.begin(), try_R.end()), try_R.end());\n\n    for (int R : try_R) {\n        if (R > N) continue;\n        auto current_time = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2700) break;\n\n        // DP to group reservations 0..N-1 into R contiguous strips based on peak area requirement across all days.\n        vector<vector<int>> strips(R);\n        vector<vector<ll>> dp_g(R + 1, vector<ll>(N + 1, INF));\n        vector<vector<int>> parent_g(R + 1, vector<int>(N + 1, -1));\n        dp_g[0][0] = 0;\n        for (int r = 1; r <= R; ++r) {\n            for (int k = r; k <= N; ++k) {\n                for (int p = r - 1; p < k; ++p) {\n                    ll max_sum = 0;\n                    for (int d = 0; d < D; ++d) {\n                        ll s = 0;\n                        for (int i = p; i < k; ++i) s += a[d][i];\n                        max_sum = max(max_sum, s);\n                    }\n                    if (dp_g[r - 1][p] + max_sum < dp_g[r][k]) {\n                        dp_g[r][k] = dp_g[r - 1][p] + max_sum;\n                        parent_g[r][k] = p;\n                    }\n                }\n            }\n        }\n        int cur_group_k = N;\n        for (int r = R; r >= 1; --r) {\n            int p = parent_g[r][cur_group_k];\n            for (int i = p; i < cur_group_k; ++i) strips[r - 1].push_back(i);\n            cur_group_k = p;\n        }\n\n        // DP to determine fixed heights H for each strip to minimize total estimated area penalty across all days.\n        vector<vector<ll>> strip_penalty_h(R, vector<ll>(W + 1, 0));\n        for (int r = 0; r < R; ++r) {\n            vector<ll> strip_a_d(strips[r].size());\n            for (int h = 1; h <= W; ++h) {\n                ll total_p = 0;\n                for (int d = 0; d < D; ++d) {\n                    for (int i = 0; i < (int)strips[r].size(); ++i) strip_a_d[i] = a[d][strips[r][i]];\n                    total_p += approx_area_penalty(strip_a_d, h, W);\n                }\n                strip_penalty_h[r][h] = total_p;\n            }\n        }\n        vector<vector<ll>> dp_h(R + 1, vector<ll>(W + 1, INF));\n        vector<vector<int>> parent_h(R + 1, vector<int>(W + 1, -1));\n        dp_h[0][0] = 0;\n        for (int r = 1; r <= R; ++r) {\n            for (int y = r; y <= W - (R - r); ++y) {\n                for (int hc = 1; y - hc >= r - 1; ++hc) {\n                    if (dp_h[r - 1][y - hc] + strip_penalty_h[r - 1][hc] < dp_h[r][y]) {\n                        dp_h[r][y] = dp_h[r - 1][y - hc] + strip_penalty_h[r - 1][hc];\n                        parent_h[r][y] = hc;\n                    }\n                }\n            }\n        }\n        vector<int> H(R);\n        int cur_y_pos = W;\n        for (int r = R; r >= 1; --r) { H[r - 1] = parent_h[r][cur_y_pos]; cur_y_pos -= H[r - 1]; }\n        vector<int> y_coords(R + 1, 0);\n        for (int i = 0; i < R; ++i) y_coords[i + 1] = y_coords[i] + H[i];\n\n        // Evaluate both orientations of the strip model.\n        for (bool horizontal : {true, false}) {\n            vector<vector<Rectangle>> cur_rects(D, vector<Rectangle>(N));\n            for (int d = 0; d < D; ++d) {\n                for (int r = 0; r < R; ++r) {\n                    int nr = strips[r].size(), h = H[r];\n                    vector<vector<ll>> dp_v(nr + 1, vector<ll>(W + 1, INF));\n                    vector<vector<int>> p_v(nr + 1, vector<int>(W + 1, -1));\n                    dp_v[0][0] = 0;\n\n                    vector<int> overlap_at_x(W + 1, 0);\n                    if (d > 0) {\n                        for (int k_prev = 0; k_prev < N; ++k_prev) {\n                            const auto& r_prev = cur_rects[d - 1][k_prev];\n                            int x_coord = horizontal ? r_prev.c1 : r_prev.r1;\n                            if (x_coord > 0 && x_coord < W) {\n                                int py1 = horizontal ? r_prev.r1 : r_prev.c1;\n                                int py2 = horizontal ? r_prev.r2 : r_prev.c2;\n                                int inter = max(0, min(py2, y_coords[r + 1]) - max(py1, y_coords[r]));\n                                if (inter > 0) overlap_at_x[x_coord] = inter;\n                            }\n                        }\n                    }\n\n                    for (int k = 1; k <= nr; ++k) {\n                        ll a_target = a[d][strips[r][k - 1]];\n                        int req_w = (int)((a_target + h - 1) / h);\n                        deque<int> dq;\n                        ll p1_min = INF; int p1_idx = -1;\n                        for (int x = 1; x <= W; ++x) {\n                            int p1_new = x - req_w;\n                            if (p1_new >= k - 1 && p1_new < x && p1_new <= W) {\n                                if (dp_v[k - 1][p1_new] < p1_min) { p1_min = dp_v[k - 1][p1_new]; p1_idx = p1_new; }\n                            }\n                            while (!dq.empty() && dq.front() <= x - req_w) dq.pop_front();\n                            if (x - 1 >= k - 1 && dp_v[k - 1][x - 1] < INF) {\n                                ll g_val = dp_v[k - 1][x - 1] + 100LL * h * (x - 1);\n                                while (!dq.empty() && dp_v[k - 1][dq.back()] + 100LL * h * dq.back() >= g_val) dq.pop_back();\n                                dq.push_back(x - 1);\n                            }\n                            if (x < k || x > W - (nr - k)) continue;\n                            ll bc = INF; int bp = -1;\n                            if (p1_min < INF) { bc = p1_min; bp = p1_idx; }\n                            if (!dq.empty()) {\n                                int p2 = dq.front();\n                                ll v2 = dp_v[k - 1][p2] + 100LL * a_target - 100LL * h * (x - p2);\n                                if (v2 < bc) { bc = v2; bp = p2; }\n                            }\n                            if (bc < INF) {\n                                ll move_c = (d > 0 && k < nr) ? (ll)h - 2LL * overlap_at_x[x] : 0;\n                                dp_v[k][x] = bc + move_c;\n                                p_v[k][x] = bp;\n                            }\n                        }\n                    }\n                    int cur_back_x = W;\n                    for (int k = nr; k >= 1; --k) {\n                        int p = p_v[k][cur_back_x];\n                        if (horizontal) cur_rects[d][strips[r][k - 1]] = {y_coords[r], p, y_coords[r + 1], cur_back_x};\n                        else cur_rects[d][strips[r][k - 1]] = {p, y_coords[r], cur_back_x, y_coords[r + 1]};\n                        cur_back_x = p;\n                    }\n                }\n            }\n            ll score = calculate_actual_cost(W, D, N, a, cur_rects);\n            if (best_overall_cost == -1 || score < best_overall_cost) {\n                best_overall_cost = score;\n                best_all_rects = cur_rects;\n            }\n        }\n    }\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_all_rects[d][k].r1 << \" \" << best_all_rects[d][k].c1 << \" \"\n                 << best_all_rects[d][k].r2 << \" \" << best_all_rects[d][k].c2 << \"\\n\";\n        }\n    }\n    return 0;\n}\n","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <stdint.h>\n#include <string.h>\n\nusing namespace std;\n\n// Problem constants\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst long long P = 998244353;\nconst double W = 0.5; // Heuristic weight for board squares that are not yet \"fixed\"\n\n// Struct to store a single stamp operation\nstruct Op {\n    int m, p, q;\n};\n\n// Struct to represent a combination of 0 to 3 stamps used at the same (p, q) position\nstruct Combination {\n    int k;                   // Total number of stamps in the combination\n    vector<int> ms;          // Indices of the stamps used\n    uint32_t s[3][3];        // Sum of stamp values modulo P\n};\n\n// State representation for the beam search\nstruct State {\n    uint32_t board[N][N];    // Board square values modulo P\n    int total_k;             // Cumulative number of stamps used so far\n    int parent_idx;          // Link to parent state index in the previous beam level\n    int combi_idx;           // Index of the combination chosen at the current step\n    double eval;             // Weighted evaluation score\n};\n\n// Potential candidate for the next step of the beam search\nstruct Candidate {\n    int state_idx;           // Index of the parent state in the current beam\n    int combi_idx;           // Index of the combination to apply\n    double eval;             // Resulting evaluation score\n\n    // Descending order comparison by evaluation score\n    bool operator>(const Candidate& other) const {\n        return eval > other.eval;\n    }\n};\n\n// Global arrays for precomputed heuristic values to speed up evaluation\ndouble pre_eval_sum_sw[49][1771];\ndouble P_w_after[49][3][3];\ndouble w_after_val[49][3][3];\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    uint32_t a[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    uint32_t stamps[M][3][3];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[m][i][j];\n\n    // Precompute all stamp combinations of sizes 0, 1, 2, and 3\n    vector<Combination> all_combi;\n    all_combi.push_back({0, {}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}});\n\n    for (int m = 0; m < M; ++m) {\n        Combination c;\n        c.k = 1; c.ms = {m};\n        for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) c.s[i][j] = stamps[m][i][j];\n        all_combi.push_back(c);\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            Combination c;\n            c.k = 2; c.ms = {m1, m2};\n            for (int i = 0; i < 3; ++i)\n                for (int j = 0; j < 3; ++j)\n                    c.s[i][j] = (stamps[m1][i][j] + stamps[m2][i][j]) % P;\n            all_combi.push_back(c);\n        }\n    }\n\n    for (int m1 = 0; m1 < M; ++m1) {\n        for (int m2 = m1; m2 < M; ++m2) {\n            for (int m3 = m2; m3 < M; ++m3) {\n                Combination c;\n                c.k = 3; c.ms = {m1, m2, m3};\n                for (int i = 0; i < 3; ++i)\n                    for (int j = 0; j < 3; ++j)\n                        c.s[i][j] = ((long long)stamps[m1][i][j] + stamps[m2][i][j] + stamps[m3][i][j]) % P;\n                all_combi.push_back(c);\n            }\n        }\n    }\n\n    // List all potential stamp placement corners (p, q) in row-major order\n    vector<pair<int, int>> positions;\n    for (int p = 0; p <= 6; ++p)\n        for (int q = 0; q <= 6; ++q)\n            positions.push_back({p, q});\n\n    // Identify for each grid cell when it will no longer be affected by future stamps\n    int last_p[N][N], last_q[N][N];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            last_p[r][c] = -1; last_q[r][c] = -1;\n            for (const auto& pos : positions) {\n                if (r >= pos.first && r < pos.first + 3 && c >= pos.second && c < pos.second + 3) {\n                    last_p[r][c] = pos.first;\n                    last_q[r][c] = pos.second;\n                }\n            }\n        }\n    }\n\n    // Track which squares become \"fixed\" at each step in the beam search\n    vector<pair<int, int>> fixed_squares[7][7];\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            fixed_squares[last_p[r][c]][last_q[r][c]].push_back({r, c});\n        }\n    }\n\n    // Precompute heuristic values for stamp weights at each position\n    for (int step = 0; step < 49; ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int r = p + i, c = q + j;\n                double w = (last_p[r][c] == p && last_q[r][c] == q) ? 1.0 : W;\n                w_after_val[step][i][j] = w;\n                P_w_after[step][i][j] = (double)P * w;\n            }\n        }\n        for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n            double sum_sw = 0;\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    sum_sw += (double)all_combi[c_idx].s[i][j] * w_after_val[step][i][j];\n                }\n            }\n            pre_eval_sum_sw[step][c_idx] = sum_sw;\n        }\n    }\n\n    // Beam search initialization\n    State initial_state;\n    memcpy(initial_state.board, a, sizeof(a));\n    initial_state.total_k = 0;\n    initial_state.parent_idx = -1;\n    initial_state.combi_idx = -1;\n    initial_state.eval = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            initial_state.eval += (double)a[i][j] * W;\n\n    vector<vector<State>> all_beams;\n    all_beams.push_back({initial_state});\n\n    int B = 900; // Beam size (adjusted for speed)\n    vector<Candidate> candidates;\n    candidates.reserve(B * all_combi.size());\n\n    // Iterative beam search through each stamp position\n    for (int step = 0; step < (int)positions.size(); ++step) {\n        int p = positions[step].first;\n        int q = positions[step].second;\n        const vector<State>& current_beam = all_beams.back();\n        candidates.clear();\n\n        for (int s_idx = 0; s_idx < (int)current_beam.size(); ++s_idx) {\n            const State& st = current_beam[s_idx];\n            double base_eval_increase = 0;\n            for (const auto& sq : fixed_squares[p][q]) {\n                base_eval_increase += (double)st.board[sq.first][sq.second] * (1.0 - W);\n            }\n            double base_eval = st.eval + base_eval_increase;\n\n            // Tight inner loop for evaluation of each combination\n            for (int c_idx = 0; c_idx < (int)all_combi.size(); ++c_idx) {\n                const Combination& combi = all_combi[c_idx];\n                if (st.total_k + combi.k > K) continue;\n\n                double cur_eval = base_eval + pre_eval_sum_sw[step][c_idx];\n                if (st.board[p][q] + combi.s[0][0] >= P) cur_eval -= P_w_after[step][0][0];\n                if (st.board[p][q+1] + combi.s[0][1] >= P) cur_eval -= P_w_after[step][0][1];\n                if (st.board[p][q+2] + combi.s[0][2] >= P) cur_eval -= P_w_after[step][0][2];\n                if (st.board[p+1][q] + combi.s[1][0] >= P) cur_eval -= P_w_after[step][1][0];\n                if (st.board[p+1][q+1] + combi.s[1][1] >= P) cur_eval -= P_w_after[step][1][1];\n                if (st.board[p+1][q+2] + combi.s[1][2] >= P) cur_eval -= P_w_after[step][1][2];\n                if (st.board[p+2][q] + combi.s[2][0] >= P) cur_eval -= P_w_after[step][2][0];\n                if (st.board[p+2][q+1] + combi.s[2][1] >= P) cur_eval -= P_w_after[step][2][1];\n                if (st.board[p+2][q+2] + combi.s[2][2] >= P) cur_eval -= P_w_after[step][2][2];\n                \n                candidates.push_back({s_idx, c_idx, cur_eval});\n            }\n        }\n\n        // Selection of top B candidates for the next beam level\n        int next_B = min((int)candidates.size(), B);\n        nth_element(candidates.begin(), candidates.begin() + next_B, candidates.end(), greater<Candidate>());\n        candidates.resize(next_B);\n\n        vector<State> next_beam;\n        next_beam.reserve(next_B);\n        for (const auto& cand : candidates) {\n            const State& parent = current_beam[cand.state_idx];\n            const Combination& combi = all_combi[cand.combi_idx];\n            State ns;\n            memcpy(ns.board, parent.board, sizeof(parent.board));\n            for (int i = 0; i < 3; ++i) {\n                for (int j = 0; j < 3; ++j) {\n                    uint32_t v = ns.board[p + i][q + j] + combi.s[i][j];\n                    if (v >= P) v -= P;\n                    ns.board[p + i][q + j] = v;\n                }\n            }\n            ns.total_k = parent.total_k + combi.k;\n            ns.parent_idx = cand.state_idx;\n            ns.combi_idx = cand.combi_idx;\n            ns.eval = cand.eval;\n            next_beam.push_back(std::move(ns));\n        }\n        all_beams.push_back(std::move(next_beam));\n    }\n\n    // Retrieve best overall final state and output the sequence of operations\n    const vector<State>& final_beam = all_beams.back();\n    int best_state_idx = 0;\n    double best_eval = -1e18;\n    for (int i = 0; i < (int)final_beam.size(); ++i) {\n        if (final_beam[i].eval > best_eval) {\n            best_eval = final_beam[i].eval;\n            best_state_idx = i;\n        }\n    }\n\n    vector<Op> final_ops;\n    int cur_idx = best_state_idx;\n    for (int step = (int)positions.size() - 1; step >= 0; --step) {\n        const State& st = all_beams[step + 1][cur_idx];\n        const Combination& combi = all_combi[st.combi_idx];\n        for (int m_idx : combi.ms) {\n            final_ops.push_back({m_idx, positions[step].first, positions[step].second});\n        }\n        cur_idx = st.parent_idx;\n    }\n\n    cout << final_ops.size() << \"\\n\";\n    for (int i = (int)final_ops.size() - 1; i >= 0; --i) {\n        cout << final_ops[i].m << \" \" << final_ops[i].p << \" \" << final_ops[i].q << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <deque>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer solution.\n * \n * Logic:\n * 1. Strategic Induction Phase (Turn 0-17): All 5 cranes move in unison to clear \n *    the first three containers from each arrival gate and relocate them to buffer columns 1-3. \n *    This ensures that 20 containers are on the grid early on.\n * 2. Mobile Workspace Management: Helper cranes (1-4) are bombed at Turn 18 to remove\n *    all risks of collision and allow the Large Crane (Crane 0) maximum maneuverability.\n * 3. Priority Dispatch Logic: Large Crane 0 prioritizes delivering dispatchable \n *    containers based on total distance (pickup + delivery).\n * 4. Urgent Gate Unblocking: If no container can be dispatched, the crane moves \n *    to clear the arrival gate containing the globally most urgent container.\n * 5. Score Optimization: Strict sequential delivery ensures M1=0, M2=0, and M3=0.\n */\n\nconst int N = 5;\n\nstruct Crane {\n    int r, c;\n    int held = -1;\n    bool bombed = false;\n    string actions = \"\";\n    deque<char> plan;\n};\n\n// Returns 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    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int Nin;\n    if (!(cin >> Nin)) return 0;\n\n    vector<vector<int>> arrival_queue(N, vector<int>(N));\n    vector<int> gate_of(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!(cin >> arrival_queue[i][j])) return 0;\n            gate_of[arrival_queue[i][j]] = i;\n        }\n    }\n\n    vector<Crane> cranes(N);\n    for (int i = 0; i < N; i++) {\n        cranes[i].r = i; cranes[i].c = 0;\n    }\n\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<int> next_to_arrive(N, 0);\n    vector<int> next_needed(N);\n    for (int i = 0; i < N; i++) next_needed[i] = i * N;\n    int total_dispatched = 0;\n\n    // Fixed sequence for all 5 cranes to induce 3 containers each into buffer columns\n    string unison = \"PRRRQLLLPRRQLLPRQL\";\n\n    for (int t = 0; t < 10000; t++) {\n        // Step 1: Receiving Gates Induction\n        for (int i = 0; i < N; i++) {\n            if (grid[i][0] == -1 && next_to_arrive[i] < N) {\n                bool crane_holding_over_gate = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].bombed && cranes[k].held != -1 && cranes[k].r == i && cranes[k].c == 0) {\n                        crane_holding_over_gate = true; break;\n                    }\n                }\n                if (!crane_holding_over_gate) {\n                    grid[i][0] = arrival_queue[i][next_to_arrive[i]++];\n                }\n            }\n        }\n\n        // Step 2: Planning Crane actions\n        for (int i = 0; i < N; i++) {\n            if (cranes[i].bombed) continue;\n\n            if (t < (int)unison.length()) {\n                cranes[i].plan.push_back(unison[t]);\n            } else if (i > 0 && t == (int)unison.length()) {\n                cranes[i].plan.push_back('B');\n            } else if (i == 0 && cranes[0].plan.empty()) {\n                // Large Crane 0 Greedy Sort Strategy\n                int best_v = -1, min_cost = 10000, tr = -1, tc = -1, target_gate = -1;\n\n                // Priority 1: Pick and deliver any container that matches a dispatch gate's current requirement\n                for (int g = 0; g < N; g++) {\n                    int v_req = next_needed[g];\n                    if (v_req < (g + 1) * N) {\n                        for (int r = 0; r < N; r++) {\n                            for (int c = 0; c < 4; c++) {\n                                if (grid[r][c] == v_req) {\n                                    int cost = get_dist(cranes[0].r, cranes[0].c, r, c) + get_dist(r, c, g, 4);\n                                    if (cost < min_cost) {\n                                        min_cost = cost; best_v = v_req; tr = r; tc = c; target_gate = g;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n\n                if (best_v != -1) {\n                    int cr = cranes[0].r, cc = cranes[0].c;\n                    auto add_p = [&](int target_r, int target_c) {\n                        while (cr < target_r) { cranes[0].plan.push_back('D'); cr++; }\n                        while (cr > target_r) { cranes[0].plan.push_back('U'); cr--; }\n                        while (cc < target_c) { cranes[0].plan.push_back('R'); cc++; }\n                        while (cc > target_c) { cranes[0].plan.push_back('L'); cc--; }\n                    };\n                    add_p(tr, tc); cranes[0].plan.push_back('P');\n                    add_p(target_gate, 4); cranes[0].plan.push_back('Q');\n                } else {\n                    // Priority 2: Clear blocker from arrival gate of the most urgent container\n                    int urg_v = -1;\n                    for (int g = 0; g < N; g++) {\n                        if (next_needed[g] < (g + 1) * N) {\n                            if (urg_v == -1 || next_needed[g] < urg_v) urg_v = next_needed[g];\n                        }\n                    }\n\n                    if (urg_v != -1) {\n                        int g_induction = gate_of[urg_v];\n                        if (grid[g_induction][0] != -1 && grid[g_induction][0] != urg_v) {\n                            int cr = cranes[0].r, cc = cranes[0].c;\n                            auto add_p = [&](int target_r, int target_c) {\n                                while (cr < target_r) { cranes[0].plan.push_back('D'); cr++; }\n                                while (cr > target_r) { cranes[0].plan.push_back('U'); cr--; }\n                                while (cc < target_c) { cranes[0].plan.push_back('R'); cc++; }\n                                while (cc > target_c) { cranes[0].plan.push_back('L'); cc--; }\n                            };\n                            add_p(g_induction, 0); cranes[0].plan.push_back('P');\n                            int br = -1, bc = -1, min_dist_to_buffer = 100;\n                            for (int col = 1; col <= 3; col++) {\n                                for (int row = 0; row < N; row++) {\n                                    if (grid[row][col] == -1) {\n                                        int d = get_dist(g_induction, 0, row, col);\n                                        if (d < min_dist_to_buffer) { min_dist_to_buffer = d; br = row; bc = col; }\n                                    }\n                                }\n                            }\n                            if (br != -1) { add_p(br, bc); cranes[0].plan.push_back('Q'); }\n                        } else {\n                            // Wait at the arrival gate for the urgent container\n                            if (cranes[0].r != g_induction) cranes[0].plan.push_back(cranes[0].r < g_induction ? 'D' : 'U');\n                            else if (cranes[0].c > 0) cranes[0].plan.push_back('L');\n                            else cranes[0].plan.push_back('.');\n                        }\n                    }\n                }\n            }\n        }\n\n        // Step 3: Action execution and state update\n        for (int i = 0; i < N; i++) {\n            if (cranes[i].bombed) { cranes[i].actions += '.'; continue; }\n            char act = '.';\n            if (!cranes[i].plan.empty()) {\n                act = cranes[i].plan.front();\n                cranes[i].plan.pop_front();\n            }\n            cranes[i].actions += act;\n\n            if (act == 'P') {\n                cranes[i].held = grid[cranes[i].r][cranes[i].c];\n                grid[cranes[i].r][cranes[i].c] = -1;\n            } else if (act == 'Q') {\n                grid[cranes[i].r][cranes[i].c] = cranes[i].held;\n                cranes[i].held = -1;\n            } else if (act == 'U') cranes[i].r--;\n            else if (act == 'D') cranes[i].r++;\n            else if (act == 'L') cranes[i].c--;\n            else if (act == 'R') cranes[i].c++;\n            else if (act == 'B') cranes[i].bombed = true;\n        }\n\n        // Step 4: Dispatch processing\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int val = grid[i][4];\n                if (val == next_needed[i]) next_needed[i]++;\n                grid[i][4] = -1; \n                total_dispatched++;\n            }\n        }\n        if (total_dispatched == 25) break;\n    }\n\n    // Final output of all action sequences\n    for (int i = 0; i < N; i++) {\n        size_t max_len = 0;\n        for (int k = 0; k < N; k++) max_len = max(max_len, cranes[k].actions.length());\n        string s = cranes[i].actions;\n        while (s.length() < max_len) s += '.';\n        cout << s << endl;\n    }\n\n    return 0;\n}\n","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\n// The ground leveling site is a fixed 20x20 grid according to the problem.\nconst int N = 20;\n\n/**\n * Op struct represents an individual turn's operation: \n * loading (+d), unloading (-d), or movement (U, D, L, R).\n */\nstruct Op {\n    char type; // '+', '-', 'U', 'D', 'L', 'R'\n    int val;   // amount d for '+' or '-'\n};\n\n/**\n * State struct maintains the simulation status of the construction site.\n * It tracks current grid heights, truck position, soil load, operations, and cost.\n */\nstruct State {\n    int h[N][N];\n    int r, c;\n    long long L;\n    long long cost;\n    vector<Op> ops;\n\n    State(const int initial_h[N][N]) : r(0), c(0), L(0), cost(0) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                h[i][j] = initial_h[i][j];\n        ops.reserve(50000);\n    }\n\n    // Load d units of soil: truck load increases, height at square decreases.\n    void load(int d) {\n        if (d <= 0) return;\n        h[r][c] -= d;\n        L += (long long)d;\n        cost += (long long)d;\n        ops.push_back({'+', d});\n    }\n\n    // Unload d units of soil: truck load decreases, height at square increases.\n    void unload(int d) {\n        if (d <= 0) return;\n        h[r][c] += d;\n        L -= (long long)d;\n        cost += (long long)d;\n        ops.push_back({'-', d});\n    }\n\n    // Move to adjacent square: cost depends on movement (100) and current load (L).\n    void move(char dir) {\n        if (dir == 'U') r--;\n        else if (dir == 'D') r++;\n        else if (dir == 'L') c--;\n        else if (dir == 'R') c++;\n        cost += (100LL + L);\n        ops.push_back({dir, 0});\n    }\n};\n\n// Power tables to accelerate the calculation of heuristic scores during trials.\ndouble dist_pow_table[41];\ndouble soil_pow_table[101];\n\n/**\n * Solve function implementing a multi-start randomized greedy heuristic.\n * Heuristic parameters:\n *   dp: power for distance weighting.\n *   sp: power for soil volume weighting.\n *   lp: load penalty for source squares.\n *   sw: sink weight multiplier.\n *   cp: power for (100 + Load) cost weighting.\n */\nvoid solve(const int initial_h[N][N], double dp, double sp, double lp, double sw, double cp, \n           vector<Op>& best_ops, long long &best_total_cost, mt19937& rng) {\n    State s(initial_h);\n    vector<pair<int, int>> targets;\n    targets.reserve(N * N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (initial_h[i][j] != 0) targets.push_back({i, j});\n\n    // Initialize power tables for this specific solve trial.\n    for (int i = 1; i <= 40; ++i) dist_pow_table[i] = pow((double)i, dp);\n    for (int i = 1; i <= 100; ++i) soil_pow_table[i] = pow((double)i, sp);\n\n    while (s.ops.size() < 99950) {\n        // Step 1: Process current cell: load from sources or unload into sinks.\n        if (s.h[s.r][s.c] > 0) {\n            s.load(s.h[s.r][s.c]);\n        } else if (s.h[s.r][s.c] < 0 && s.L > 0) {\n            s.unload((int)min((long long)abs(s.h[s.r][s.c]), s.L));\n        }\n\n        // Periodically refresh the work target list.\n        for (int k = 0; k < (int)targets.size(); ++k) {\n            if (s.h[targets[k].first][targets[k].second] == 0) {\n                targets[k] = targets.back();\n                targets.pop_back();\n                k--;\n            }\n        }\n        if (targets.empty() && s.L == 0) break;\n        if (s.cost >= best_total_cost) return; // Pruning.\n\n        // Step 2: Target Selection Heuristic.\n        int tr = -1, tc = -1;\n        double min_score = 1e30;\n        double l_val = (cp == 1.0) ? (100.0 + (double)s.L) : pow(100.0 + (double)s.L, cp);\n\n        for (const auto& t : targets) {\n            int d_val = abs(s.r - t.first) + abs(s.c - t.second);\n            if (d_val == 0) continue;\n            if (s.h[t.first][t.second] < 0 && s.L == 0) continue;\n\n            int v_val = (s.h[t.first][t.second] > 0) ? s.h[t.first][t.second] : (int)min((long long)abs(s.h[t.first][t.second]), s.L);\n            if (v_val < 1) v_val = 1; else if (v_val > 100) v_val = 100;\n            \n            double score = (dist_pow_table[d_val] * l_val / soil_pow_table[v_val]);\n            if (s.h[t.first][t.second] > 0) score *= (1.0 + (double)s.L * lp);\n            else score *= sw;\n\n            if (score < min_score) {\n                min_score = score; tr = t.first; tc = t.second;\n            }\n        }\n        if (tr == -1) break;\n\n        // Step 3: Directional Move Selection using path density logic.\n        int dr = tr - s.r, dc = tc - s.c;\n        char best_m = 0;\n        if (dr != 0 && dc != 0) {\n            auto get_path_work = [&](bool row_then_col) {\n                double work = 0;\n                int cr = s.r, cc = s.c;\n                long long temp_L = s.L;\n                if (row_then_col) {\n                    int r_dir = (tr > s.r ? 1 : -1);\n                    while (cr != tr) { \n                        cr += r_dir; \n                        if (s.h[cr][cc] > 0) { work += s.h[cr][cc]; temp_L += s.h[cr][cc]; }\n                        else if (s.h[cr][cc] < 0 && temp_L > 0) { int d = (int)min((long long)abs(s.h[cr][cc]), temp_L); work += d; temp_L -= d; }\n                    }\n                    int c_dir = (tc > s.c ? 1 : -1);\n                    while (cc != tc) {\n                        cc += c_dir;\n                        if (s.h[cr][cc] > 0) { work += s.h[cr][cc]; temp_L += s.h[cr][cc]; }\n                        else if (s.h[cr][cc] < 0 && temp_L > 0) { int d = (int)min((long long)abs(s.h[cr][cc]), temp_L); work += d; temp_L -= d; }\n                    }\n                } else {\n                    int c_dir = (tc > s.c ? 1 : -1);\n                    while (cc != tc) {\n                        cc += c_dir;\n                        if (s.h[cr][cc] > 0) { work += s.h[cr][cc]; temp_L += s.h[cr][cc]; }\n                        else if (s.h[cr][cc] < 0 && temp_L > 0) { int d = (int)min((long long)abs(s.h[cr][cc]), temp_L); work += d; temp_L -= d; }\n                    }\n                    int r_dir = (tr > s.r ? 1 : -1);\n                    while (cr != tr) {\n                        cr += r_dir;\n                        if (s.h[cr][cc] > 0) { work += s.h[cr][cc]; temp_L += s.h[cr][cc]; }\n                        else if (s.h[cr][cc] < 0 && temp_L > 0) { int d = (int)min((long long)abs(s.h[cr][cc]), temp_L); work += d; temp_L -= d; }\n                    }\n                }\n                return work;\n            };\n            if (get_path_work(true) >= get_path_work(false)) best_m = (dr > 0 ? 'D' : 'U');\n            else best_m = (dc > 0 ? 'R' : 'L');\n        } else if (dr != 0) best_m = (dr > 0 ? 'D' : 'U');\n        else best_m = (dc > 0 ? 'R' : 'L');\n        \n        s.move(best_m);\n    }\n\n    // Evaluate trial outcome based on total cost and penalty for incomplete squares.\n    long long final_diff = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (s.h[i][j] != 0) final_diff += 100LL * abs(s.h[i][j]) + 10000LL;\n\n    if (s.cost + final_diff < best_total_cost) {\n        best_total_cost = s.cost + final_diff;\n        best_ops = s.ops;\n    }\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    int h[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> h[i][j];\n\n    auto start_time = chrono::steady_clock::now();\n    long long best_total_cost = 8e18;\n    vector<Op> best_ops;\n    mt19937 rng(42);\n\n    // Trial iterations with predefined high-performance parameter sets.\n    vector<vector<double>> params = {\n        {1.5, 1.0, 0.005, 0.5, 1.0}, {1.8, 1.2, 0.001, 0.3, 1.0}, {1.2, 0.8, 0.010, 0.8, 1.0},\n        {2.0, 0.5, 0.001, 0.6, 1.0}, {1.4, 1.4, 0.0001, 0.9, 1.0}\n    };\n    for (const auto& p : params) solve(h, p[0], p[1], p[2], p[3], p[4], best_ops, best_total_cost, rng);\n\n    // Multi-start randomized greedy search within 2.0s time limit.\n    uniform_real_distribution<double> dp_dist(1.0, 3.5), sp_dist(0.1, 2.0), lp_dist(0.0, 0.025), sw_dist(0.01, 1.5), cp_dist(0.5, 1.5);\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1850) {\n        solve(h, dp_dist(rng), sp_dist(rng), lp_dist(rng), sw_dist(rng), cp_dist(rng), best_ops, best_total_cost, rng);\n    }\n\n    // Output best operation sequence discovered.\n    for (const auto& op : best_ops) {\n        if (op.type == '+' || op.type == '-') cout << op.type << op.val << \"\\n\";\n        else cout << op.type << \"\\n\";\n    }\n\n    return 0;\n}\n","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\n/**\n * Problem Analysis:\n * - We have an N x N (6x6) grid, and we plant 36 seeds from a pool of 60.\n * - Each edge (horizontal and vertical neighbor) generates a new seed by randomly inheriting \n *   values from its two parent seeds for each of the M=15 evaluation criteria.\n * - Objective: Maximize the maximum sum of criteria in any seed after T=10 turns.\n * \n * Strategy:\n * 1. Potential Function: Use a potential function P(i, j) to predict offspring quality from parents i and j.\n *    The function is (sum of max criterion values)^p. The exponent p increases over turns to transition \n *    from diversity-preserving early breeding to peak-focused late breeding.\n * 2. Selection: Diversity is maintained by selecting the best seed for each criterion (15 seeds), \n *    supplemented by the best remaining seeds by total sum to fill the 36 planting slots.\n * 3. Grid Arrangement: Use Simulated Annealing (SA) to optimize both the selection and the placement \n *    of seeds on the grid, maximizing the total potential edge score.\n */\n\nconst int N = 6;\nconst int M = 15;\nconst int T_MAX = 10;\nconst int SEED_COUNT = 60;\nconst int PLANT_COUNT = 36;\nconst int UNUSED_COUNT = 24;\n\nstruct Seed {\n    int x[M];\n    int v; // Total sum of elements\n};\n\n// P2 precomputes the potential breeding value for every seed pair.\nlong long P2[SEED_COUNT][SEED_COUNT];\n\nvoid precompute_potentials(const vector<Seed>& seeds, double p) {\n    vector<long long> pow_table(1501);\n    for (int i = 0; i <= 1500; ++i) pow_table[i] = (long long)pow((double)i, p);\n\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = i + 1; j < SEED_COUNT; ++j) {\n            int s_max = 0;\n            for (int l = 0; l < M; ++l) {\n                s_max += max(seeds[i].x[l], seeds[j].x[l]);\n            }\n            P2[i][j] = P2[j][i] = pow_table[s_max];\n        }\n        P2[i][i] = 0;\n    }\n}\n\nint main() {\n    // Fast I/O configuration.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, m_in, t_in;\n    if (!(cin >> n_in >> m_in >> t_in)) return 0;\n\n    vector<Seed> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        seeds[i].v = 0;\n        for (int j = 0; j < M; ++j) {\n            if (!(cin >> seeds[i].x[j])) return 0;\n            seeds[i].v += seeds[i].x[j];\n        }\n    }\n\n    mt19937 rng(1337);\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    for (int turn = 0; turn < T_MAX; ++turn) {\n        // Exponent strategy: gradually increase p to focus on peak performance.\n        double p = 1.7;\n        if (turn >= 3) p = 2.0;\n        if (turn >= 6) p = 2.3;\n        if (turn >= 9) p = 2.6;\n        precompute_potentials(seeds, p);\n\n        // Selection Phase: Focus on dimension-specific specialists and overall strong generalists.\n        vector<int> current_selection;\n        vector<bool> is_selected(SEED_COUNT, false);\n        for (int l = 0; l < M; ++l) {\n            int best_idx = -1, max_val = -1;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (seeds[i].x[l] > max_val) {\n                    max_val = seeds[i].x[l];\n                    best_idx = i;\n                }\n            }\n            if (best_idx != -1 && !is_selected[best_idx]) {\n                is_selected[best_idx] = true;\n                current_selection.push_back(best_idx);\n            }\n        }\n        vector<int> sorted_indices(SEED_COUNT);\n        iota(sorted_indices.begin(), sorted_indices.end(), 0);\n        sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n        for (int idx : sorted_indices) {\n            if (current_selection.size() < PLANT_COUNT && !is_selected[idx]) {\n                is_selected[idx] = true;\n                current_selection.push_back(idx);\n            }\n        }\n\n        // Grid setup: Higher-degree (interior) squares are initialized with better seeds.\n        int grid[N][N];\n        vector<pair<int, int>> squares;\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) squares.push_back({r, c});\n        sort(squares.begin(), squares.end(), [](pair<int, int> a, pair<int, int> b) {\n            auto degree = [](pair<int, int> p) {\n                return (p.first > 0) + (p.first < N - 1) + (p.second > 0) + (p.second < N - 1);\n            };\n            return degree(a) > degree(b);\n        });\n        sort(current_selection.begin(), current_selection.end(), [&](int a, int b) {\n            return seeds[a].v > seeds[b].v;\n        });\n        for (int i = 0; i < PLANT_COUNT; ++i) {\n            grid[squares[i].first][squares[i].second] = current_selection[i];\n        }\n\n        int off_grid[UNUSED_COUNT];\n        int off_ptr = 0;\n        for (int i = 0; i < SEED_COUNT; ++i) if (!is_selected[i]) off_grid[off_ptr++] = i;\n\n        auto get_local_potential = [&](int r, int c) {\n            long long res = 0;\n            if (r > 0) res += P2[grid[r][c]][grid[r - 1][c]];\n            if (r < N - 1) res += P2[grid[r][c]][grid[r + 1][c]];\n            if (c > 0) res += P2[grid[r][c]][grid[r][c - 1]];\n            if (c < N - 1) res += P2[grid[r][c]][grid[r][c + 1]];\n            return res;\n        };\n\n        // Total edge potential.\n        long long current_total_score = 0;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r + 1 < N) current_total_score += P2[grid[r][c]][grid[r + 1][c]];\n                if (c + 1 < N) current_total_score += P2[grid[r][c]][grid[r][c + 1]];\n            }\n        }\n\n        long long best_total_seen = current_total_score;\n        int best_grid_seen[N][N];\n        for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid_seen[r][c] = grid[r][c];\n\n        // SA configuration.\n        auto turn_start = chrono::steady_clock::now();\n        const double TIME_LIMIT = 0.194;\n        const double start_temp = 0.01 * pow(1200.0, p);\n        const double end_temp = 0.01 * start_temp;\n        long long iterations = 0;\n\n        while (true) {\n            if ((iterations & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now - turn_start).count();\n                if (elapsed > TIME_LIMIT) break;\n                double temp = start_temp * pow(end_temp / start_temp, elapsed / TIME_LIMIT);\n\n                for (int step = 0; step < 1024; ++step) {\n                    int move_type = rng() % 100;\n                    if (move_type < 75) {\n                        // Neighborhood: Swap seeds on grid.\n                        int r1 = rng() % N, c1 = rng() % N;\n                        int r2 = rng() % N, c2 = rng() % N;\n                        if (r1 == r2 && c1 == c2) continue;\n\n                        long long old_l = get_local_potential(r1, c1) + get_local_potential(r2, c2);\n                        bool adj = (abs(r1 - r2) + abs(c1 - c2) == 1);\n                        if (adj) old_l -= P2[grid[r1][c1]][grid[r2][c2]];\n\n                        swap(grid[r1][c1], grid[r2][c2]);\n\n                        long long new_l = get_local_potential(r1, c1) + get_local_potential(r2, c2);\n                        if (adj) new_l -= P2[grid[r1][c1]][grid[r2][c2]];\n\n                        long long diff = new_l - old_l;\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_seen) {\n                                best_total_seen = current_total_score;\n                                for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) best_grid_seen[r][c] = grid[r][c];\n                            }\n                        } else swap(grid[r1][c1], grid[r2][c2]);\n                    } else {\n                        // Neighborhood: Swap grid seed with pool seed.\n                        int r = rng() % N, c = rng() % N;\n                        int idx = rng() % UNUSED_COUNT;\n\n                        long long old_l = get_local_potential(r, c);\n                        swap(grid[r][c], off_grid[idx]);\n                        long long new_l = get_local_potential(r, c);\n                        long long diff = new_l - old_l;\n\n                        if (diff >= 0 || exp((double)diff / temp) > dist(rng)) {\n                            current_total_score += diff;\n                            if (current_total_score > best_total_seen) {\n                                best_total_seen = current_total_score;\n                                for (int rr = 0; rr < N; ++rr) for (int cc = 0; cc < N; ++cc) best_grid_seen[rr][cc] = grid[rr][cc];\n                            }\n                        } else swap(grid[r][c], off_grid[idx]);\n                    }\n                }\n            }\n            iterations++;\n        }\n\n        // Print final grid for this turn.\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) cout << best_grid_seen[r][c] << (c == N - 1 ? \"\" : \" \");\n            cout << endl;\n        }\n        cout.flush();\n\n        // Retrieve offspring seeds.\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            seeds[i].v = 0;\n            for (int j = 0; j < M; ++j) {\n                if (!(cin >> seeds[i].x[j])) return 0;\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 <random>\n\nusing namespace std;\n\n/**\n * Heuristic approach for the takoyaki robotic arm problem.\n * 1. Matching: Randomized iterative swap matching is used to minimize the total Manhattan distance.\n * 2. Robotic Arm Design: A star tree where vertex 0 is the root and vertices 1 to V-1 are leaf fingertips.\n * 3. Strategy: Select a focus task (either pick up a takoyaki or deliver a held one) using a greedy heuristic.\n * 4. Priority: Blockers (takoyakis at target squares of already held takoyakis) have the highest pickup priority.\n * 5. Deadlock Prevention: Reserve one finger to ensure blockers can always be picked up.\n * 6. Opportunistic Action: All fingers check for pickup or delivery actions every turn.\n */\n\nstruct Takoyaki {\n    int id, sx, sy, tx, ty, state, f_id; // state: 0 (initial), 1 (held), 2 (delivered)\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; i++) cin >> s_grid[i];\n    for (int i = 0; i < N; i++) cin >> t_grid[i];\n\n    vector<pair<int, int>> S_pos, T_pos;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (s_grid[i][j] == '1') S_pos.push_back({i, j});\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (t_grid[i][j] == '1') T_pos.push_back({i, j});\n\n    // Match each takoyaki starting position to a target location.\n    vector<int> S_to_T(M);\n    for (int i = 0; i < M; i++) S_to_T[i] = i;\n    mt19937 rng(42);\n    for (int iter = 0; iter < 100000; iter++) {\n        int i = rng() % M, j = rng() % M;\n        auto dist = [](pair<int, int> a, pair<int, int> b) {\n            return abs(a.first - b.first) + abs(a.second - b.second);\n        };\n        if (dist(S_pos[i], T_pos[S_to_T[i]]) + dist(S_pos[j], T_pos[S_to_T[j]]) >\n            dist(S_pos[i], T_pos[S_to_T[j]]) + dist(S_pos[j], T_pos[S_to_T[i]]))\n            swap(S_to_T[i], S_to_T[j]);\n    }\n\n    // Initialize takoyaki entities and grid occupancy trackers.\n    vector<Takoyaki> takos(M);\n    vector<vector<int>> grid_tako_id(N, vector<int>(N, -1));\n    vector<vector<bool>> grid_occ(N, vector<bool>(N, false));\n    int delivered = 0;\n    for (int i = 0; i < M; i++) {\n        takos[i] = {i, S_pos[i].first, S_pos[i].second, T_pos[S_to_T[i]].first, T_pos[S_to_T[i]].second, 0, -1};\n        if (takos[i].sx == takos[i].tx && takos[i].sy == takos[i].ty) {\n            takos[i].state = 2; delivered++;\n            grid_occ[takos[i].sx][takos[i].sy] = true;\n        } else {\n            grid_tako_id[takos[i].sx][takos[i].sy] = i;\n            grid_occ[takos[i].sx][takos[i].sy] = true;\n        }\n    }\n\n    // Design the robotic arm: Star tree structure.\n    cout << V << \"\\n\";\n    vector<int> L(V);\n    for (int i = 1; i < V; i++) {\n        L[i] = (i - 1) % (N - 1) + 1;\n        cout << 0 << \" \" << L[i] << \"\\n\";\n    }\n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n\n    vector<int> f_dir(V, 0), f_hold(V, -1);\n    int dr[] = {0, 1, 0, -1}, dc[] = {1, 0, -1, 0};\n    int turns = 0;\n\n    // Simulation loop.\n    while (delivered < M && turns < 100000) {\n        long long best_score = 1e18;\n        int focus_f = -1, focus_t = -1, focus_d = -1;\n        int busy_f = 0;\n        for (int f = 1; f < V; f++) if (f_hold[f] != -1) busy_f++;\n\n        // Heuristic selection for next target square.\n        for (int f = 1; f < V; f++) {\n            if (f_hold[f] == -1) {\n                if (busy_f >= V - 1 && delivered + busy_f < M) continue;\n                for (int i = 0; i < M; i++) {\n                    if (takos[i].state == 0) {\n                        bool is_bl = false;\n                        for (int k = 1; k < V; k++) \n                            if (f_hold[k] != -1 && takos[f_hold[k]].tx == takos[i].sx && takos[f_hold[k]].ty == takos[i].sy) is_bl = true;\n                        for (int d = 0; d < 4; d++) {\n                            int trx = takos[i].sx - dr[d] * L[f], try_ = takos[i].sy - dc[d] * L[f];\n                            if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                                int dist = max(abs(rx - trx) + abs(ry - try_), (f_dir[f] == d ? 0 : (abs(f_dir[f] - d) == 2 ? 2 : 1)));\n                                long long score = (long long)dist * 100 + (is_bl ? -10000 : 10000);\n                                if (score < best_score) { best_score = score; focus_f = f; focus_t = i; focus_d = d; }\n                            }\n                        }\n                    }\n                }\n            } else {\n                int i = f_hold[f];\n                if (!grid_occ[takos[i].tx][takos[i].ty]) {\n                    for (int d = 0; d < 4; d++) {\n                        int trx = takos[i].tx - dr[d] * L[f], try_ = takos[i].ty - dc[d] * L[f];\n                        if (trx >= 0 && trx < N && try_ >= 0 && try_ < N) {\n                            int dist = max(abs(rx - trx) + abs(ry - try_), (f_dir[f] == d ? 0 : (abs(f_dir[f] - d) == 2 ? 2 : 1)));\n                            long long score = (long long)dist * 100 + 5000;\n                            if (score < best_score) { best_score = score; focus_f = f; focus_t = i; focus_d = d; }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (focus_f == -1) break;\n\n        int target_rx = (takos[focus_t].state == 0) ? takos[focus_t].sx - dr[focus_d] * L[focus_f] : takos[focus_t].tx - dr[focus_d] * L[focus_f];\n        int target_ry = (takos[focus_t].state == 0) ? takos[focus_t].sy - dc[focus_d] * L[focus_f] : takos[focus_t].ty - dc[focus_d] * L[focus_f];\n        int init_s = takos[focus_t].state;\n\n        while (turns < 100000) {\n            string m_str = \"\";\n            if (rx < target_rx) { rx++; m_str += 'D'; } else if (rx > target_rx) { rx--; m_str += 'U'; }\n            else if (ry < target_ry) { ry++; m_str += 'R'; } else if (ry > target_ry) { ry--; m_str += 'L'; } else m_str += '.';\n            for (int f = 1; f < V; f++) {\n                if (f == focus_f && f_dir[f] != focus_d) {\n                    if ((f_dir[f] + 1) % 4 == focus_d) { f_dir[f] = (f_dir[f] + 1) % 4; m_str += 'R'; }\n                    else { f_dir[f] = (f_dir[f] + 3) % 4; m_str += 'L'; }\n                } else m_str += '.';\n            }\n            string a_str = \".\"; int curr_busy = 0;\n            for (int k = 1; k < V; k++) if (f_hold[k] != -1) curr_busy++;\n            for (int f = 1; f < V; f++) {\n                int fr = rx + dr[f_dir[f]] * L[f], fc = ry + dc[f_dir[f]] * L[f];\n                bool ok = false;\n                if (fr >= 0 && fr < N && fc >= 0 && fc < N) {\n                    if (f_hold[f] == -1) {\n                        int id = grid_tako_id[fr][fc];\n                        if (id != -1 && takos[id].state == 0) {\n                            bool is_bl = false;\n                            for (int k = 1; k < V; k++) if (f_hold[k] != -1 && takos[f_hold[k]].tx == fr && takos[f_hold[k]].ty == fc) is_bl = true;\n                            if (is_bl || curr_busy < V - 2 || (id == focus_t && f == focus_f) || delivered + curr_busy + 1 == M) {\n                                takos[id].state = 1; takos[id].f_id = f; f_hold[f] = id;\n                                grid_occ[fr][fc] = false; grid_tako_id[fr][fc] = -1;\n                                a_str += 'P'; ok = true; curr_busy++;\n                            }\n                        }\n                    } else {\n                        int id = f_hold[f];\n                        if (fr == takos[id].tx && fc == takos[id].ty && !grid_occ[fr][fc]) {\n                            takos[id].state = 2; f_hold[f] = -1;\n                            grid_occ[fr][fc] = true; delivered++;\n                            a_str += 'P'; ok = true; curr_busy--;\n                        }\n                    }\n                }\n                if (!ok) a_str += '.';\n            }\n            cout << m_str << a_str << \"\\n\";\n            turns++;\n            if (delivered == M || takos[focus_t].state != init_s || (rx == target_rx && ry == target_ry && f_dir[focus_f] == focus_d)) break;\n        }\n    }\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n/**\n * World-class algorithm engineer's solution for the Takahashi Fisher problem.\n * \n * Strategy:\n * 1. Find the best x-monotone or y-monotone rectilinear polygon.\n * 2. Monotone rectilinear polygons satisfy:\n *    - No self-intersections (by construction).\n *    - Vertex count limit (well under 1000).\n *    - Perimeter constraint (enforced within the DP objective).\n * 3. Use coordinate compression to build an adaptive grid based on fish locations.\n * 4. Use Dynamic Programming with Lagrangian relaxation to maximize:\n *    Objective = (Mackerels - Sardines) * SCALE - Perimeter\n *    Setting SCALE = 10,000,000 ensures mackerels are the primary priority.\n * 5. A penalty is applied to any path exceeding the 400,000 length limit.\n */\n\nconst int G_MAX = 86; // Grid resolution\nconst long long SCALE = 10000000LL;\nconst long long INF = 1e17;\n\nstruct Point {\n    int x, y;\n};\n\nstruct Result {\n    int fish_score;\n    long long perimeter;\n    int i_start, i_end;\n    vector<pair<int, int>> path;\n    bool swapped;\n    vector<int> xs, ys;\n};\n\n// Global DP tables to optimize memory usage and speed\nstatic int cell_fish[G_MAX][G_MAX];\nstatic int row_sum[G_MAX][G_MAX + 1];\nstatic int fish_dp[G_MAX][G_MAX][G_MAX];\nstatic int perim_dp[G_MAX][G_MAX][G_MAX];\nstatic pair<short, short> p_table[G_MAX][G_MAX][G_MAX];\n\n/**\n * Solve for an x-monotone rectilinear polygon in the given orientation.\n */\nResult solve_monotone(int N, const vector<Point>& macks, const vector<Point>& sards, bool swap_xy, int grid_size, int d_limit) {\n    vector<Point> m = macks, s = sards;\n    if (swap_xy) {\n        for (int i = 0; i < N; ++i) {\n            swap(m[i].x, m[i].y);\n            swap(s[i].x, s[i].y);\n        }\n    }\n\n    // 1. Adaptive Coordinate Compression\n    vector<int> X = {0, 100000}, Y = {0, 100000};\n    for (int i = 0; i < N; ++i) {\n        X.push_back(m[i].x); X.push_back(s[i].x);\n        Y.push_back(m[i].y); Y.push_back(s[i].y);\n    }\n    sort(X.begin(), X.end()); X.erase(unique(X.begin(), X.end()), X.end());\n    sort(Y.begin(), Y.end()); Y.erase(unique(Y.begin(), Y.end()), Y.end());\n\n    int gx_cnt = min((int)X.size() - 1, grid_size);\n    int gy_cnt = min((int)Y.size() - 1, grid_size);\n    vector<int> xs, ys;\n    for (int i = 0; i <= gx_cnt; ++i) xs.push_back(X[i * (X.size() - 1) / gx_cnt]);\n    for (int i = 0; i <= gy_cnt; ++i) ys.push_back(Y[i * (Y.size() - 1) / gy_cnt]);\n\n    // 2. Map fish density to the grid cells\n    for (int i = 0; i < gx_cnt; ++i) for (int j = 0; j < gy_cnt; ++j) cell_fish[i][j] = 0;\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), m[i].x) - xs.begin(); if (gx > 0 && (gx == gx_cnt || xs[gx] > m[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), m[i].y) - ys.begin(); if (gy > 0 && (gy == gy_cnt || ys[gy] > m[i].y)) gy--;\n        if (gx < gx_cnt && gy < gy_cnt) cell_fish[gx][gy]++;\n    }\n    for (int i = 0; i < N; ++i) {\n        int gx = lower_bound(xs.begin(), xs.end(), s[i].x) - xs.begin(); if (gx > 0 && (gx == gx_cnt || xs[gx] > s[i].x)) gx--;\n        int gy = lower_bound(ys.begin(), ys.end(), s[i].y) - ys.begin(); if (gy > 0 && (gy == gy_cnt || ys[gy] > s[i].y)) gy--;\n        if (gx < gx_cnt && gy < gy_cnt) cell_fish[gx][gy]--;\n    }\n\n    for (int i = 0; i < gx_cnt; ++i) {\n        row_sum[i][0] = 0;\n        for (int j = 0; j < gy_cnt; ++j) row_sum[i][j + 1] = row_sum[i][j] + cell_fish[i][j];\n    }\n\n    // 3. Main Dynamic Programming Loop\n    for (int i = 0; i < gx_cnt; ++i) \n        for (int L = 0; L < gy_cnt; ++L) \n            for (int R = L; R < gy_cnt; ++R) {\n                fish_dp[i][L][R] = -1000000;\n                perim_dp[i][L][R] = 10000000;\n            }\n\n    for (int i = 0; i < gx_cnt; ++i) {\n        int dx2 = 2 * (xs[i + 1] - xs[i]);\n        for (int L = 0; L < gy_cnt; ++L) {\n            for (int R = L; R < gy_cnt; ++R) {\n                int cur_f = row_sum[i][R + 1] - row_sum[i][L];\n                // Path Initiation: A single-column vertical rectangle\n                fish_dp[i][L][R] = cur_f;\n                perim_dp[i][L][R] = dx2 + (ys[R + 1] - ys[L]);\n                p_table[i][L][R] = {-1, -1};\n\n                // Path Extension: Connecting to an overlapping interval in the previous column\n                if (i > 0) {\n                    int L1_s = max(0, L - d_limit), L1_e = min({gy_cnt - 1, L + d_limit, R});\n                    int R1_s = max({0, R - d_limit, L}), R1_e = min(gy_cnt - 1, R + d_limit);\n                    for (int L1 = L1_s; L1 <= L1_e; ++L1) {\n                        for (int R1 = max(L1, R1_s); R1 <= R1_e; ++R1) {\n                            if (fish_dp[i - 1][L1][R1] < -5000) continue;\n                            \n                            int jump = abs(ys[L] - ys[L1]) + abs(ys[R + 1] - ys[R1 + 1]);\n                            int nf = fish_dp[i - 1][L1][R1] + cur_f;\n                            int np = perim_dp[i - 1][L1][R1] + jump + dx2;\n\n                            // Objective: maximize fish, penalize perimeter, avoid exceeding 400,000 length\n                            long long old_obj = (long long)fish_dp[i][L][R] * SCALE - perim_dp[i][L][R];\n                            if (perim_dp[i][L][R] + (ys[R + 1] - ys[L]) > 400000) old_obj -= 100000000000000LL;\n                            \n                            long long new_obj = (long long)nf * SCALE - np;\n                            if (np + (ys[R + 1] - ys[L]) > 400000) new_obj -= 100000000000000LL;\n\n                            if (new_obj > old_obj) {\n                                fish_dp[i][L][R] = nf;\n                                perim_dp[i][L][R] = np;\n                                p_table[i][L][R] = {(short)L1, (short)R1};\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // 4. Extract the Global Optimal Solution\n    long long best_obj = -INF;\n    int bi = -1, bl = -1, br = -1;\n    for (int i = 0; i < gx_cnt; ++i) {\n        for (int L = 0; L < gy_cnt; ++L) {\n            for (int R = L; R < gy_cnt; ++R) {\n                if (fish_dp[i][L][R] < -5000) continue;\n                long long total_p = (long long)perim_dp[i][L][R] + (ys[R + 1] - ys[L]);\n                long long obj = (long long)fish_dp[i][L][R] * SCALE - total_p;\n                if (total_p > 400000) obj -= 100000000000000LL;\n                if (obj > best_obj) {\n                    best_obj = obj; bi = i; bl = L; br = R;\n                }\n            }\n        }\n    }\n\n    if (bi == -1 || fish_dp[bi][bl][br] <= 0) return {0, 0, -1, -1, {}, swap_xy, xs, ys};\n\n    vector<pair<int, int>> path;\n    int ci = bi, cl = bl, cr = br;\n    while (ci >= 0 && cl != -1) {\n        path.push_back({cl, cr});\n        auto p = p_table[ci][cl][cr];\n        cl = p.first; cr = p.second; ci--;\n    }\n    reverse(path.begin(), path.end());\n    return {fish_dp[bi][bl][br], (long long)perim_dp[bi][bl][br] + (ys[br + 1] - ys[bl]), bi - (int)path.size() + 1, bi, path, swap_xy, xs, ys};\n}\n\n/**\n * Output standard vertex format for a monotone rectilinear polygon.\n */\nvoid output(const Result& res) {\n    if (res.fish_score <= 0) {\n        cout << \"4\\n0 0\\n0 1\\n1 1\\n1 0\" << endl;\n        return;\n    }\n    vector<pair<int, int>> v;\n    int n = res.path.size();\n    v.push_back({res.xs[res.i_start], res.ys[res.path[0].first]});\n    v.push_back({res.xs[res.i_start], res.ys[res.path[0].second + 1]});\n    for (int i = 0; i < n - 1; ++i) {\n        v.push_back({res.xs[res.i_start + i + 1], res.ys[res.path[i].second + 1]});\n        v.push_back({res.xs[res.i_start + i + 1], res.ys[res.path[i + 1].second + 1]});\n    }\n    v.push_back({res.xs[res.i_end + 1], res.ys[res.path.back().second + 1]});\n    v.push_back({res.xs[res.i_end + 1], res.ys[res.path.back().first]});\n    for (int i = n - 1; i > 0; --i) {\n        v.push_back({res.xs[res.i_start + i], res.ys[res.path[i].first]});\n        v.push_back({res.xs[res.i_start + i], res.ys[res.path[i - 1].first]});\n    }\n    if (res.swapped) for (auto& p : v) swap(p.first, p.second);\n    \n    vector<pair<int, int>> uv;\n    for (auto p : v) if (uv.empty() || p != uv.back()) uv.push_back(p);\n    if (uv.size() > 1 && uv.front() == uv.back()) uv.pop_back();\n\n    cout << uv.size() << endl;\n    for (auto p : uv) cout << p.first << \" \" << p.second << endl;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    int N; if (!(cin >> N)) return 0;\n    vector<Point> macks(N), sards(N);\n    for (int i = 0; i < N; ++i) cin >> macks[i].x >> macks[i].y;\n    for (int i = 0; i < N; ++i) cin >> sards[i].x >> sards[i].y;\n\n    Result best = {0, 0, -1, -1, {}, false, {}, {}};\n    // Evaluate x-monotone and y-monotone polygons and pick the best one.\n    for (bool s_xy : {false, true}) {\n        Result cur = solve_monotone(N, macks, sards, s_xy, 85, 10);\n        if (cur.fish_score > best.fish_score || (cur.fish_score == best.fish_score && cur.perimeter < best.perimeter)) {\n            best = cur;\n        }\n    }\n    output(best);\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <algorithm>\n\nusing namespace std;\n\n// Representation of a rectangle's placement on a 2D grid\nstruct Rect {\n    long long x, y, xw, yh;\n};\n\n// Arrangement configuration for N rectangles\nstruct Config {\n    int r[100]; // 0: no rotation, 1: 90-degree rotation\n    int d[100]; // 0: 'U' (fixed x, moves toward y=0), 1: 'L' (fixed y, moves toward x=0)\n    int b[100]; // Reference rectangle index, -1 for coordinate axes\n};\n\n// Global arrays for tracking overlap dependencies to allow path tracing\nint parentX[100], parentY[100];\n\n/**\n * Calculates the bounding box and placement of N rectangles.\n * Returns the {Width, Height} of the bounding box.\n */\npair<long long, long long> evaluate(int N, const Config& conf, Rect* p, const vector<long long>& w, const vector<long long>& h, int start_idx = 0) {\n    for (int i = start_idx; i < N; ++i) {\n        long long cur_w = conf.r[i] ? h[i] : w[i];\n        long long cur_h = conf.r[i] ? w[i] : h[i];\n        long long x = 0, y = 0;\n        parentX[i] = -1;\n        parentY[i] = -1;\n        \n        if (conf.d[i] == 0) { // Upward placement ('U')\n            x = (conf.b[i] == -1) ? 0 : p[conf.b[i]].xw;\n            for (int j = 0; j < i; ++j) {\n                if (x < p[j].xw && p[j].x < x + cur_w) {\n                    if (p[j].yh > y) {\n                        y = p[j].yh;\n                        parentY[i] = j;\n                    }\n                }\n            }\n        } else { // Leftward placement ('L')\n            y = (conf.b[i] == -1) ? 0 : p[conf.b[i]].yh;\n            for (int j = 0; j < i; ++j) {\n                if (y < p[j].yh && p[j].y < y + cur_h) {\n                    if (p[j].xw > x) {\n                        x = p[j].xw;\n                        parentX[i] = j;\n                    }\n                }\n            }\n        }\n        p[i] = {x, y, x + cur_w, y + cur_h};\n    }\n    \n    long long max_w = 0, max_h = 0;\n    for (int i = 0; i < N; ++i) {\n        max_w = max(max_w, p[i].xw);\n        max_h = max(max_h, p[i].yh);\n    }\n    return {max_w, max_h};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T_turns;\n    double sigma_val;\n    if (!(cin >> N >> T_turns >> sigma_val)) return 0;\n\n    // Initial width and height observations\n    vector<double> w_est(N), h_est(N);\n    vector<double> current_sigma(N, sigma_val);\n    vector<int> count_measurements(N, 1);\n    for (int i = 0; i < N; ++i) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_time = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    mt19937 rng(1337);\n    Config best_ever_conf;\n    for (int i = 0; i < N; ++i) {\n        best_ever_conf.r[i] = (w_est[i] < h_est[i] ? 1 : 0);\n        best_ever_conf.d[i] = rng() % 2;\n        best_ever_conf.b[i] = (int)(rng() % (i + 1)) - 1;\n    }\n    long long best_ever_score = -1;\n\n    // Phase 1: Direct Measurement turns\n    int M = min(N, T_turns / 2);\n    for (int t = 0; t < M; ++t) {\n        cout << 1 << \"\\n\" << t << \" 0 U -1\\n\" << flush;\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) return 0;\n        w_est[t] = (w_est[t] * count_measurements[t] + W_p) / (count_measurements[t] + 1.0);\n        h_est[t] = (h_est[t] * count_measurements[t] + H_p) / (count_measurements[t] + 1.0);\n        count_measurements[t]++;\n        current_sigma[t] = sigma_val / sqrt(count_measurements[t]);\n    }\n\n    Rect placed[100];\n    \n    // Phase 2: Packing and refinement using Simulated Annealing\n    for (int t = M; t < T_turns; ++t) {\n        double turn_start_time = elapsed_time();\n        double turn_time_limit = (2.90 - turn_start_time) / (T_turns - t);\n\n        // Thompson Sampling: sample true dimensions from our current posterior\n        vector<long long> w_sample(N), h_sample(N);\n        for (int i = 0; i < N; ++i) {\n            normal_distribution<double> dist_w(w_est[i], current_sigma[i]);\n            normal_distribution<double> dist_h(h_est[i], current_sigma[i]);\n            w_sample[i] = max(1LL, (long long)round(dist_w(rng)));\n            h_sample[i] = max(1LL, (long long)round(dist_h(rng)));\n        }\n\n        Config current_conf = best_ever_conf;\n        auto initial_eval = evaluate(N, current_conf, placed, w_sample, h_sample);\n        long long current_score = initial_eval.first + initial_eval.second;\n        Config best_in_turn = current_conf;\n        long long best_score_in_turn = current_score;\n\n        // SA Parameters\n        double t_start = sigma_val;\n        double t_end = 1.0;\n        uniform_real_distribution<double> dist01(0, 1);\n\n        // Run SA for the turn's time slice\n        while (elapsed_time() - turn_start_time < turn_time_limit) {\n            int k = rng() % N;\n            int old_r = current_conf.r[k], old_d = current_conf.d[k], old_b = current_conf.b[k];\n            Rect backup_p[100];\n            for (int i = k; i < N; ++i) backup_p[i] = placed[i];\n\n            int type = rng() % 3;\n            if (type == 0) current_conf.r[k] = 1 - current_conf.r[k];\n            else if (type == 1) current_conf.d[k] = 1 - current_conf.d[k];\n            else current_conf.b[k] = (int)(rng() % (k + 1)) - 1;\n\n            auto n_res = evaluate(N, current_conf, placed, w_sample, h_sample, k);\n            long long n_score = n_res.first + n_res.second;\n\n            double ratio = (elapsed_time() - turn_start_time) / turn_time_limit;\n            double temp = t_start * pow(t_end / t_start, ratio);\n\n            if (n_score < current_score || dist01(rng) < exp((double)(current_score - n_score) / temp)) {\n                current_score = n_score;\n                if (n_score < best_score_in_turn) {\n                    best_score_in_turn = n_score;\n                    best_in_turn = current_conf;\n                }\n            } else {\n                current_conf.r[k] = old_r; current_conf.d[k] = old_d; current_conf.b[k] = old_b;\n                for (int i = k; i < N; ++i) placed[i] = backup_p[i];\n            }\n        }\n\n        // Send current best configuration to the judge\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; ++i) cout << i << \" \" << best_in_turn.r[i] << \" \" << (best_in_turn.d[i] == 0 ? 'U' : 'L') << \" \" << best_in_turn.b[i] << \"\\n\";\n        cout << flush;\n\n        long long W_p, H_p;\n        if (!(cin >> W_p >> H_p)) break;\n\n        // Trace the width and height critical paths to slightly nudge estimates\n        vector<long long> w_ll(N), h_ll(N);\n        for(int i=0; i<N; ++i) { w_ll[i] = (long long)round(w_est[i]); h_ll[i] = (long long)round(h_est[i]); }\n        auto final_res = evaluate(N, best_in_turn, placed, w_ll, h_ll);\n\n        auto trace = [&](bool isW, long long target) {\n            vector<int> path;\n            int cur = -1;\n            for (int i = 0; i < N; ++i) { if ((isW ? placed[i].xw : placed[i].yh) == target) { cur = i; break; } }\n            while (cur != -1) {\n                path.push_back(cur);\n                if (isW) cur = (best_in_turn.d[cur] == 0 ? best_in_turn.b[cur] : parentX[cur]);\n                else cur = (best_in_turn.d[cur] == 1 ? best_in_turn.b[cur] : parentY[cur]);\n            }\n            return path;\n        };\n\n        vector<int> pW = trace(true, final_res.first);\n        vector<int> pH = trace(false, final_res.second);\n        double errW = (double)(W_p - final_res.first);\n        double errH = (double)(H_p - final_res.second);\n        for (int i : pW) { if (best_in_turn.r[i] == 0) w_est[i] += errW / pW.size() * 0.1; else h_est[i] += errW / pW.size() * 0.1; }\n        for (int i : pH) { if (best_in_turn.r[i] == 0) h_est[i] += errH / pH.size() * 0.1; else w_est[i] += errH / pH.size() * 0.1; }\n\n        if (best_ever_score == -1 || W_p + H_p < best_ever_score) {\n            best_ever_score = W_p + H_p;\n            best_ever_conf = best_in_turn;\n        }\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#include <numeric>\n\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int H_LIMIT = 10;\n\nint N, M, H_input;\nlong long A[MAXN];\nvector<int> adj[MAXN];\nint parent_v[MAXN];\nvector<int> children_v[MAXN];\nint depth_v[MAXN];\nlong long subtree_sum_A[MAXN];\nint max_depth_rel[MAXN];\n\n// Fast check for ancestor within height limit to prevent cycles\nbool is_ancestor(int u, int v) {\n    if (u == -1) return false;\n    int curr = v;\n    int count = 0;\n    while (curr != -1 && count <= H_LIMIT + 2) {\n        if (curr == u) return true;\n        curr = parent_v[curr];\n        count++;\n    }\n    return false;\n}\n\n// Recompute beauty sum and relative max depth for node u\nvoid recompute_node_metrics(int u) {\n    long long sum = A[u];\n    int mx = 0;\n    for (int child : children_v[u]) {\n        sum += subtree_sum_A[child];\n        mx = max(mx, max_depth_rel[child] + 1);\n    }\n    subtree_sum_A[u] = sum;\n    max_depth_rel[u] = mx;\n}\n\n// Update a node and its ancestors after a change in its subtree\nvoid update_ancestors(int u) {\n    int count = 0;\n    while (u != -1 && count <= H_LIMIT + 2) {\n        long long old_sum = subtree_sum_A[u];\n        int old_mx = max_depth_rel[u];\n        recompute_node_metrics(u);\n        if (subtree_sum_A[u] == old_sum && max_depth_rel[u] == old_mx) break;\n        u = parent_v[u];\n        count++;\n    }\n}\n\n// Propagate depth changes down the subtree\nvoid update_subtree_depth(int u, int d) {\n    depth_v[u] = d;\n    for (int child : children_v[u]) {\n        update_subtree_depth(child, d + 1);\n    }\n}\n\n// Move a node and its entire subtree to a new parent\nvoid move_v(int v, int new_p) {\n    int old_p = parent_v[v];\n    if (old_p != -1) {\n        auto& cv = children_v[old_p];\n        for (size_t i = 0; i < cv.size(); ++i) {\n            if (cv[i] == v) {\n                cv[i] = cv.back();\n                cv.pop_back();\n                break;\n            }\n        }\n        update_ancestors(old_p);\n    }\n    parent_v[v] = new_p;\n    if (new_p != -1) {\n        children_v[new_p].push_back(v);\n        update_subtree_depth(v, depth_v[new_p] + 1);\n        update_ancestors(new_p);\n    } else {\n        update_subtree_depth(v, 0);\n        update_ancestors(-1); \n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> H_input)) 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; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    for (int i = 0; i < N; ++i) {\n        parent_v[i] = -1; depth_v[i] = 0; children_v[i].clear();\n        subtree_sum_A[i] = A[i]; max_depth_rel[i] = 0;\n    }\n\n    mt19937 mt(42);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    sort(nodes.begin(), nodes.end(), [&](int i, int j) { return A[i] > A[j]; });\n\n    // Greedy start\n    for (int v : nodes) {\n        int best_p = -1, max_h = -1;\n        for (int p : adj[v]) {\n            if (!is_ancestor(v, p) && depth_v[p] + 1 + max_depth_rel[v] <= H_LIMIT) {\n                if (depth_v[p] > max_h) { max_h = depth_v[p]; best_p = p; }\n            }\n        }\n        if (best_p != -1) move_v(v, best_p);\n    }\n\n    auto start_time = chrono::high_resolution_clock::now();\n    double T_start = 2000.0, T_end = 0.1, log_T_ratio = log(T_end / T_start);\n    long long iter = 0; \n    double T = T_start;\n    uniform_real_distribution<double> dist(0.0, 1.0);\n\n    // Simulated Annealing\n    while (true) {\n        if ((iter & 255) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 1.92) break;\n            T = T_start * exp(log_T_ratio * (elapsed / 1.92));\n        }\n        iter++;\n        int v = mt() % N;\n        int deg = (int)adj[v].size();\n        int r = mt() % (deg + 1);\n        int new_p = (r == deg) ? -1 : adj[v][r];\n\n        if (new_p == parent_v[v]) continue;\n\n        bool ok = (new_p == -1) || (depth_v[new_p] + 1 + max_depth_rel[v] <= H_LIMIT && !is_ancestor(v, new_p));\n        if (ok) {\n            int old_d = depth_v[v];\n            int new_d = (new_p == -1 ? 0 : depth_v[new_p] + 1);\n            long long delta = (long long)(new_d - old_d) * subtree_sum_A[v];\n            if (delta >= 0 || (T > 0 && dist(mt) < exp((double)delta / T))) {\n                move_v(v, new_p);\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << parent_v[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#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n/**\n * Optimized Solver for \"Oni wa Soto, Fuku wa Uchi\"\n * \n * Strategy:\n * 1. For each Oni, determine safe directions (L, R, U, D) where no Fukunokami exists \n *    between the Oni and the edge of the board.\n * 2. Assign each Oni exactly one of its safe directions using Simulated Annealing (SA).\n * 3. Two-Phase Movement Strategy:\n *    - Phase 1 (First Dimension): Shift rows/columns to remove assigned Oni.\n *      Return each row/column to its original state IF it contains a Fukunokami \n *      OR an Oni needed for the second phase. Otherwise, save moves by not returning.\n *    - Phase 2 (Last Dimension): Shift rows/columns without return.\n * 4. SA explores direction assignments and the order of phases (Rows-then-Cols vs. Cols-then-Rows).\n */\n\nconst int N = 20;\n\nstruct Oni {\n    int r, c;\n    int dists[4]; // 0:L, 1:R, 2:U, 3:D\n    vector<int> safe_dirs;\n};\n\ninline int get_cost_last(int m1, int m2) {\n    if (m1 > 0 && m2 > 0) return min(2 * m1 + m2, 2 * m2 + m1);\n    return max(m1, m2);\n}\n\ninline int get_cost_first(int m1, int m2, bool must) {\n    if (must) return 2 * (m1 + m2);\n    return get_cost_last(m1, m2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n_in;\n    if (!(cin >> n_in)) return 0;\n    vector<string> board(N);\n    bool row_has_fuku[N] = {false}, col_has_fuku[N] = {false};\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] == 'o') {\n                row_has_fuku[i] = true;\n                col_has_fuku[j] = true;\n            }\n        }\n    }\n\n    vector<Oni> onis;\n    vector<int> row_onis[N], col_onis[N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                Oni oni; oni.r = i; oni.c = j;\n                oni.dists[0] = j + 1; oni.dists[1] = N - j;\n                oni.dists[2] = i + 1; oni.dists[3] = N - i;\n                bool l_s = true; for (int k = 0; k < j; ++k) if (board[i][k] == 'o') l_s = false;\n                if (l_s) oni.safe_dirs.push_back(0);\n                bool r_s = true; for (int k = j + 1; k < N; ++k) if (board[i][k] == 'o') r_s = false;\n                if (r_s) oni.safe_dirs.push_back(1);\n                bool u_s = true; for (int k = 0; k < i; ++k) if (board[k][j] == 'o') u_s = false;\n                if (u_s) oni.safe_dirs.push_back(2);\n                bool d_s = true; for (int k = i + 1; k < N; ++k) if (board[k][j] == 'o') d_s = false;\n                if (d_s) oni.safe_dirs.push_back(3);\n                row_onis[i].push_back((int)onis.size());\n                col_onis[j].push_back((int)onis.size());\n                onis.push_back(oni);\n            }\n        }\n    }\n    if (onis.empty()) return 0;\n\n    mt19937 rng(42);\n    vector<int> cur_d(onis.size());\n    int Lc[N][N + 1] = {0}, Rc[N][N + 1] = {0}, Uc[N][N + 1] = {0}, Dc[N][N + 1] = {0};\n    int maxL[N] = {0}, maxR[N] = {0}, maxU[N] = {0}, maxD[N] = {0};\n    int lr_count_in_col[N] = {0}, ud_count_in_row[N] = {0};\n\n    for (int i = 0; i < (int)onis.size(); i++) {\n        cur_d[i] = onis[i].safe_dirs[rng() % onis[i].safe_dirs.size()];\n        int d = cur_d[i];\n        if (d == 0) { Lc[onis[i].r][onis[i].dists[0]]++; maxL[onis[i].r] = max(maxL[onis[i].r], onis[i].dists[0]); }\n        else if (d == 1) { Rc[onis[i].r][onis[i].dists[1]]++; maxR[onis[i].r] = max(maxR[onis[i].r], onis[i].dists[1]); }\n        else if (d == 2) { Uc[onis[i].c][onis[i].dists[2]]++; maxU[onis[i].c] = max(maxU[onis[i].c], onis[i].dists[2]); }\n        else if (d == 3) { Dc[onis[i].c][onis[i].dists[3]]++; maxD[onis[i].c] = max(maxD[onis[i].c], onis[i].dists[3]); }\n        if (d <= 1) lr_count_in_col[onis[i].c]++; else ud_count_in_row[onis[i].r]++;\n    }\n\n    auto update_m = [&](int d, int val, int idx, int dist) {\n        if (d == 0) { Lc[idx][dist] += val; if (val == 1) { if (dist > maxL[idx]) maxL[idx] = dist; } else if (dist == maxL[idx] && Lc[idx][dist] == 0) { while (maxL[idx] > 0 && Lc[idx][maxL[idx]] == 0) maxL[idx]--; } }\n        else if (d == 1) { Rc[idx][dist] += val; if (val == 1) { if (dist > maxR[idx]) maxR[idx] = dist; } else if (dist == maxR[idx] && Rc[idx][dist] == 0) { while (maxR[idx] > 0 && Rc[idx][maxR[idx]] == 0) maxR[idx]--; } }\n        else if (d == 2) { Uc[idx][dist] += val; if (val == 1) { if (dist > maxU[idx]) maxU[idx] = dist; } else if (dist == maxU[idx] && Uc[idx][dist] == 0) { while (maxU[idx] > 0 && Uc[idx][maxU[idx]] == 0) maxU[idx]--; } }\n        else if (d == 3) { Dc[idx][dist] += val; if (val == 1) { if (dist > maxD[idx]) maxD[idx] = dist; } else if (dist == maxD[idx] && Dc[idx][dist] == 0) { while (maxD[idx] > 0 && Dc[idx][maxD[idx]] == 0) maxD[idx]--; } }\n    };\n\n    int tot_costA = 0, tot_costB = 0; // A: Cols First, Rows Last. B: Rows First, Cols Last.\n    for (int i = 0; i < N; i++) {\n        tot_costA += get_cost_first(maxU[i], maxD[i], col_has_fuku[i] || lr_count_in_col[i] > 0);\n        tot_costA += get_cost_last(maxL[i], maxR[i]);\n        tot_costB += get_cost_first(maxL[i], maxR[i], row_has_fuku[i] || ud_count_in_row[i] > 0);\n        tot_costB += get_cost_last(maxU[i], maxD[i]);\n    }\n    int cur_total = min(tot_costA, tot_costB);\n\n    auto start_time = chrono::steady_clock::now();\n    double st = 3.0, et = 0.01;\n    for (int iter = 0; ; iter++) {\n        if ((iter & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double ms = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n            if (ms > 1920) break;\n            double T = st + (et - st) * (ms / 1920.0);\n\n            for (int sub = 0; sub < 1024; sub++) {\n                int k = rng() % onis.size(); if (onis[k].safe_dirs.size() <= 1) continue;\n                int old_d = cur_d[k], next_d = onis[k].safe_dirs[rng() % onis[k].safe_dirs.size()]; if (next_d == old_d) continue;\n                int r = onis[k].r, c = onis[k].c;\n                int old_row_A = get_cost_last(maxL[r], maxR[r]), old_col_A = get_cost_first(maxU[c], maxD[c], col_has_fuku[c] || lr_count_in_col[c] > 0);\n                int old_row_B = get_cost_first(maxL[r], maxR[r], row_has_fuku[r] || ud_count_in_row[r] > 0), old_col_B = get_cost_last(maxU[c], maxD[c]);\n\n                update_m(old_d, -1, (old_d <= 1 ? r : c), onis[k].dists[old_d]);\n                if (old_d <= 1) lr_count_in_col[c]--; else ud_count_in_row[r]--;\n                cur_d[k] = next_d;\n                update_m(next_d, 1, (next_d <= 1 ? r : c), onis[k].dists[next_d]);\n                if (next_d <= 1) lr_count_in_col[c]++; else ud_count_in_row[r]++;\n\n                int next_row_A = get_cost_last(maxL[r], maxR[r]), next_col_A = get_cost_first(maxU[c], maxD[c], col_has_fuku[c] || lr_count_in_col[c] > 0);\n                int next_row_B = get_cost_first(maxL[r], maxR[r], row_has_fuku[r] || ud_count_in_row[r] > 0), next_col_B = get_cost_last(maxU[c], maxD[c]);\n                int next_totA = tot_costA - old_row_A - old_col_A + next_row_A + next_col_A;\n                int next_totB = tot_costB - old_row_B - old_col_B + next_row_B + next_col_B;\n                int next_total = min(next_totA, next_totB);\n\n                if (next_total <= cur_total || (T > 0 && exp((double)(cur_total - next_total) / T) > (double)rng() / rng.max())) {\n                    cur_total = next_total; tot_costA = next_totA; tot_costB = next_totB;\n                } else {\n                    update_m(next_d, -1, (next_d <= 1 ? r : c), onis[k].dists[next_d]);\n                    if (next_d <= 1) lr_count_in_col[c]--; else ud_count_in_row[r]--;\n                    cur_d[k] = old_d;\n                    update_m(old_d, 1, (old_d <= 1 ? r : c), onis[k].dists[old_d]);\n                    if (old_d <= 1) lr_count_in_col[c]++; else ud_count_in_row[r]++;\n                }\n            }\n        }\n    }\n\n    auto exec_ph1 = [&](char d1, char d2, int id, int m1, int m2, bool must) {\n        if (must) { for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\"; for (int k = 0; k < m1 + m2; k++) cout << d2 << \" \" << id << \"\\n\"; for (int k = 0; k < m2; k++) cout << d1 << \" \" << id << \"\\n\"; }\n        else { if (m1 > 0 && m2 > 0) { if (2 * m1 + m2 < 2 * m2 + m1) { for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\"; for (int k = 0; k < m1 + m2; k++) cout << d2 << \" \" << id << \"\\n\"; } else { for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\"; for (int k = 0; k < m2 + m1; k++) cout << d1 << \" \" << id << \"\\n\"; } } else if (m1 > 0) for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\"; else if (m2 > 0) for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\"; }\n    };\n    auto exec_ph2 = [&](char d1, char d2, int id, int m1, int m2) {\n        if (m1 > 0 && m2 > 0) { if (2 * m1 + m2 < 2 * m2 + m1) { for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\"; for (int k = 0; k < m1 + m2; k++) cout << d2 << \" \" << id << \"\\n\"; } else { for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\"; for (int k = 0; k < m2 + m1; k++) cout << d1 << \" \" << id << \"\\n\"; } } else if (m1 > 0) for (int k = 0; k < m1; k++) cout << d1 << \" \" << id << \"\\n\"; else if (m2 > 0) for (int k = 0; k < m2; k++) cout << d2 << \" \" << id << \"\\n\";\n    };\n\n    if (tot_costA <= tot_costB) {\n        for (int j = 0; j < N; j++) exec_ph1('U', 'D', j, maxU[j], maxD[j], col_has_fuku[j] || lr_count_in_col[j] > 0);\n        for (int i = 0; i < N; i++) exec_ph2('L', 'R', i, maxL[i], maxR[i]);\n    } else {\n        for (int i = 0; i < N; i++) exec_ph1('L', 'R', i, maxL[i], maxR[i], row_has_fuku[i] || ud_count_in_row[i] > 0);\n        for (int j = 0; j < N; j++) exec_ph2('U', 'D', j, maxU[j], maxD[j]);\n    }\n    return 0;\n}\n","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\n/**\n * Problem Summary:\n * We need to determine two integers a_i and b_i for each employee i (0 to N-1).\n * Weekly cleaners are decided by the previous cleaner's visit parity.\n * Objective: Minimize sum |actual_visit_count_i - target_T_i| over L weeks.\n *\n * Strategy:\n * 1. Proxy Cost Optimization:\n *    Use the flow balance equations based on parity:\n *    t_j \u2248 delta_{j,0} + sum_{i} (ceil(T_i/2) * [a_i=j] + floor(T_i/2) * [b_i=j])\n *    Minimize sum |t_j - target_T_j| using Simulated Annealing.\n *    This ensures the overall network structure supports the target counts.\n * 2. Fine-Tuning:\n *    Use Hill Climbing based on actual 500,000-week simulations to account for\n *    transient behavior and the exact L-week limit.\n */\n\nconst int N = 100;\nlong long target_T[N];\nint best_final_a[N], best_final_b[N];\nlong long min_actual_err = -1;\n\nlong long U_calls[N], V_calls[N];\n\n// Buffers for proxy cost calculation\nbool reachable[N];\nlong long cur_t_arr[N];\nint bfs_q[N];\nint sim_counts[N];\n\n/**\n * Calculates a proxy error based on target transitions.\n * If target_T[i] visits to node i occur, it sends ceil(target_T[i]/2) to a_i\n * and floor(target_T[i]/2) to b_i.\n */\nlong long get_proxy_cost(const int* a, const int* b) {\n    fill(reachable, reachable + N, false);\n    fill(cur_t_arr, cur_t_arr + N, 0);\n    \n    // Check reachability from starting node 0\n    int head = 0, tail = 0;\n    bfs_q[tail++] = 0;\n    reachable[0] = true;\n    while (head < tail) {\n        int u = bfs_q[head++];\n        int na = a[u];\n        if (!reachable[na]) {\n            reachable[na] = true;\n            bfs_q[tail++] = na;\n        }\n        int nb = b[u];\n        if (!reachable[nb]) {\n            reachable[nb] = true;\n            bfs_q[tail++] = nb;\n        }\n    }\n    \n    // Start count for week 1\n    cur_t_arr[0] = 1;\n    // Calculate expected inflows from reachable nodes\n    for (int i = 0; i < N; ++i) {\n        if (reachable[i]) {\n            cur_t_arr[a[i]] += U_calls[i];\n            cur_t_arr[b[i]] += V_calls[i];\n        }\n    }\n    \n    long long err = 0;\n    for (int i = 0; i < N; ++i) {\n        // Heavy penalty for unreachable nodes that should have cleanings\n        if (!reachable[i] && target_T[i] > 0) {\n            err += 1000000LL + target_T[i];\n        }\n        err += abs(cur_t_arr[i] - target_T[i]);\n    }\n    return err;\n}\n\n/**\n * Performs a full L-week simulation to calculate exact visit counts.\n * Complexity: O(L), where L = 500,000.\n */\nlong long get_actual_err(const int* a, const int* b, int L) {\n    fill(sim_counts, sim_counts + N, 0);\n    int curr = 0;\n    for (int w = 0; w < L; ++w) {\n        sim_counts[curr]++;\n        if (sim_counts[curr] & 1) curr = a[curr];\n        else curr = b[curr];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; ++i) err += abs((long long)sim_counts[i] - target_T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, l_in;\n    if (!(cin >> n_in >> l_in)) return 0;\n    for (int i = 0; i < N; ++i) cin >> target_T[i];\n\n    // Precompute call distributions for each node's target visit count\n    for (int i = 0; i < N; ++i) {\n        U_calls[i] = (target_T[i] + 1) / 2;\n        V_calls[i] = target_T[i] / 2;\n    }\n\n    mt19937 mt(1337);\n    int cur_a[N], cur_b[N];\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = mt() % N;\n        cur_b[i] = mt() % N;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Step 1: Simulated Annealing for proxy error optimization\n    long long cur_proxy_err = get_proxy_cost(cur_a, cur_b);\n    long long best_step1_err = cur_proxy_err;\n    int best_step1_a[N], best_step1_b[N];\n    for(int i=0; i<N; ++i) { best_step1_a[i] = cur_a[i]; best_step1_b[i] = cur_b[i]; }\n\n    const double duration_step1 = 1.0;\n    const double t_start = 2500.0, t_end = 0.1;\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > duration_step1) break;\n        }\n        iters++;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long next_proxy_err = get_proxy_cost(cur_a, cur_b);\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double temp = t_start * pow(t_end / t_start, elapsed / duration_step1);\n        \n        if (next_proxy_err <= cur_proxy_err || \n            (double)mt() / mt.max() < exp((double)(cur_proxy_err - next_proxy_err) / temp)) {\n            cur_proxy_err = next_proxy_err;\n            if (cur_proxy_err < best_step1_err) {\n                best_step1_err = cur_proxy_err;\n                for(int k=0; k<N; ++k) { best_step1_a[k] = cur_a[k]; best_step1_b[k] = cur_b[k]; }\n            }\n        } else {\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Initialize current state with the best found in Step 1\n    for (int i = 0; i < N; ++i) {\n        cur_a[i] = best_step1_a[i];\n        cur_b[i] = best_step1_b[i];\n        best_final_a[i] = cur_a[i];\n        best_final_b[i] = cur_b[i];\n    }\n    min_actual_err = get_actual_err(cur_a, cur_b, l_in);\n    \n    // Step 2: Hill Climbing with Actual Simulation for fine-tuning\n    const double duration_total = 1.95;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > duration_total) break;\n        \n        int idx = mt() % N;\n        int choice = mt() % 2;\n        int old_val = (choice == 0 ? cur_a[idx] : cur_b[idx]);\n        int next_val = mt() % N;\n        if (old_val == next_val) continue;\n        \n        if (choice == 0) cur_a[idx] = next_val;\n        else cur_b[idx] = next_val;\n        \n        long long actual_err = get_actual_err(cur_a, cur_b, l_in);\n        if (actual_err <= min_actual_err) {\n            min_actual_err = actual_err;\n            for (int i = 0; i < N; ++i) {\n                best_final_a[i] = cur_a[i];\n                best_final_b[i] = cur_b[i];\n            }\n        } else {\n            // Revert on worse score\n            if (choice == 0) cur_a[idx] = old_val;\n            else cur_b[idx] = old_val;\n        }\n    }\n    \n    // Output the final optimal cleaning plan transitions\n    for (int i = 0; i < N; ++i) {\n        cout << best_final_a[i] << \" \" << best_final_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}\n","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Disjoint Set Union structure for MST and connectivity tracking\nstruct DSU {\n    vector<int> p;\n    int comps;\n    DSU(int n) : p(n), comps(n) {\n        for (int i = 0; i < n; i++) p[i] = i;\n    }\n    int find(int i) {\n        if (p[i] == i) return i;\n        return p[i] = find(p[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            p[root_i] = root_j;\n            comps--;\n            return true;\n        }\n        return false;\n    }\n};\n\nstruct Edge {\n    int u, v;\n    long long w;\n    bool operator<(const Edge& other) const {\n        if (w != other.w) return w < other.w;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G_sizes;\ndouble hat_x[800], hat_y[800];\nint center_dist[800][800];\nlong long unique_dist[800][800];\nvector<int> groups[400];\nint group_id[800];\nint index_in_group[800];\nbool is_query_tested[800][800];\nbool is_query_selected[800][800];\n\n// MST weight using Prim's algorithm - O(G^2). Strictly follows the judge's tie-breaking rules.\nlong long get_mst_weight(const vector<int>& group) {\n    int n = (int)group.size();\n    if (n <= 1) return 0;\n    static long long min_d[800];\n    static bool visited[800];\n    for (int i = 0; i < n; i++) {\n        min_d[i] = unique_dist[group[0]][group[i]];\n        visited[i] = false;\n    }\n    visited[0] = true;\n    long long total_w = 0;\n    for (int i = 0; i < n - 1; i++) {\n        int u_idx = -1;\n        long long best_d = 8e18; // Use a sufficiently large value\n        for (int j = 0; j < n; j++) {\n            if (!visited[j] && min_d[j] < best_d) {\n                best_d = min_d[j];\n                u_idx = j;\n            }\n        }\n        if (u_idx == -1) break;\n        visited[u_idx] = true;\n        total_w += (best_d / 1000000LL);\n        int u_city = group[u_idx];\n        for (int j = 0; j < n; j++) {\n            if (!visited[j]) {\n                long long d = unique_dist[u_city][group[j]];\n                if (d < min_d[j]) min_d[j] = d;\n            }\n        }\n    }\n    return total_w;\n}\n\n// Initial partitioning using recursive bisection\nvoid bisect(vector<int> cities, int g_start, int g_end, int depth) {\n    if (g_start + 1 == g_end) {\n        groups[g_start] = cities;\n        return;\n    }\n    int mid = (g_start + g_end) / 2;\n    int left_n = 0;\n    for (int i = g_start; i < mid; i++) left_n += G_sizes[i];\n    if (depth % 2 == 0) sort(cities.begin(), cities.end(), [&](int a, int b) { \n        if(hat_x[a] != hat_x[b]) return hat_x[a] < hat_x[b];\n        return a < b;\n    });\n    else sort(cities.begin(), cities.end(), [&](int a, int b) { \n        if(hat_y[a] != hat_y[b]) return hat_y[a] < hat_y[b];\n        return a < b;\n    });\n    bisect(vector<int>(cities.begin(), cities.begin() + left_n), g_start, mid, depth + 1);\n    bisect(vector<int>(cities.begin() + left_n, cities.end()), mid, g_end, depth + 1);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(NULL);\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    G_sizes.resize(M);\n    for (int i = 0; i < M; i++) cin >> G_sizes[i];\n    for (int i = 0; i < N; i++) {\n        double lx, rx, ly, ry; cin >> lx >> rx >> ly >> ry;\n        hat_x[i] = (lx + rx) / 2.0; hat_y[i] = (ly + ry) / 2.0;\n    }\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) { center_dist[i][j] = 0; unique_dist[i][j] = 0; }\n            else {\n                double dx = hat_x[i] - hat_x[j], dy = hat_y[i] - hat_y[j];\n                center_dist[i][j] = (int)floor(sqrt(dx * dx + dy * dy) + 1e-9);\n                int u = min(i, j), v = max(i, j);\n                unique_dist[i][j] = (long long)center_dist[i][j] * 1000000LL + (long long)u * 1000LL + v;\n            }\n        }\n    }\n\n    vector<int> all_cities(N);\n    for (int i = 0; i < N; i++) all_cities[i] = i;\n    bisect(all_cities, 0, M, 0);\n\n    vector<long long> g_mst_w(M);\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < (int)groups[k].size(); i++) {\n            group_id[groups[k][i]] = k; index_in_group[groups[k][i]] = i;\n        }\n        g_mst_w[k] = get_mst_weight(groups[k]);\n    }\n\n    mt19937 rng(42);\n    auto start_time = chrono::steady_clock::now();\n    double sa_limit = 1.2;\n    long long iter = 0;\n    while (true) {\n        if ((iter & 255) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > sa_limit) break;\n            double T = 50.0 * (1.0 - elapsed / sa_limit);\n            for (int s = 0; s < 256; s++) {\n                int u = rng() % N, v = rng() % N;\n                int gU = group_id[u], gV = group_id[v];\n                if (gU == gV) continue;\n                long long old_w = g_mst_w[gU] + g_mst_w[gV];\n                swap(groups[gU][index_in_group[u]], groups[gV][index_in_group[v]]);\n                long long n_wU = get_mst_weight(groups[gU]), n_wV = get_mst_weight(groups[gV]);\n                if (n_wU + n_wV < old_w || (T > 0 && uniform_real_distribution<double>(0, 1)(rng) < exp((double)(old_w - (n_wU + n_wV)) / T))) {\n                    g_mst_w[gU] = n_wU; g_mst_w[gV] = n_wV;\n                    swap(index_in_group[u], index_in_group[v]);\n                    group_id[u] = gV; group_id[v] = gU;\n                } else {\n                    swap(groups[gU][index_in_group[u]], groups[gV][index_in_group[v]]);\n                }\n            }\n        }\n        iter += 256;\n    }\n\n    vector<DSU> dsus;\n    vector<int> l_idx(N);\n    for (int k = 0; k < M; k++) {\n        dsus.emplace_back((int)groups[k].size());\n        for (int i = 0; i < (int)groups[k].size(); i++) l_idx[groups[k][i]] = i;\n    }\n\n    int q_count = 0;\n    while (q_count < Q) {\n        bool improved_this_round = false;\n        for (int k = 0; k < M && q_count < Q; k++) {\n            if (groups[k].size() < 2 || dsus[k].comps == 1) continue;\n            int u_idx = -1, v_idx = -1; long long d_min = 2e18;\n            for (int i = 0; i < (int)groups[k].size(); i++) {\n                for (int j = i + 1; j < (int)groups[k].size(); j++) {\n                    if (dsus[k].find(i) != dsus[k].find(j)) {\n                        if (unique_dist[groups[k][i]][groups[k][j]] < d_min) {\n                            d_min = unique_dist[groups[k][i]][groups[k][j]];\n                            u_idx = i; v_idx = j;\n                        }\n                    }\n                }\n            }\n            if (u_idx != -1) {\n                improved_this_round = true;\n                vector<int> C; C.push_back(groups[k][u_idx]); C.push_back(groups[k][v_idx]);\n                vector<bool> in_C(N, false); in_C[C[0]] = in_C[C[1]] = true;\n                while ((int)C.size() < min(L, (int)groups[k].size())) {\n                    int next_v = -1; long long next_d = 2e18;\n                    for (int city : groups[k]) if (!in_C[city]) {\n                        for (int cc : C) if (unique_dist[city][cc] < next_d) { next_d = unique_dist[city][cc]; next_v = city; }\n                    }\n                    if (next_v != -1) { C.push_back(next_v); in_C[next_v] = true; } else break;\n                }\n                sort(C.begin(), C.end());\n                cout << \"? \" << C.size();\n                for (int c : C) cout << \" \" << c; cout << endl;\n                q_count++;\n                for (int i = 0; i < (int)C.size() - 1; i++) {\n                    int a, b; cin >> a >> b;\n                    if (a > b) swap(a, b); is_query_selected[a][b] = true;\n                    if (group_id[a] == k && group_id[b] == k) dsus[k].unite(l_idx[a], l_idx[b]);\n                }\n                for (int i = 0; i < (int)C.size(); i++) for (int j = i + 1; j < (int)C.size(); j++) {\n                    int a = C[i], b = C[j]; if (a > b) swap(a, b);\n                    is_query_tested[a][b] = true;\n                }\n            }\n        }\n        if (!improved_this_round) break;\n    }\n\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < (int)groups[k].size(); i++) cout << groups[k][i] << (i == (int)groups[k].size() - 1 ? \"\" : \" \"); cout << endl;\n        if (groups[k].size() > 1) {\n            vector<Edge> edges;\n            for (int i = 0; i < (int)groups[k].size(); i++) for (int j = i + 1; j < (int)groups[k].size(); j++) {\n                int u = min(groups[k][i], groups[k][j]), v = max(groups[k][i], groups[k][j]);\n                long long p = is_query_selected[u][v] ? 0 : (!is_query_tested[u][v] ? 1 : 2);\n                edges.push_back({u, v, p * 1000000000000LL + unique_dist[u][v]});\n            }\n            sort(edges.begin(), edges.end());\n            DSU f_dsu((int)groups[k].size());\n            int ec = 0;\n            for (auto& e : edges) if (f_dsu.unite(l_idx[e.u], l_idx[e.v])) {\n                cout << e.u << \" \" << e.v << endl; if (++ec == (int)groups[k].size() - 1) break;\n            }\n        }\n    }\n    return 0;\n}\n","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\n// Skating rink constants\nconst int N = 20;\nconst int N2 = 400;\nconst int dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nconst int dc[] = {0, 0, -1, 1};\nconst char dchar[] = {'U', 'D', 'L', 'R'};\nconst int INF = 1e7;\n\n// To store parent information for path reconstruction\nstruct Parent {\n    int v;\n    char type, dir;\n};\n\n/**\n * Fast Dijkstra using Dial's algorithm (3-bucket queue) for edge weights 1 and 2.\n * Weights: Slide = 1, Move = 1 (empty square), Alter + Move = 2 (blocked square).\n * Calculates the shortest path distance and parents from start_v.\n */\nvoid fast_dijkstra(int start_v, const bool* grid, int* dists, Parent* parents = nullptr) {\n    fill(dists, dists + N2, INF);\n    if (start_v < 0 || start_v >= N2) return;\n    dists[start_v] = 0;\n\n    static int q[3][1024];\n    int h[3] = {0, 0, 0}, t[3] = {0, 0, 0};\n    q[0][t[0]++] = start_v;\n\n    int d = 0, rem = 1;\n    while (rem > 0) {\n        int b = d % 3;\n        while (h[b] < t[b]) {\n            int u = q[b][h[b]++]; rem--;\n            if (dists[u] < d) continue;\n\n            int cr = u / N, cc = u % N;\n            // Action: Move (cost 1 if empty, 2 if blocked by adding/removing a block)\n            for (int i = 0; i < 4; ++i) {\n                int nr = cr + dr[i], nc = cc + dc[i];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    int v = nr * N + nc;\n                    int cost = 1 + (grid[v] ? 1 : 0);\n                    if (dists[v] > d + cost) {\n                        dists[v] = d + cost;\n                        if (parents) parents[v] = {u, 'M', dchar[i]};\n                        q[(d + cost) % 3][t[(d + cost) % 3]++] = v; rem++;\n                    }\n                }\n            }\n            // Action: Slide (cost 1)\n            for (int i = 0; i < 4; ++i) {\n                int sr = cr, sc = cc;\n                while (true) {\n                    int nr = sr + dr[i], nc = sc + dc[i];\n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N || grid[nr * N + nc]) break;\n                    sr = nr; sc = nc;\n                }\n                if (sr != cr || sc != cc) {\n                    int v = sr * N + sc;\n                    if (dists[v] > d + 1) {\n                        dists[v] = d + 1;\n                        if (parents) parents[v] = {u, 'S', dchar[i]};\n                        q[(d + 1) % 3][t[(d + 1) % 3]++] = v; rem++;\n                    }\n                }\n            }\n        }\n        h[b] = t[b] = 0; d++;\n    }\n}\n\n/**\n * Backward Dijkstra to handle slide asymmetry. \n * Calculates turn-costs from all squares towards target_v.\n */\nvoid fast_backward_dijkstra(int target_v, const bool* grid, int* dists) {\n    fill(dists, dists + N2, INF);\n    if (target_v < 0 || target_v >= N2) return;\n    dists[target_v] = 0;\n\n    static int q[3][1024];\n    int h[3] = {0, 0, 0}, t[3] = {0, 0, 0};\n    q[0][t[0]++] = target_v;\n\n    int d = 0, rem = 1;\n    while (rem > 0) {\n        int b = d % 3;\n        while (h[b] < t[b]) {\n            int u = q[b][h[b]++]; rem--;\n            if (dists[u] < d) continue;\n\n            int cr = u / N, cc = u % N;\n            // Reverse Move\n            for (int i = 0; i < 4; ++i) {\n                int pr = cr - dr[i], pc = cc - dc[i];\n                if (pr >= 0 && pr < N && pc >= 0 && pc < N) {\n                    int cost = 1 + (grid[u] ? 1 : 0);\n                    int v = pr * N + pc;\n                    if (dists[v] > d + cost) {\n                        dists[v] = d + cost;\n                        q[(d + cost) % 3][t[(d + cost) % 3]++] = v; rem++;\n                    }\n                }\n            }\n            // Reverse Slide: Finds all squares that would stop at current (cr, cc) when sliding.\n            for (int i = 0; i < 4; ++i) {\n                int br = cr + dr[i], bc = cc + dc[i];\n                if (br < 0 || br >= N || bc < 0 || bc >= N || grid[br * N + bc]) {\n                    int pr = cr - dr[i], pc = cc - dc[i];\n                    while (pr >= 0 && pr < N && pc >= 0 && pc < N && !grid[pr * N + pc]) {\n                        int v = pr * N + pc;\n                        if (dists[v] > d + 1) {\n                            dists[v] = d + 1;\n                            q[(d + 1) % 3][t[(d + 1) % 3]++] = v; rem++;\n                        }\n                        pr -= dr[i]; pc -= dc[i];\n                    }\n                }\n            }\n        }\n        h[b] = t[b] = 0; d++;\n    }\n}\n\n/**\n * Reconstructs the movement sequence for a path, outputs actions, and updates global rink state.\n */\nvoid reconstruct_path(int start_v, int end_v, Parent* parents, bool* grid, int& cur_v) {\n    if (start_v == end_v) return;\n    vector<pair<char, char>> path;\n    int v = end_v;\n    while (v != start_v) {\n        Parent p = parents[v];\n        path.push_back({p.type, p.dir});\n        v = p.v;\n    }\n    reverse(path.begin(), path.end());\n    for (auto& p : path) {\n        int di = (p.second == 'U' ? 0 : p.second == 'D' ? 1 : p.second == 'L' ? 2 : 3);\n        if (p.first == 'M') {\n            int next_v = cur_v + dr[di] * N + dc[di];\n            if (grid[next_v]) { cout << \"A \" << p.second << \"\\n\"; grid[next_v] = false; }\n            cout << \"M \" << p.second << \"\\n\";\n            cur_v = next_v;\n        } else {\n            cout << \"S \" << p.second << \"\\n\";\n            while (true) {\n                int nr = cur_v / N + dr[di], nc = cur_v % N + dc[di];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N || grid[nr * N + nc]) break;\n                cur_v = nr * N + nc;\n            }\n        }\n    }\n}\n\n// Global reusable buffers\nbool grid[N2];\nint d_cur[N2], bdm_mod[N2], d_temp[N2], d_final[N2], d_baseline[41][N2];\nParent p_initial[N2], p_final[N2];\nconst int MAX_LOOK_AHEAD = 10;\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int n_in, m_in;\n    if (!(cin >> n_in >> m_in)) return 0;\n    vector<int> targets(m_in);\n    for (int i = 0; i < m_in; i++) { \n        int r, c; cin >> r >> c; targets[i] = r * N + c; \n    }\n    fill(grid, grid + N2, false);\n    int cur_v = targets[0];\n    auto start_time = chrono::steady_clock::now();\n\n    for (int k = 1; k < m_in; k++) {\n        int tr = targets[k];\n        fast_dijkstra(cur_v, grid, d_cur, p_initial);\n        \n        // Calculate look-ahead baseline turn costs for pruning\n        long long best_eval = d_cur[tr];\n        int lv = tr;\n        for (int fk = k + 1; fk < min(m_in, k + MAX_LOOK_AHEAD); ++fk) {\n            fast_dijkstra(lv, grid, d_temp);\n            best_eval += d_temp[targets[fk]];\n            lv = targets[fk];\n        }\n\n        int b_bv = -1, b_av = -1; char b_adir = ' ';\n        // Optimize path by potentially flipping one block to enable Slides or better paths\n        for (int br = 0; br < N; br++) {\n            if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 1900) break;\n            for (int bc = 0; bc < N; bc++) {\n                int bv = br * N + bc;\n                if (bv == tr || bv == cur_v) continue;\n\n                grid[bv] = !grid[bv];\n                fast_backward_dijkstra(tr, grid, bdm_mod);\n                \n                long long mck = INF; int cav = -1; char cad = ' ';\n                // Check all squares adjacent to the flip target to start from\n                for (int d = 0; d < 4; ++d) {\n                    int ar = br + dr[d], ac = bc + dc[d];\n                    if (ar >= 0 && ar < N && ac >= 0 && ac < N) {\n                        int av = ar * N + ac;\n                        if (d_cur[av] < INF && bdm_mod[av] < INF) {\n                            long long cost = (long long)d_cur[av] + 1 + bdm_mod[av];\n                            if (cost < mck) { mck = cost; cav = av; cad = dchar[d ^ 1]; }\n                        }\n                    }\n                }\n                if (mck < best_eval) {\n                    long long eval = mck;\n                    int nlv = tr;\n                    for (int fk = k + 1; fk < min(m_in, k + MAX_LOOK_AHEAD); ++fk) {\n                        fast_dijkstra(nlv, grid, d_temp);\n                        eval += d_temp[targets[fk]];\n                        nlv = targets[fk];\n                        if (eval >= best_eval) break;\n                    }\n                    if (eval < best_eval) {\n                        best_eval = eval; b_bv = bv; b_av = cav; b_adir = cad;\n                    }\n                }\n                grid[bv] = !grid[bv]; // Revert the flip\n            }\n        }\n\n        if (b_bv == -1) {\n            reconstruct_path(cur_v, tr, p_initial, grid, cur_v);\n        } else {\n            reconstruct_path(cur_v, b_av, p_initial, grid, cur_v);\n            cout << \"A \" << b_adir << \"\\n\";\n            grid[b_bv] = !grid[b_bv];\n            fast_dijkstra(b_av, grid, d_final, p_final);\n            reconstruct_path(b_av, tr, p_final, grid, cur_v);\n        }\n    }\n    return 0;\n}\n"}}}